From 555b54f6b59e06bffe7f72a5e4c305dd5e7cb85c Mon Sep 17 00:00:00 2001 From: javorosas Date: Fri, 13 Nov 2026 13:55:41 +0100 Subject: [PATCH 1/2] feat(sdk)!: generate typed customer contracts from OpenAPI Generate customer inputs, resource methods and XML documentation from a pinned public specification while preserving dictionary-based calls. BREAKING CHANGE: Customer.SatValidatedAt and Customer.EditLinkExpiresAt now use nullable DateTime values. Handle absent dates before reading their values. --- .gitattributes | 29 ++ .github/workflows/ci.yml | 13 + .gitignore | 4 +- CHANGELOG.md | 15 + FacturapiTest/ClientCompatibilityTests.cs | 6 +- FacturapiTest/WrapperBehaviorTests.cs | 67 ++++ Models/Address.cs | 75 ++++- Models/Customer.cs | 133 +++++++- Models/CustomerEditLinkEmailResult.cs | 21 ++ Models/Inputs/CustomerCreateParams.cs | 30 ++ .../Inputs/CustomerCreateWithEditLinkInput.cs | 110 +++++++ .../CustomerCreateWithEditLinkInputAddress.cs | 122 ++++++++ Models/Inputs/CustomerEditLinkEmailInput.cs | 26 ++ Models/Inputs/CustomerForeignAddressInput.cs | 122 ++++++++ Models/Inputs/CustomerForeignCreateInput.cs | 110 +++++++ Models/Inputs/CustomerGenericCreateInput.cs | 110 +++++++ .../CustomerGenericCreateInputAddress.cs | 122 ++++++++ Models/Inputs/CustomerListParams.cs | 92 ++++++ Models/Inputs/CustomerNationalAddressInput.cs | 124 ++++++++ Models/Inputs/CustomerNationalCreateInput.cs | 109 +++++++ Models/Inputs/CustomerUpdateInput.cs | 106 +++++++ Models/Inputs/CustomerUpdateInputAddress.cs | 120 ++++++++ Models/Inputs/CustomerUpdateParams.cs | 28 ++ .../Inputs/CustomerUpdateWithEditLinkInput.cs | 110 +++++++ .../CustomerUpdateWithEditLinkInputAddress.cs | 122 ++++++++ Models/Inputs/DateRangeInput.cs | 66 ++++ Models/SearchResult.cs | 61 +++- Models/TaxInfoError.cs | 43 +++ Models/TaxInfoValidation.cs | 26 +- README.md | 34 +++ Router/CustomerRouter.cs | 30 +- Router/Router.cs | 2 +- Wrappers/CustomerWrapper.cs | 288 ++++++++++++++--- Wrappers/ICustomerWrapper.cs | 215 ++++++++++++- facturapi-net.csproj | 2 +- openapi/generated.json | 29 ++ openapi/source.json | 5 + package.json | 19 ++ pnpm-lock.yaml | 276 +++++++++++++++++ scripts/generate-sdk.mjs | 92 ++++++ scripts/sdk/compiler.mjs | 289 ++++++++++++++++++ scripts/sdk/compiler.test.mjs | 165 ++++++++++ scripts/sdk/config.json | 25 ++ scripts/sdk/openapi-source.mjs | 81 +++++ scripts/sdk/render-models.mjs | 103 +++++++ scripts/sdk/render-resources.mjs | 142 +++++++++ scripts/sync-openapi.mjs | 24 ++ 47 files changed, 3863 insertions(+), 80 deletions(-) create mode 100644 Models/CustomerEditLinkEmailResult.cs create mode 100644 Models/Inputs/CustomerCreateParams.cs create mode 100644 Models/Inputs/CustomerCreateWithEditLinkInput.cs create mode 100644 Models/Inputs/CustomerCreateWithEditLinkInputAddress.cs create mode 100644 Models/Inputs/CustomerEditLinkEmailInput.cs create mode 100644 Models/Inputs/CustomerForeignAddressInput.cs create mode 100644 Models/Inputs/CustomerForeignCreateInput.cs create mode 100644 Models/Inputs/CustomerGenericCreateInput.cs create mode 100644 Models/Inputs/CustomerGenericCreateInputAddress.cs create mode 100644 Models/Inputs/CustomerListParams.cs create mode 100644 Models/Inputs/CustomerNationalAddressInput.cs create mode 100644 Models/Inputs/CustomerNationalCreateInput.cs create mode 100644 Models/Inputs/CustomerUpdateInput.cs create mode 100644 Models/Inputs/CustomerUpdateInputAddress.cs create mode 100644 Models/Inputs/CustomerUpdateParams.cs create mode 100644 Models/Inputs/CustomerUpdateWithEditLinkInput.cs create mode 100644 Models/Inputs/CustomerUpdateWithEditLinkInputAddress.cs create mode 100644 Models/Inputs/DateRangeInput.cs create mode 100644 Models/TaxInfoError.cs create mode 100644 openapi/generated.json create mode 100644 openapi/source.json create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 scripts/generate-sdk.mjs create mode 100644 scripts/sdk/compiler.mjs create mode 100644 scripts/sdk/compiler.test.mjs create mode 100644 scripts/sdk/config.json create mode 100644 scripts/sdk/openapi-source.mjs create mode 100644 scripts/sdk/render-models.mjs create mode 100644 scripts/sdk/render-resources.mjs create mode 100644 scripts/sync-openapi.mjs diff --git a/.gitattributes b/.gitattributes index 1ff0c42..2820e21 100644 --- a/.gitattributes +++ b/.gitattributes @@ -61,3 +61,32 @@ #*.PDF diff=astextplain #*.rtf diff=astextplain #*.RTF diff=astextplain + +# BEGIN generated SDK +Models/Address.cs linguist-generated=true +Models/Customer.cs linguist-generated=true +Models/CustomerEditLinkEmailResult.cs linguist-generated=true +Models/Inputs/CustomerCreateParams.cs linguist-generated=true +Models/Inputs/CustomerCreateWithEditLinkInput.cs linguist-generated=true +Models/Inputs/CustomerCreateWithEditLinkInputAddress.cs linguist-generated=true +Models/Inputs/CustomerEditLinkEmailInput.cs linguist-generated=true +Models/Inputs/CustomerForeignAddressInput.cs linguist-generated=true +Models/Inputs/CustomerForeignCreateInput.cs linguist-generated=true +Models/Inputs/CustomerGenericCreateInput.cs linguist-generated=true +Models/Inputs/CustomerGenericCreateInputAddress.cs linguist-generated=true +Models/Inputs/CustomerListParams.cs linguist-generated=true +Models/Inputs/CustomerNationalAddressInput.cs linguist-generated=true +Models/Inputs/CustomerNationalCreateInput.cs linguist-generated=true +Models/Inputs/CustomerUpdateInput.cs linguist-generated=true +Models/Inputs/CustomerUpdateInputAddress.cs linguist-generated=true +Models/Inputs/CustomerUpdateParams.cs linguist-generated=true +Models/Inputs/CustomerUpdateWithEditLinkInput.cs linguist-generated=true +Models/Inputs/CustomerUpdateWithEditLinkInputAddress.cs linguist-generated=true +Models/Inputs/DateRangeInput.cs linguist-generated=true +Models/SearchResult.cs linguist-generated=true +Models/TaxInfoError.cs linguist-generated=true +Models/TaxInfoValidation.cs linguist-generated=true +Router/CustomerRouter.cs linguist-generated=true +Wrappers/CustomerWrapper.cs linguist-generated=true +Wrappers/ICustomerWrapper.cs linguist-generated=true +# END generated SDK diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 65fbf91..e08b48e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,3 +56,16 @@ jobs: - name: Test run: dotnet test FacturapiTest/FacturapiTest.csproj --framework ${{ matrix.test_framework }} --configuration Release --no-build + + codegen: + name: Verify generated Customers SDK + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '24' + - uses: pnpm/action-setup@v4 + - run: pnpm install --frozen-lockfile + - run: pnpm test:codegen + - run: pnpm generate:sdk:check diff --git a/.gitignore b/.gitignore index 9491a2f..023fd57 100644 --- a/.gitignore +++ b/.gitignore @@ -360,4 +360,6 @@ MigrationBackup/ .ionide/ # Fody - auto-generated XML schema -FodyWeavers.xsd \ No newline at end of file +FodyWeavers.xsd +# SDK generation tooling +node_modules/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d49595..325e29c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [8.0.0] - 2026-11-13 + +### Breaking + +- `Customer.SatValidatedAt` and `Customer.EditLinkExpiresAt` are nullable dates, matching responses that contain `null`. See the README migration guide. + +### Added + +- Typed customer creation, update and search inputs, with helpers for national, foreign, generic and edit-link workflows. Existing dictionary calls remain supported. +- Expose customer organization, CURP and external ID, and stable fiscal-validation detail codes and sources. + +### Fixed + +- Serialize boolean query values as lowercase `true` and `false`. + ## [7.1.0] - 2026-10-07 ### Added diff --git a/FacturapiTest/ClientCompatibilityTests.cs b/FacturapiTest/ClientCompatibilityTests.cs index af69126..b81826f 100644 --- a/FacturapiTest/ClientCompatibilityTests.cs +++ b/FacturapiTest/ClientCompatibilityTests.cs @@ -32,12 +32,14 @@ public void Router_ListCustomers_SendsExplicitEmptyQueryValues() { var query = new Dictionary { - ["foo"] = "" + ["foo"] = "", + ["enabled"] = true, + ["disabled"] = false }; var url = Router.ListCustomers(query); - Assert.Equal("customers?foo=", url); + Assert.Equal("customers?foo=&enabled=true&disabled=false", url); } [Fact] diff --git a/FacturapiTest/WrapperBehaviorTests.cs b/FacturapiTest/WrapperBehaviorTests.cs index 6e38009..180ad63 100644 --- a/FacturapiTest/WrapperBehaviorTests.cs +++ b/FacturapiTest/WrapperBehaviorTests.cs @@ -1,5 +1,6 @@ using Facturapi; using Facturapi.Wrappers; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.IO; @@ -733,6 +734,72 @@ public async Task RetentionDownloadZipAsync_ReturnsSeekableStreamAtPositionZero( Assert.Equal("zip-content", text); } + [Fact] + public async Task GeneratedCustomerInputs_PreserveOmissionExplicitNullAndTypedResponses() + { + var handler = new RecordingHandler(async (request, cancellationToken) => + { + Assert.Equal(HttpMethod.Put, request.Method); + Assert.Equal("/v2/customers/cus_1", request.RequestUri!.PathAndQuery); + var body = Newtonsoft.Json.Linq.JObject.Parse(await request.Content!.ReadAsStringAsync()); + Assert.Equal(Newtonsoft.Json.Linq.JTokenType.Null, body["email"]!.Type); + Assert.Null(body.Property("legal_name")); + Assert.Equal("Centro", body["address"]!["street"]!.Value()); + Assert.Null(body["address"]!["country"]); + return JsonResponse("{\"id\":\"cus_1\",\"created_at\":\"2026-01-02T00:00:00Z\",\"sat_validated_at\":null,\"edit_link_expires_at\":null,\"organization\":\"org_1\",\"external_id\":\"external_1\",\"address\":{\"zip\":\"86500\"}}"); + }); + ICustomerWrapper wrapper = new CustomerWrapper("test_key", "v2", CreateHttpClient(handler)); + var result = await wrapper.UpdateAsync("cus_1", new CustomerUpdateInput + { + Email = null, + Address = new CustomerUpdateInputAddress { Street = "Centro" } + }); + Assert.Equal("cus_1", result.Id); + Assert.Equal(new DateTime(2026, 1, 2, 0, 0, 0, DateTimeKind.Utc), result.CreatedAt); + Assert.Null(result.SatValidatedAt); + Assert.Null(result.EditLinkExpiresAt); + Assert.Equal("org_1", result.Organization); + Assert.Equal("external_1", result.ExternalId); + Assert.Equal("86500", result.Address.Zip); + } + + [Fact] + public async Task GeneratedCustomerCreateNational_UsesRequiredFieldsAndExistingInterface() + { + var handler = new RecordingHandler(async (request, cancellationToken) => + { + Assert.Equal(HttpMethod.Post, request.Method); + Assert.Equal("/v2/customers", request.RequestUri!.PathAndQuery); + var body = Newtonsoft.Json.Linq.JObject.Parse(await request.Content!.ReadAsStringAsync()); + Assert.Equal("Dunder Mifflin", body["legal_name"]!.Value()); + Assert.Equal("86500", body["address"]!["zip"]!.Value()); + Assert.Null(body.Property("email")); + Assert.Null(body["address"]!["country"]); + return JsonResponse("{\"id\":\"cus_1\"}"); + }); + ICustomerWrapper wrapper = new CustomerWrapper("test_key", "v2", CreateHttpClient(handler)); + Assert.Equal("cus_1", (await wrapper.CreateNationalAsync(new CustomerNationalCreateInput( + "Dunder Mifflin", "ABC101010111", "601", new CustomerNationalAddressInput("86500")))).Id); + } + + [Fact] + public async Task GeneratedCustomerListParams_SerializeDateRangesAndReadCursorPages() + { + var handler = new RecordingHandler((request, cancellationToken) => + { + Assert.Equal("/v2/customers?pagination=cursor&after=abc&date%5Bgte%5D=2026-01-01T00%3A00%3A00Z", request.RequestUri!.PathAndQuery); + return Task.FromResult(JsonResponse("{\"next_cursor\":null,\"data\":[{\"id\":\"cus_1\"}]}")); + }); + var wrapper = new CustomerWrapper("test_key", "v2", CreateHttpClient(handler)); + var result = await wrapper.ListAsync(new CustomerListParams + { + Pagination = "cursor", After = "abc", Date = new DateRangeInput { Gte = "2026-01-01T00:00:00Z" } + }); + Assert.Null(result.TotalResults); + Assert.Null(result.NextCursor); + Assert.Equal("cus_1", Assert.Single(result.Data).Id); + } + private static HttpClient CreateHttpClient(HttpMessageHandler handler) { return new HttpClient(handler) diff --git a/Models/Address.cs b/Models/Address.cs index 230ccfd..a2a22a8 100644 --- a/Models/Address.cs +++ b/Models/Address.cs @@ -1,15 +1,86 @@ -namespace Facturapi +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi { + /// + /// Address + /// public class Address { + /// + /// street + /// Opcional. + /// Admite null. + /// + [JsonProperty("street")] public string Street { get; set; } + + /// + /// exterior + /// Opcional. + /// Admite null. + /// + [JsonProperty("exterior")] public string Exterior { get; set; } + + /// + /// interior + /// Opcional. + /// Admite null. + /// + [JsonProperty("interior")] public string Interior { get; set; } + + /// + /// neighborhood + /// Opcional. + /// Admite null. + /// + [JsonProperty("neighborhood")] public string Neighborhood { get; set; } + + /// + /// city + /// Opcional. + /// Admite null. + /// + [JsonProperty("city")] public string City { get; set; } + + /// + /// municipality + /// Opcional. + /// Admite null. + /// + [JsonProperty("municipality")] public string Municipality { get; set; } + + /// + /// zip + /// Opcional. + /// Admite null. + /// + [JsonProperty("zip")] + public string Zip { get; set; } + + /// + /// state + /// Opcional. + /// Admite null. + /// + [JsonProperty("state")] public string State { get; set; } + + /// + /// country + /// Opcional. + /// Admite null. + /// + [JsonProperty("country")] public string Country { get; set; } - public string Zip { get; set; } + } } diff --git a/Models/Customer.cs b/Models/Customer.cs index d59e870..6e0193c 100644 --- a/Models/Customer.cs +++ b/Models/Customer.cs @@ -1,21 +1,140 @@ -using System; +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; namespace Facturapi { + /// + /// Objeto Customer + /// public class Customer { + /// + /// ID del objeto + /// Requerido. + /// + [JsonProperty("id")] public string Id { get; set; } + + /// + /// Format: date-time + /// Fecha de registro + /// Requerido. + /// + [JsonProperty("created_at")] public DateTime CreatedAt { get; set; } + + /// + /// Si el valor es `true`, indica que el objeto fue creado en ambiente Live; o si es `false`, en ambiente Test. + /// Requerido. + /// + [JsonProperty("livemode")] public bool Livemode { get; set; } - public string Email { get; set; } - public string Phone { get; set; } - public Address Address { get; set; } + + /// + /// Enlace a una página alojada donde el cliente puede editar su información una vez. + /// Ejemplo: https://auto.facturapi.io/tax-info/abcdWXYZ1234 + /// Opcional. + /// Admite null. + /// + [JsonProperty("edit_link")] + public string EditLink { get; set; } + + /// + /// Format: date-time + /// Fecha de expiración del enlace de edición. + /// Opcional. + /// Admite null. + /// + [JsonProperty("edit_link_expires_at")] + public DateTime? EditLinkExpiresAt { get; set; } + + /// + /// Format: date-time + /// Fecha en la que la información fiscal fue validado por el SAT. + /// Opcional. + /// Admite null. + /// + [JsonProperty("sat_validated_at")] + public DateTime? SatValidatedAt { get; set; } + + /// + /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). + /// Opcional. + /// Admite null. + /// + [JsonProperty("legal_name")] public string LegalName { get; set; } + + /// + /// En clientes de México contiene el RFC del cliente. Para extranjeros es opcional y representa el número de registro de identificación tributaria, es decir, el equivalente al RFC en el país del cliente. + /// Opcional. + /// Admite null. + /// + [JsonProperty("tax_id")] public string TaxId { get; set; } + + /// + /// Requerido para clientes nacionales. Clave del régimen fiscal del cliente, del catálogo de [Regímenes Fiscales](https://docs.facturapi.io/api/#r%C3%A9gimen-fiscal). + /// Opcional. + /// Admite null. + /// + [JsonProperty("tax_system")] public string TaxSystem { get; set; } - public DateTime SatValidatedAt { get; set; } - public string EditLink { get; set; } - public DateTime EditLinkExpiresAt { get; set; } + + /// + /// Format: email + /// Dirección de correo electrónico al cual enviar las facturas generadas. + /// Opcional. + /// Admite null. + /// + [JsonProperty("email")] + public string Email { get; set; } + + /// + /// Teléfono del cliente. + /// Opcional. + /// Admite null. + /// + [JsonProperty("phone")] + public string Phone { get; set; } + + /// + /// Uso de CFDI por defecto. + /// Opcional. + /// + [JsonProperty("default_invoice_use")] public string DefaultInvoiceUse { get; set; } + + /// + /// address + /// Opcional. + /// Admite null. + /// + [JsonProperty("address")] + public Address Address { get; set; } + + /// + /// ID de la organización a la que pertenece este recurso. + /// Requerido. + /// + [JsonProperty("organization")] + public string Organization { get; set; } + + /// + /// curp + /// Opcional. + /// + [JsonProperty("curp")] + public string Curp { get; set; } + + /// + /// external_id + /// Opcional. + /// + [JsonProperty("external_id")] + public string ExternalId { get; set; } + } } diff --git a/Models/CustomerEditLinkEmailResult.cs b/Models/CustomerEditLinkEmailResult.cs new file mode 100644 index 0000000..3417d33 --- /dev/null +++ b/Models/CustomerEditLinkEmailResult.cs @@ -0,0 +1,21 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// CustomerEditLinkEmailResult + /// + public class CustomerEditLinkEmailResult + { + /// + /// Indica si el enlace se envió correctamente + /// Opcional. + /// + [JsonProperty("ok")] + public bool? Ok { get; set; } + + } +} diff --git a/Models/Inputs/CustomerCreateParams.cs b/Models/Inputs/CustomerCreateParams.cs new file mode 100644 index 0000000..1dd33f9 --- /dev/null +++ b/Models/Inputs/CustomerCreateParams.cs @@ -0,0 +1,30 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// CustomerCreateParams + /// + public class CustomerCreateParams : Dictionary + { + /// + /// Si pasas el valor `true`, se generará un enlace para que el cliente pueda editar + /// su información fiscal. Este enlace estará disponible en el campo "edit_link", será + /// válido por 3 días y sólo se podrá usar una vez. + /// Además, pasar el valor `true` desactivará la validación de información fiscal con el SAT, + /// permitiendo crear clientes con información incompleta. + /// Con `true`, el body sigue `CustomerCreateWithEditLinkInput`; en otro caso sigue `CustomerCreateInput`. + /// Opcional. + /// + [JsonIgnore] + public bool? CreateEditLink + { + get => TryGetValue("createEditLink", out var value) ? (bool?)value : default; + set => this["createEditLink"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerCreateWithEditLinkInput.cs b/Models/Inputs/CustomerCreateWithEditLinkInput.cs new file mode 100644 index 0000000..eff1fa0 --- /dev/null +++ b/Models/Inputs/CustomerCreateWithEditLinkInput.cs @@ -0,0 +1,110 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// La información del cliente puede estar incompleta cuando createEditLink=true. Los campos opcionales con valor null se tratan como omitidos. Los valores no nulos deben conservar formatos válidos. + /// + public class CustomerCreateWithEditLinkInput : Dictionary + { + /// + /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string LegalName + { + get => TryGetValue("legal_name", out var value) ? (string)value : default; + set => this["legal_name"] = value; + } + + /// + /// En clientes de México contiene el RFC del cliente. Para extranjeros es opcional y representa el número de registro de identificación tributaria, es decir, el equivalente al RFC en el país del cliente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string TaxId + { + get => TryGetValue("tax_id", out var value) ? (string)value : default; + set => this["tax_id"] = value; + } + + /// + /// Format: email + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Email + { + get => TryGetValue("email", out var value) ? (string)value : default; + set => this["email"] = value; + } + + /// + /// Teléfono del cliente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Phone + { + get => TryGetValue("phone", out var value) ? (string)value : default; + set => this["phone"] = value; + } + + /// + /// external_id + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string ExternalId + { + get => TryGetValue("external_id", out var value) ? (string)value : default; + set => this["external_id"] = value; + } + + /// + /// Uso de CFDI que se utiliza en facturas de ingreso cuando se omite use o se envía null. Si el cliente no tiene un uso configurado, se utiliza G03. Para clientes extranjeros o con RFC genérico sólo se admite S01; omitirlo, enviar null o una cadena vacía asigna S01. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string DefaultInvoiceUse + { + get => TryGetValue("default_invoice_use", out var value) ? (string)value : default; + set => this["default_invoice_use"] = value; + } + + /// + /// Requerido para clientes nacionales. Clave del régimen fiscal del cliente, del catálogo de [Regímenes Fiscales](https://docs.facturapi.io/api/#r%C3%A9gimen-fiscal). + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string TaxSystem + { + get => TryGetValue("tax_system", out var value) ? (string)value : default; + set => this["tax_system"] = value; + } + + /// + /// address + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public CustomerCreateWithEditLinkInputAddress Address + { + get => TryGetValue("address", out var value) ? (CustomerCreateWithEditLinkInputAddress)value : default; + set => this["address"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerCreateWithEditLinkInputAddress.cs b/Models/Inputs/CustomerCreateWithEditLinkInputAddress.cs new file mode 100644 index 0000000..63b0931 --- /dev/null +++ b/Models/Inputs/CustomerCreateWithEditLinkInputAddress.cs @@ -0,0 +1,122 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// CustomerCreateWithEditLinkInputAddress + /// + public class CustomerCreateWithEditLinkInputAddress : Dictionary + { + /// + /// Nombre de la calle + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Street + { + get => TryGetValue("street", out var value) ? (string)value : default; + set => this["street"] = value; + } + + /// + /// Número exterior. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Exterior + { + get => TryGetValue("exterior", out var value) ? (string)value : default; + set => this["exterior"] = value; + } + + /// + /// Número interior. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Interior + { + get => TryGetValue("interior", out var value) ? (string)value : default; + set => this["interior"] = value; + } + + /// + /// Colonia + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Neighborhood + { + get => TryGetValue("neighborhood", out var value) ? (string)value : default; + set => this["neighborhood"] = value; + } + + /// + /// Ciudad + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string City + { + get => TryGetValue("city", out var value) ? (string)value : default; + set => this["city"] = value; + } + + /// + /// Municipio o delegación + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Municipality + { + get => TryGetValue("municipality", out var value) ? (string)value : default; + set => this["municipality"] = value; + } + + /// + /// state + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string State + { + get => TryGetValue("state", out var value) ? (string)value : default; + set => this["state"] = value; + } + + /// + /// ISO 3166-1 alpha-3. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Country + { + get => TryGetValue("country", out var value) ? (string)value : default; + set => this["country"] = value; + } + + /// + /// Código postal + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Zip + { + get => TryGetValue("zip", out var value) ? (string)value : default; + set => this["zip"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerEditLinkEmailInput.cs b/Models/Inputs/CustomerEditLinkEmailInput.cs new file mode 100644 index 0000000..765f485 --- /dev/null +++ b/Models/Inputs/CustomerEditLinkEmailInput.cs @@ -0,0 +1,26 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// CustomerEditLinkEmailInput + /// + public class CustomerEditLinkEmailInput : Dictionary + { + /// + /// Correo electrónico de destino. Si se omite o es null, se usa el correo electrónico del cliente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Email + { + get => TryGetValue("email", out var value) ? (string)value : default; + set => this["email"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerForeignAddressInput.cs b/Models/Inputs/CustomerForeignAddressInput.cs new file mode 100644 index 0000000..f8df57c --- /dev/null +++ b/Models/Inputs/CustomerForeignAddressInput.cs @@ -0,0 +1,122 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// CustomerForeignAddressInput + /// + public class CustomerForeignAddressInput : Dictionary + { + /// + /// Crea CustomerForeignAddressInput. + /// + /// Código ISO 3166-1 alpha-3 distinto de MEX. Es necesario para aplicar las reglas de cliente extranjero. Requerido. + public CustomerForeignAddressInput(string country) + { + this["country"] = country; + } + + /// + /// Nombre de la calle + /// Opcional. + /// + [JsonIgnore] + public string Street + { + get => TryGetValue("street", out var value) ? (string)value : default; + set => this["street"] = value; + } + + /// + /// Número exterior. + /// Opcional. + /// + [JsonIgnore] + public string Exterior + { + get => TryGetValue("exterior", out var value) ? (string)value : default; + set => this["exterior"] = value; + } + + /// + /// Número interior. + /// Opcional. + /// + [JsonIgnore] + public string Interior + { + get => TryGetValue("interior", out var value) ? (string)value : default; + set => this["interior"] = value; + } + + /// + /// Colonia + /// Opcional. + /// + [JsonIgnore] + public string Neighborhood + { + get => TryGetValue("neighborhood", out var value) ? (string)value : default; + set => this["neighborhood"] = value; + } + + /// + /// Ciudad + /// Opcional. + /// + [JsonIgnore] + public string City + { + get => TryGetValue("city", out var value) ? (string)value : default; + set => this["city"] = value; + } + + /// + /// Municipio o delegación + /// Opcional. + /// + [JsonIgnore] + public string Municipality + { + get => TryGetValue("municipality", out var value) ? (string)value : default; + set => this["municipality"] = value; + } + + /// + /// Código postal + /// Opcional. + /// + [JsonIgnore] + public string Zip + { + get => TryGetValue("zip", out var value) ? (string)value : default; + set => this["zip"] = value; + } + + /// + /// Código ISO 3166-1 alpha-3 distinto de MEX. Es necesario para aplicar las reglas de cliente extranjero. + /// Requerido. + /// + [JsonIgnore] + public string Country + { + get => TryGetValue("country", out var value) ? (string)value : default; + set => this["country"] = value; + } + + /// + /// state + /// Opcional. + /// + [JsonIgnore] + public string State + { + get => TryGetValue("state", out var value) ? (string)value : default; + set => this["state"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerForeignCreateInput.cs b/Models/Inputs/CustomerForeignCreateInput.cs new file mode 100644 index 0000000..6f56f0a --- /dev/null +++ b/Models/Inputs/CustomerForeignCreateInput.cs @@ -0,0 +1,110 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// Requiere razón social y domicilio con un país explícito distinto de MEX. El identificador fiscal y el código postal son opcionales; el régimen fiscal predeterminado es 616. + /// + public class CustomerForeignCreateInput : Dictionary + { + /// + /// Crea CustomerForeignCreateInput. + /// + /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). Requerido. + /// address Requerido. + public CustomerForeignCreateInput(string legalName, CustomerForeignAddressInput address) + { + this["legal_name"] = legalName; + this["address"] = address; + } + + /// + /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). + /// Requerido. + /// + [JsonIgnore] + public string LegalName + { + get => TryGetValue("legal_name", out var value) ? (string)value : default; + set => this["legal_name"] = value; + } + + /// + /// Format: email + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Email + { + get => TryGetValue("email", out var value) ? (string)value : default; + set => this["email"] = value; + } + + /// + /// Teléfono del cliente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Phone + { + get => TryGetValue("phone", out var value) ? (string)value : default; + set => this["phone"] = value; + } + + /// + /// Uso de CFDI que se utiliza en facturas de ingreso cuando se omite use o se envía null. Si el cliente no tiene un uso configurado, se utiliza G03. Para clientes extranjeros o con RFC genérico sólo se admite S01; omitirlo, enviar null o una cadena vacía asigna S01. + /// Sólo se admite S01. Omitirlo, enviar null o una cadena vacía asigna S01. + /// Valores: "", "S01". + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string DefaultInvoiceUse + { + get => TryGetValue("default_invoice_use", out var value) ? (string)value : default; + set => this["default_invoice_use"] = value; + } + + /// + /// En clientes de México contiene el RFC del cliente. Para extranjeros es opcional y representa el número de registro de identificación tributaria, es decir, el equivalente al RFC en el país del cliente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string TaxId + { + get => TryGetValue("tax_id", out var value) ? (string)value : default; + set => this["tax_id"] = value; + } + + /// + /// Los clientes extranjeros usan 616. Omitirlo, enviar null o una cadena vacía usa el valor predeterminado. + /// Valores: "", "616". + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string TaxSystem + { + get => TryGetValue("tax_system", out var value) ? (string)value : default; + set => this["tax_system"] = value; + } + + /// + /// address + /// Requerido. + /// + [JsonIgnore] + public CustomerForeignAddressInput Address + { + get => TryGetValue("address", out var value) ? (CustomerForeignAddressInput)value : default; + set => this["address"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerGenericCreateInput.cs b/Models/Inputs/CustomerGenericCreateInput.cs new file mode 100644 index 0000000..4e1bab6 --- /dev/null +++ b/Models/Inputs/CustomerGenericCreateInput.cs @@ -0,0 +1,110 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// RFC de público en general XAXX010101000 o RFC genérico extranjero XEXX010101000. Requiere razón social y RFC. El régimen fiscal predeterminado es 616. El código postal es opcional; null o una cadena vacía se tratan como omitidos. + /// + public class CustomerGenericCreateInput : Dictionary + { + /// + /// Crea CustomerGenericCreateInput. + /// + /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). Nombre fiscal o razón social del receptor, sin el régimen societario (ej.: S.A. de C.V.). Para una factura individual con RFC genérico, envía el nombre del receptor y omite global. Para una factura global de ingreso, usa PUBLICO EN GENERAL con el RFC XAXX010101000 y envía global con periodicity, months y year. Requerido. + /// tax_id Valores: "XAXX010101000", "XEXX010101000". Requerido. + public CustomerGenericCreateInput(string legalName, string taxId) + { + this["legal_name"] = legalName; + this["tax_id"] = taxId; + } + + /// + /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). + /// Nombre fiscal o razón social del receptor, sin el régimen societario (ej.: S.A. de C.V.). Para una factura individual con RFC genérico, envía el nombre del receptor y omite global. Para una factura global de ingreso, usa PUBLICO EN GENERAL con el RFC XAXX010101000 y envía global con periodicity, months y year. + /// Requerido. + /// + [JsonIgnore] + public string LegalName + { + get => TryGetValue("legal_name", out var value) ? (string)value : default; + set => this["legal_name"] = value; + } + + /// + /// Format: email + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Email + { + get => TryGetValue("email", out var value) ? (string)value : default; + set => this["email"] = value; + } + + /// + /// Teléfono del cliente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Phone + { + get => TryGetValue("phone", out var value) ? (string)value : default; + set => this["phone"] = value; + } + + /// + /// Uso de CFDI que se utiliza en facturas de ingreso cuando se omite use o se envía null. Si el cliente no tiene un uso configurado, se utiliza G03. Para clientes extranjeros o con RFC genérico sólo se admite S01; omitirlo, enviar null o una cadena vacía asigna S01. + /// Sólo se admite S01. Omitirlo, enviar null o una cadena vacía asigna S01. + /// Valores: "", "S01". + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string DefaultInvoiceUse + { + get => TryGetValue("default_invoice_use", out var value) ? (string)value : default; + set => this["default_invoice_use"] = value; + } + + /// + /// tax_id + /// Valores: "XAXX010101000", "XEXX010101000". + /// Requerido. + /// + [JsonIgnore] + public string TaxId + { + get => TryGetValue("tax_id", out var value) ? (string)value : default; + set => this["tax_id"] = value; + } + + /// + /// Régimen fiscal del receptor. Con RFC genérico, si se omite se utiliza 616 (Sin obligaciones fiscales); si se envía explícitamente, sólo se admite 616. + /// Valores: "616". + /// Opcional. + /// + [JsonIgnore] + public string TaxSystem + { + get => TryGetValue("tax_system", out var value) ? (string)value : default; + set => this["tax_system"] = value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public CustomerGenericCreateInputAddress Address + { + get => TryGetValue("address", out var value) ? (CustomerGenericCreateInputAddress)value : default; + set => this["address"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerGenericCreateInputAddress.cs b/Models/Inputs/CustomerGenericCreateInputAddress.cs new file mode 100644 index 0000000..63269f6 --- /dev/null +++ b/Models/Inputs/CustomerGenericCreateInputAddress.cs @@ -0,0 +1,122 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// CustomerGenericCreateInputAddress + /// + public class CustomerGenericCreateInputAddress : Dictionary + { + /// + /// Nombre de la calle + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Street + { + get => TryGetValue("street", out var value) ? (string)value : default; + set => this["street"] = value; + } + + /// + /// Número exterior. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Exterior + { + get => TryGetValue("exterior", out var value) ? (string)value : default; + set => this["exterior"] = value; + } + + /// + /// Número interior. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Interior + { + get => TryGetValue("interior", out var value) ? (string)value : default; + set => this["interior"] = value; + } + + /// + /// Colonia + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Neighborhood + { + get => TryGetValue("neighborhood", out var value) ? (string)value : default; + set => this["neighborhood"] = value; + } + + /// + /// Ciudad + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string City + { + get => TryGetValue("city", out var value) ? (string)value : default; + set => this["city"] = value; + } + + /// + /// Municipio o delegación + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Municipality + { + get => TryGetValue("municipality", out var value) ? (string)value : default; + set => this["municipality"] = value; + } + + /// + /// state + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string State + { + get => TryGetValue("state", out var value) ? (string)value : default; + set => this["state"] = value; + } + + /// + /// ISO 3166-1 alpha-3. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Country + { + get => TryGetValue("country", out var value) ? (string)value : default; + set => this["country"] = value; + } + + /// + /// Código postal opcional. Para México, si se proporciona debe tener cinco dígitos. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Zip + { + get => TryGetValue("zip", out var value) ? (string)value : default; + set => this["zip"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerListParams.cs b/Models/Inputs/CustomerListParams.cs new file mode 100644 index 0000000..6d05367 --- /dev/null +++ b/Models/Inputs/CustomerListParams.cs @@ -0,0 +1,92 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// CustomerListParams + /// + public class CustomerListParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string Pagination + { + get => TryGetValue("pagination", out var value) ? (string)value : default; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string After + { + get => TryGetValue("after", out var value) ? (string)value : default; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string Before + { + get => TryGetValue("before", out var value) ? (string)value : default; + set => this["before"] = value; + } + + /// + /// Consulta. Texto a buscar en `legal_name` (nombre fiscal) o en `tax_id` (RFC). + /// Opcional. + /// + [JsonIgnore] + public string Q + { + get => TryGetValue("q", out var value) ? (string)value : default; + set => this["q"] = value; + } + + /// + /// Objeto con rango de fechas solicitado. + /// Opcional. + /// + [JsonIgnore] + public DateRangeInput Date + { + get => TryGetValue("date", out var value) ? (DateRangeInput)value : default; + set => this["date"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados (con el `limit` por defecto de 100, la página máxima es 30). + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value : default; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value : default; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerNationalAddressInput.cs b/Models/Inputs/CustomerNationalAddressInput.cs new file mode 100644 index 0000000..559b637 --- /dev/null +++ b/Models/Inputs/CustomerNationalAddressInput.cs @@ -0,0 +1,124 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// CustomerNationalAddressInput + /// + public class CustomerNationalAddressInput : Dictionary + { + /// + /// Crea CustomerNationalAddressInput. + /// + /// Código postal Requerido. + public CustomerNationalAddressInput(string zip) + { + this["zip"] = zip; + } + + /// + /// Nombre de la calle + /// Opcional. + /// + [JsonIgnore] + public string Street + { + get => TryGetValue("street", out var value) ? (string)value : default; + set => this["street"] = value; + } + + /// + /// Número exterior. + /// Opcional. + /// + [JsonIgnore] + public string Exterior + { + get => TryGetValue("exterior", out var value) ? (string)value : default; + set => this["exterior"] = value; + } + + /// + /// Número interior. + /// Opcional. + /// + [JsonIgnore] + public string Interior + { + get => TryGetValue("interior", out var value) ? (string)value : default; + set => this["interior"] = value; + } + + /// + /// Colonia + /// Opcional. + /// + [JsonIgnore] + public string Neighborhood + { + get => TryGetValue("neighborhood", out var value) ? (string)value : default; + set => this["neighborhood"] = value; + } + + /// + /// Ciudad + /// Opcional. + /// + [JsonIgnore] + public string City + { + get => TryGetValue("city", out var value) ? (string)value : default; + set => this["city"] = value; + } + + /// + /// Municipio o delegación + /// Opcional. + /// + [JsonIgnore] + public string Municipality + { + get => TryGetValue("municipality", out var value) ? (string)value : default; + set => this["municipality"] = value; + } + + /// + /// Código postal + /// Requerido. + /// + [JsonIgnore] + public string Zip + { + get => TryGetValue("zip", out var value) ? (string)value : default; + set => this["zip"] = value; + } + + /// + /// state + /// Opcional. + /// + [JsonIgnore] + public string State + { + get => TryGetValue("state", out var value) ? (string)value : default; + set => this["state"] = value; + } + + /// + /// country + /// Valores: "", "MEX". + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Country + { + get => TryGetValue("country", out var value) ? (string)value : default; + set => this["country"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerNationalCreateInput.cs b/Models/Inputs/CustomerNationalCreateInput.cs new file mode 100644 index 0000000..6dcdcb5 --- /dev/null +++ b/Models/Inputs/CustomerNationalCreateInput.cs @@ -0,0 +1,109 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// País MEX, u omitido. Requiere razón social, RFC, régimen fiscal y código postal. Los RFC genéricos usan CustomerGenericCreateInput. + /// + public class CustomerNationalCreateInput : Dictionary + { + /// + /// Crea CustomerNationalCreateInput. + /// + /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). Requerido. + /// En clientes de México contiene el RFC del cliente. Para extranjeros es opcional y representa el número de registro de identificación tributaria, es decir, el equivalente al RFC en el país del cliente. Requerido. + /// Requerido para clientes nacionales. Clave del régimen fiscal del cliente, del catálogo de [Regímenes Fiscales](https://docs.facturapi.io/api/#r%C3%A9gimen-fiscal). Requerido. + /// address Requerido. + public CustomerNationalCreateInput(string legalName, string taxId, string taxSystem, CustomerNationalAddressInput address) + { + this["legal_name"] = legalName; + this["tax_id"] = taxId; + this["tax_system"] = taxSystem; + this["address"] = address; + } + + /// + /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). + /// Requerido. + /// + [JsonIgnore] + public string LegalName + { + get => TryGetValue("legal_name", out var value) ? (string)value : default; + set => this["legal_name"] = value; + } + + /// + /// Format: email + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Email + { + get => TryGetValue("email", out var value) ? (string)value : default; + set => this["email"] = value; + } + + /// + /// Teléfono del cliente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Phone + { + get => TryGetValue("phone", out var value) ? (string)value : default; + set => this["phone"] = value; + } + + /// + /// Uso de CFDI que se utiliza en facturas de ingreso cuando se omite use o se envía null. Si el cliente no tiene un uso configurado, se utiliza G03. Para clientes extranjeros o con RFC genérico sólo se admite S01; omitirlo, enviar null o una cadena vacía asigna S01. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string DefaultInvoiceUse + { + get => TryGetValue("default_invoice_use", out var value) ? (string)value : default; + set => this["default_invoice_use"] = value; + } + + /// + /// En clientes de México contiene el RFC del cliente. Para extranjeros es opcional y representa el número de registro de identificación tributaria, es decir, el equivalente al RFC en el país del cliente. + /// Requerido. + /// + [JsonIgnore] + public string TaxId + { + get => TryGetValue("tax_id", out var value) ? (string)value : default; + set => this["tax_id"] = value; + } + + /// + /// Requerido para clientes nacionales. Clave del régimen fiscal del cliente, del catálogo de [Regímenes Fiscales](https://docs.facturapi.io/api/#r%C3%A9gimen-fiscal). + /// Requerido. + /// + [JsonIgnore] + public string TaxSystem + { + get => TryGetValue("tax_system", out var value) ? (string)value : default; + set => this["tax_system"] = value; + } + + /// + /// address + /// Requerido. + /// + [JsonIgnore] + public CustomerNationalAddressInput Address + { + get => TryGetValue("address", out var value) ? (CustomerNationalAddressInput)value : default; + set => this["address"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerUpdateInput.cs b/Models/Inputs/CustomerUpdateInput.cs new file mode 100644 index 0000000..ad80411 --- /dev/null +++ b/Models/Inputs/CustomerUpdateInput.cs @@ -0,0 +1,106 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// En una actualización sin createEditLink=true, los campos omitidos conservan su valor. Un valor null borra los campos que admiten null; un campo opcional puede omitirse sin que necesariamente admita null. No se permite null en legal_name, tax_id, tax_system ni address. En email, phone y los campos opcionales street, exterior, interior, neighborhood, city, municipality y state del domicilio, una cadena vacía o sólo espacios se normaliza a null. El código postal vacío no se acepta. + /// + public class CustomerUpdateInput : Dictionary + { + /// + /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). + /// Opcional. + /// + [JsonIgnore] + public string LegalName + { + get => TryGetValue("legal_name", out var value) ? (string)value : default; + set => this["legal_name"] = value; + } + + /// + /// En clientes de México contiene el RFC del cliente. Para extranjeros es opcional y representa el número de registro de identificación tributaria, es decir, el equivalente al RFC en el país del cliente. + /// Opcional. + /// + [JsonIgnore] + public string TaxId + { + get => TryGetValue("tax_id", out var value) ? (string)value : default; + set => this["tax_id"] = value; + } + + /// + /// email + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Email + { + get => TryGetValue("email", out var value) ? (string)value : default; + set => this["email"] = value; + } + + /// + /// Teléfono del cliente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Phone + { + get => TryGetValue("phone", out var value) ? (string)value : default; + set => this["phone"] = value; + } + + /// + /// external_id + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string ExternalId + { + get => TryGetValue("external_id", out var value) ? (string)value : default; + set => this["external_id"] = value; + } + + /// + /// Uso de CFDI que se utiliza en facturas de ingreso cuando se omite use o se envía null. Si el cliente no tiene un uso configurado, se utiliza G03. Para clientes extranjeros o con RFC genérico sólo se admite S01; omitirlo, enviar null o una cadena vacía asigna S01. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string DefaultInvoiceUse + { + get => TryGetValue("default_invoice_use", out var value) ? (string)value : default; + set => this["default_invoice_use"] = value; + } + + /// + /// Requerido para clientes nacionales. Clave del régimen fiscal del cliente, del catálogo de [Regímenes Fiscales](https://docs.facturapi.io/api/#r%C3%A9gimen-fiscal). + /// Opcional. + /// + [JsonIgnore] + public string TaxSystem + { + get => TryGetValue("tax_system", out var value) ? (string)value : default; + set => this["tax_system"] = value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public CustomerUpdateInputAddress Address + { + get => TryGetValue("address", out var value) ? (CustomerUpdateInputAddress)value : default; + set => this["address"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerUpdateInputAddress.cs b/Models/Inputs/CustomerUpdateInputAddress.cs new file mode 100644 index 0000000..70875d5 --- /dev/null +++ b/Models/Inputs/CustomerUpdateInputAddress.cs @@ -0,0 +1,120 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// CustomerUpdateInputAddress + /// + public class CustomerUpdateInputAddress : Dictionary + { + /// + /// Nombre de la calle + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Street + { + get => TryGetValue("street", out var value) ? (string)value : default; + set => this["street"] = value; + } + + /// + /// Número exterior. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Exterior + { + get => TryGetValue("exterior", out var value) ? (string)value : default; + set => this["exterior"] = value; + } + + /// + /// Número interior. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Interior + { + get => TryGetValue("interior", out var value) ? (string)value : default; + set => this["interior"] = value; + } + + /// + /// Colonia + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Neighborhood + { + get => TryGetValue("neighborhood", out var value) ? (string)value : default; + set => this["neighborhood"] = value; + } + + /// + /// Ciudad + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string City + { + get => TryGetValue("city", out var value) ? (string)value : default; + set => this["city"] = value; + } + + /// + /// Municipio o delegación + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Municipality + { + get => TryGetValue("municipality", out var value) ? (string)value : default; + set => this["municipality"] = value; + } + + /// + /// Código postal + /// Opcional. + /// + [JsonIgnore] + public string Zip + { + get => TryGetValue("zip", out var value) ? (string)value : default; + set => this["zip"] = value; + } + + /// + /// state + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string State + { + get => TryGetValue("state", out var value) ? (string)value : default; + set => this["state"] = value; + } + + /// + /// ISO 3166-1 alpha-3. + /// Opcional. + /// + [JsonIgnore] + public string Country + { + get => TryGetValue("country", out var value) ? (string)value : default; + set => this["country"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerUpdateParams.cs b/Models/Inputs/CustomerUpdateParams.cs new file mode 100644 index 0000000..90b1491 --- /dev/null +++ b/Models/Inputs/CustomerUpdateParams.cs @@ -0,0 +1,28 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// CustomerUpdateParams + /// + public class CustomerUpdateParams : Dictionary + { + /// + /// Si pasas el valor `true`, se generará un enlace para que el cliente pueda editar + /// su información fiscal. Este enlace estará disponible en el campo "edit_link", será + /// válido por 3 días y sólo se podrá usar una vez. Pasar el valor `true` al editar + /// **no** desactivará la validación de información fiscal con el SAT. + /// Opcional. + /// + [JsonIgnore] + public bool? CreateEditLink + { + get => TryGetValue("createEditLink", out var value) ? (bool?)value : default; + set => this["createEditLink"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerUpdateWithEditLinkInput.cs b/Models/Inputs/CustomerUpdateWithEditLinkInput.cs new file mode 100644 index 0000000..d28fd3b --- /dev/null +++ b/Models/Inputs/CustomerUpdateWithEditLinkInput.cs @@ -0,0 +1,110 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// Con createEditLink=true, los campos omitidos conservan su valor y null borra el valor existente, incluidos los datos fiscales. Los valores no nulos deben ser válidos. En email, phone y los campos opcionales street, exterior, interior, neighborhood, city, municipality y state del domicilio, una cadena vacía o sólo espacios se normaliza a null. El código postal vacío no se acepta. + /// + public class CustomerUpdateWithEditLinkInput : Dictionary + { + /// + /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string LegalName + { + get => TryGetValue("legal_name", out var value) ? (string)value : default; + set => this["legal_name"] = value; + } + + /// + /// En clientes de México contiene el RFC del cliente. Para extranjeros es opcional y representa el número de registro de identificación tributaria, es decir, el equivalente al RFC en el país del cliente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string TaxId + { + get => TryGetValue("tax_id", out var value) ? (string)value : default; + set => this["tax_id"] = value; + } + + /// + /// email + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Email + { + get => TryGetValue("email", out var value) ? (string)value : default; + set => this["email"] = value; + } + + /// + /// Teléfono del cliente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Phone + { + get => TryGetValue("phone", out var value) ? (string)value : default; + set => this["phone"] = value; + } + + /// + /// external_id + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string ExternalId + { + get => TryGetValue("external_id", out var value) ? (string)value : default; + set => this["external_id"] = value; + } + + /// + /// Uso de CFDI que se utiliza en facturas de ingreso cuando se omite use o se envía null. Si el cliente no tiene un uso configurado, se utiliza G03. Para clientes extranjeros o con RFC genérico sólo se admite S01; omitirlo, enviar null o una cadena vacía asigna S01. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string DefaultInvoiceUse + { + get => TryGetValue("default_invoice_use", out var value) ? (string)value : default; + set => this["default_invoice_use"] = value; + } + + /// + /// Requerido para clientes nacionales. Clave del régimen fiscal del cliente, del catálogo de [Regímenes Fiscales](https://docs.facturapi.io/api/#r%C3%A9gimen-fiscal). + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string TaxSystem + { + get => TryGetValue("tax_system", out var value) ? (string)value : default; + set => this["tax_system"] = value; + } + + /// + /// address + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public CustomerUpdateWithEditLinkInputAddress Address + { + get => TryGetValue("address", out var value) ? (CustomerUpdateWithEditLinkInputAddress)value : default; + set => this["address"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerUpdateWithEditLinkInputAddress.cs b/Models/Inputs/CustomerUpdateWithEditLinkInputAddress.cs new file mode 100644 index 0000000..1cbb0cc --- /dev/null +++ b/Models/Inputs/CustomerUpdateWithEditLinkInputAddress.cs @@ -0,0 +1,122 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// CustomerUpdateWithEditLinkInputAddress + /// + public class CustomerUpdateWithEditLinkInputAddress : Dictionary + { + /// + /// Nombre de la calle + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Street + { + get => TryGetValue("street", out var value) ? (string)value : default; + set => this["street"] = value; + } + + /// + /// Número exterior. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Exterior + { + get => TryGetValue("exterior", out var value) ? (string)value : default; + set => this["exterior"] = value; + } + + /// + /// Número interior. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Interior + { + get => TryGetValue("interior", out var value) ? (string)value : default; + set => this["interior"] = value; + } + + /// + /// Colonia + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Neighborhood + { + get => TryGetValue("neighborhood", out var value) ? (string)value : default; + set => this["neighborhood"] = value; + } + + /// + /// Ciudad + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string City + { + get => TryGetValue("city", out var value) ? (string)value : default; + set => this["city"] = value; + } + + /// + /// Municipio o delegación + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Municipality + { + get => TryGetValue("municipality", out var value) ? (string)value : default; + set => this["municipality"] = value; + } + + /// + /// state + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string State + { + get => TryGetValue("state", out var value) ? (string)value : default; + set => this["state"] = value; + } + + /// + /// ISO 3166-1 alpha-3. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Country + { + get => TryGetValue("country", out var value) ? (string)value : default; + set => this["country"] = value; + } + + /// + /// Código postal + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string Zip + { + get => TryGetValue("zip", out var value) ? (string)value : default; + set => this["zip"] = value; + } + + } +} diff --git a/Models/Inputs/DateRangeInput.cs b/Models/Inputs/DateRangeInput.cs new file mode 100644 index 0000000..8da46de --- /dev/null +++ b/Models/Inputs/DateRangeInput.cs @@ -0,0 +1,66 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// DateRangeInput + /// + public class DateRangeInput : Dictionary + { + /// + /// Greater than + /// Format: date-time + /// Límite inferior exclusivo del rango de fechas a solicitar. + /// Opcional. + /// + [JsonIgnore] + public string Gt + { + get => TryGetValue("gt", out var value) ? (string)value : default; + set => this["gt"] = value; + } + + /// + /// Greater than or equals + /// Format: date-time + /// Límite inferior inclusivo del rango de fechas a solicitar. + /// Opcional. + /// + [JsonIgnore] + public string Gte + { + get => TryGetValue("gte", out var value) ? (string)value : default; + set => this["gte"] = value; + } + + /// + /// Lesser than + /// Format: date-time + /// Límite superior exclusivo del rango de fechas a solicitar. + /// Opcional. + /// + [JsonIgnore] + public string Lt + { + get => TryGetValue("lt", out var value) ? (string)value : default; + set => this["lt"] = value; + } + + /// + /// Lesser than or equals + /// Format: date-time + /// Límite superior inclusivo del rango de fechas a solicitar. + /// Opcional. + /// + [JsonIgnore] + public string Lte + { + get => TryGetValue("lte", out var value) ? (string)value : default; + set => this["lte"] = value; + } + + } +} diff --git a/Models/SearchResult.cs b/Models/SearchResult.cs index 1964a0b..6515842 100644 --- a/Models/SearchResult.cs +++ b/Models/SearchResult.cs @@ -1,16 +1,71 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; using System.Collections.Generic; +using Newtonsoft.Json; namespace Facturapi { + /// + /// Resultados paginados. + /// public class SearchResult { - // Nullable: cursor responses after the first page omit page/totals. + /// + /// Página + /// Número de página. Vale 0 cuando no hay coincidencias. Se omite en todas las respuestas de paginación por cursor, incluida la primera página. + /// Opcional. + /// + [JsonProperty("page")] public int? Page { get; set; } + + /// + /// Páginas totales + /// Total de páginas. Se omite en todas las respuestas de paginación por cursor, incluida la primera página. + /// Opcional. + /// + [JsonProperty("total_pages")] public int? TotalPages { get; set; } + + /// + /// Resultados totales + /// Número de elementos individuales en todas las páginas de resultados. En modo `pagination=cursor` solo se incluye en la primera página de la búsqueda (sin `after`/`before`); el total no cambia entre páginas. + /// Opcional. + /// + [JsonProperty("total_results")] public int? TotalResults { get; set; } - public bool? TotalsAreCapped { get; set; } - public string NextCursor { get; set; } + + /// + /// Cursor anterior + /// Cursor para obtener la página anterior de resultados. Es `null` en la primera página. Solo disponible con `pagination=cursor`. + /// Opcional. + /// Admite null. + /// + [JsonProperty("previous_cursor")] public string PreviousCursor { get; set; } + + /// + /// Cursor siguiente + /// Cursor para obtener la página siguiente de resultados. Es `null` cuando no hay más resultados. Solo disponible con `pagination=cursor`. + /// Opcional. + /// Admite null. + /// + [JsonProperty("next_cursor")] + public string NextCursor { get; set; } + + /// + /// Resultados con tope + /// Indica si `total_results` está limitado a 3,000 porque existen más resultados de los reportados. + /// Opcional. + /// + [JsonProperty("totals_are_capped")] + public bool? TotalsAreCapped { get; set; } + + /// + /// data + /// Requerido. + /// + [JsonProperty("data")] public List Data { get; set; } + } } diff --git a/Models/TaxInfoError.cs b/Models/TaxInfoError.cs new file mode 100644 index 0000000..f8291bd --- /dev/null +++ b/Models/TaxInfoError.cs @@ -0,0 +1,43 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// TaxInfoValidationError + /// + public class TaxInfoError + { + /// + /// Indica que Facturapi generó el detalle de validación. + /// Valores: "facturapi". + /// Requerido. + /// + [JsonProperty("source")] + public string Source { get; set; } + + /// + /// Código estable del detalle de validación. + /// Requerido. + /// + [JsonProperty("code")] + public string Code { get; set; } + + /// + /// Ruta del campo cuya información fiscal no es válida. + /// Opcional. + /// + [JsonProperty("path")] + public string Path { get; set; } + + /// + /// Mensaje descriptivo del detalle de validación. + /// Requerido. + /// + [JsonProperty("message")] + public string Message { get; set; } + + } +} diff --git a/Models/TaxInfoValidation.cs b/Models/TaxInfoValidation.cs index aac8e53..5e9a24c 100644 --- a/Models/TaxInfoValidation.cs +++ b/Models/TaxInfoValidation.cs @@ -1,16 +1,28 @@ -using System.Collections.Generic; +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; +using Newtonsoft.Json; namespace Facturapi { - public class TaxInfoError - { - public string Message { get; set; } - public string Path { get; set; } - } - + /// + /// TaxInfoValidation + /// public class TaxInfoValidation { + /// + /// Indica si la información fiscal del cliente coincide con los registros del SAT + /// Requerido. + /// + [JsonProperty("is_valid")] public bool IsValid { get; set; } + + /// + /// Detalles de validación fiscal. Es un array vacío cuando `is_valid` es `true`. + /// Requerido. + /// + [JsonProperty("errors")] public TaxInfoError[] Errors { get; set; } + } } diff --git a/README.md b/README.md index 4e8ebc7..4c44bce 100644 --- a/README.md +++ b/README.md @@ -209,3 +209,37 @@ Mándanos un Pull Request! Agradecemos todo tipo de ayuda :) ### Contáctanos contacto@facturapi.io + +## Clientes con entradas tipadas + +Puedes seguir usando `Dictionary` y las firmas existentes. Los modelos de entrada también son diccionarios y sólo serializan los campos asignados; un `null` explícito se conserva. + +```csharp +var customer = await facturapi.Customer.CreateNationalAsync( + new CustomerNationalCreateInput("Dunder Mifflin", "ABC101010111", "601", + new CustomerNationalAddressInput("86500"))); +await facturapi.Customer.UpdateAsync(customer.Id, new CustomerUpdateInput { Email = null }); +``` + +También están disponibles `CreateForeignAsync`, `CreateGenericAsync`, `CreateWithEditLinkAsync` y `UpdateWithEditLinkAsync`, y los filtros `CustomerListParams`, `CustomerCreateParams` y `CustomerUpdateParams`. + +### Migración a v8 + +`Customer.SatValidatedAt` y `Customer.EditLinkExpiresAt` ahora son `DateTime?`, porque la API admite `null`. Si asignabas estas propiedades a una variable `DateTime`, maneja el caso nulo antes de acceder a `.Value`. Las llamadas con diccionarios no requieren cambios. Las implementaciones manuales de `ICustomerWrapper` deben añadir los métodos nuevos. + +## SDK generation + +The Customers resource is generated from the public OpenAPI contract. The scope currently includes Customers and its input/output models; other resources remain handwritten. Generated files carry a banner and must be changed through the generator or the public specification. + +For SDK development, install Node.js 24+ and pnpm 11.9, then run: + +```sh +pnpm install --frozen-lockfile +pnpm generate:sdk +pnpm test:codegen +pnpm generate:sdk:check +``` + +`openapi/source.json` pins the public documentation commit. To update it, run `pnpm sync:openapi [public-ref]` followed by generation and the SDK's normal test suite. Generation downloads the spec at that exact commit into memory; builds and consumers use the tracked generated code and need neither Node.js nor access to the spec. CI verifies regeneration and rejects unbound Customers operations or unsupported schema shapes instead of silently widening their types. + +The TypeScript compiler resolves the contract after `openapi-typescript`; C# renderers emit models, methods and documentation. SDK bindings preserve method names, generic pagination and established compatibility behavior. Input models distinguish properties that were never assigned from explicit `null`. Literal string constraints remain documented strings so existing catalog values and response parsing stay compatible; server-side validation still applies. diff --git a/Router/CustomerRouter.cs b/Router/CustomerRouter.cs index 5d86d4d..ace3eff 100644 --- a/Router/CustomerRouter.cs +++ b/Router/CustomerRouter.cs @@ -1,41 +1,45 @@ -using System.Collections.Generic; +// Generated by pnpm generate:sdk. Do not edit directly. +using System; +using System.Collections.Generic; namespace Facturapi { internal static partial class Router { - public static string ListCustomers(Dictionary query = null) + public static string CreateCustomer(Dictionary query = null) { - return UriWithQuery("customers", query); + return UriWithQuery($"customers", query); } - public static string RetrieveCustomer(string id, Dictionary query = null) + public static string ListCustomers(Dictionary query = null) { - return $"{UriWithQuery($"customers/{id}", query)}"; + return UriWithQuery($"customers", query); } - public static string ValidateCustomerTaxInfo(string id) + public static string RetrieveCustomer(string id) { - return $"customers/{id}/tax-info-validation"; + return UriWithQuery($"customers/{Uri.EscapeDataString(id)}"); } - public static string CreateCustomer(Dictionary query = null) + public static string UpdateCustomer(string id, Dictionary query = null) { - return UriWithQuery("customers", query); + return UriWithQuery($"customers/{Uri.EscapeDataString(id)}", query); } public static string DeleteCustomer(string id) { - return RetrieveCustomer(id); + return UriWithQuery($"customers/{Uri.EscapeDataString(id)}"); } - public static string UpdateCustomer(string id, Dictionary query = null) { - return RetrieveCustomer(id, query); + public static string ValidateCustomerTaxInfo(string id) + { + return UriWithQuery($"customers/{Uri.EscapeDataString(id)}/tax-info-validation"); } public static string SendEditLinkByEmail(string id) { - return $"{UriWithQuery($"customers/{id}/email-edit-link")}"; + return UriWithQuery($"customers/{Uri.EscapeDataString(id)}/email-edit-link"); } + } } diff --git a/Router/Router.cs b/Router/Router.cs index 6bfbcf0..67c446d 100644 --- a/Router/Router.cs +++ b/Router/Router.cs @@ -64,7 +64,7 @@ private static void AppendQueryPart(List parts, string key, object value return; } - parts.Add(Uri.EscapeDataString(key) + "=" + Uri.EscapeDataString(value.ToString() ?? String.Empty)); + parts.Add(Uri.EscapeDataString(key) + "=" + Uri.EscapeDataString(value is bool boolean ? (boolean ? "true" : "false") : value.ToString() ?? String.Empty)); } } } diff --git a/Wrappers/CustomerWrapper.cs b/Wrappers/CustomerWrapper.cs index ab7e64a..625737b 100644 --- a/Wrappers/CustomerWrapper.cs +++ b/Wrappers/CustomerWrapper.cs @@ -1,94 +1,300 @@ -using Newtonsoft.Json; +// Generated by pnpm generate:sdk. Do not edit directly. +using System; using System.Collections.Generic; using System.Net.Http; using System.Text; -using System.Threading.Tasks; using System.Threading; +using System.Threading.Tasks; +using Newtonsoft.Json; namespace Facturapi.Wrappers { + /// + /// Operaciones de clientes. + /// public class CustomerWrapper : BaseWrapper, ICustomerWrapper { - internal CustomerWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) - { - } + internal CustomerWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) {} - public async Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Crear cliente + /// + /// Registra un nuevo cliente en Facturapi. + /// + /// Esta llamada valida que los datos fiscales coincidan con + /// los registros del SAT para ese RFC, de lo contrario, la llamada + /// devolverá un error indicando el problema. + /// + /// Una vez creado el cliente y obtenido un objeto de respuesta, + /// te recomendamos guardar el ID en tu base de datos junto a la información + /// de tu cliente. Posteriormente, puedes llamar al endpoint de Crear Factura + /// pasando el ID del cliente en lugar de repetir la información. + /// + /// Por último, ten en cuenta que los clientes que crees en ambiente _Test_ **no se + /// comparten** con el ambiente _Live_. + /// + /// + /// Datos de la solicitud. Admite los modelos Customer*Input. + /// Parámetros de consulta. Admite CustomerCreateParams. + /// Permite cancelar la solicitud. + /// Un objeto `Customer` con la misma información ya existía + /// + public async Task CreateAsync(Dictionary data, Dictionary queryParams = null, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.ListCustomers(query), cancellationToken).ConfigureAwait(false)) + using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) + using (var response = await client.PostAsync(Router.CreateCustomer(queryParams), content, cancellationToken).ConfigureAwait(false)) { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - - var searchResult = JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - return searchResult; + await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); + return JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync().ConfigureAwait(false), jsonSettings); } } - public async Task CreateAsync(Dictionary data, Dictionary queryParams = null, CancellationToken cancellationToken = default) + /// + /// Listar clientes + /// + /// Regresa una lista paginada de todos los clientes de una organización o realiza una búsqueda de acuerdo a parámetros + /// + /// Parámetros de consulta. Admite CustomerListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public async Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.CreateCustomer(queryParams), content, cancellationToken).ConfigureAwait(false)) + using (var response = await client.GetAsync(Router.ListCustomers(query), cancellationToken).ConfigureAwait(false)) { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var customer = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return customer; + await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); + return JsonConvert.DeserializeObject>(await response.Content.ReadAsStringAsync().ConfigureAwait(false), jsonSettings); } } + /// + /// Obtener cliente por ID + /// + /// Regresa el objeto 'Customer' relacionado al `id` especificado. + /// + /// ID del objeto a obtener + /// Permite cancelar la solicitud. + /// Objeto `Customer` + /// public async Task RetrieveAsync(string id, CancellationToken cancellationToken = default) { using (var response = await client.GetAsync(Router.RetrieveCustomer(id), cancellationToken).ConfigureAwait(false)) { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var customer = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return customer; + await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); + return JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync().ConfigureAwait(false), jsonSettings); } } - public async Task DeleteAsync(string id, CancellationToken cancellationToken = default) + /// + /// Editar cliente + /// + /// Actualiza la información de un cliente existente, asignando los valores de los parámetros enviados. Los parámetros que no se envíen en la petición no se modificarán. + /// + /// ID del objeto a editar + /// Datos de la solicitud. Admite los modelos Customer*Input. + /// Parámetros de consulta. Admite CustomerUpdateParams. + /// Permite cancelar la solicitud. + /// Objeto `Customer` editado correctamente + /// + public async Task UpdateAsync(string id, Dictionary data, Dictionary queryParams = null, CancellationToken cancellationToken = default) { - using (var response = await client.DeleteAsync(Router.DeleteCustomer(id), cancellationToken).ConfigureAwait(false)) + using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) + using (var response = await client.PutAsync(Router.UpdateCustomer(id, queryParams), content, cancellationToken).ConfigureAwait(false)) { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var customer = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return customer; + await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); + return JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync().ConfigureAwait(false), jsonSettings); } } - public async Task UpdateAsync(string id, Dictionary data, Dictionary queryParams = null, CancellationToken cancellationToken = default) + /// + /// Eliminar cliente + /// + /// Elimina el cliente de tu organización. Las facturas asociadas al cliente **no** se eliminarán. + /// + /// ID del objeto a eliminar + /// Permite cancelar la solicitud. + /// Objeto `Customer` eliminado correctamente + /// + public async Task DeleteAsync(string id, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PutAsync(Router.UpdateCustomer(id, queryParams), content, cancellationToken).ConfigureAwait(false)) + using (var response = await client.DeleteAsync(Router.DeleteCustomer(id), cancellationToken).ConfigureAwait(false)) { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var customer = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return customer; + await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); + return JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync().ConfigureAwait(false), jsonSettings); } } + /// + /// Validar información fiscal + /// + /// Valida que la información fiscal del cliente coincida con los registros del SAT. + /// + /// Su función principal es validar que los datos del cliente registrado siguen cumpliendo la validación del SAT. + /// + /// :::tip + /// Las operaciones de crear cliente, editar cliente y crear factura ya realizan una + /// validación de la información del cliente, por lo que **no** es necesario llamar a este endpoint + /// antes de realizar dichas operaciones. + /// ::: + /// + /// + /// ID del objeto `Customer` a validar + /// Permite cancelar la solicitud. + /// Resultado de la validación + /// public async Task ValidateTaxInfoAsync(string id, CancellationToken cancellationToken = default) { using (var response = await client.GetAsync(Router.ValidateCustomerTaxInfo(id), cancellationToken).ConfigureAwait(false)) { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var validation = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return validation; + await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); + return JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync().ConfigureAwait(false), jsonSettings); } } + /// + /// Enviar enlace de edición por correo electrónico + /// + /// Envía un enlace para que el cliente pueda editar su información fiscal. + /// + /// Este enlace estará disponible en el campo `edit_link`, será válido por 3 días y sólo se podrá usar una vez. + /// + /// + /// ID del objeto `Customer` a editar + /// Datos de la solicitud. Admite CustomerEditLinkEmailInput. + /// Permite cancelar la solicitud. + /// Enlace de edición enviado correctamente + /// public async Task SendEditLinkByEmailAsync(string id, Dictionary data, CancellationToken cancellationToken = default) { using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) using (var response = await client.PostAsync(Router.SendEditLinkByEmail(id), content, cancellationToken).ConfigureAwait(false)) { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); + await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); } } + + /// + /// Crear cliente + /// + /// Registra un nuevo cliente en Facturapi. + /// + /// Esta llamada valida que los datos fiscales coincidan con + /// los registros del SAT para ese RFC, de lo contrario, la llamada + /// devolverá un error indicando el problema. + /// + /// Una vez creado el cliente y obtenido un objeto de respuesta, + /// te recomendamos guardar el ID en tu base de datos junto a la información + /// de tu cliente. Posteriormente, puedes llamar al endpoint de Crear Factura + /// pasando el ID del cliente en lugar de repetir la información. + /// + /// Por último, ten en cuenta que los clientes que crees en ambiente _Test_ **no se + /// comparten** con el ambiente _Live_. + /// + /// + /// País MEX, u omitido. Requiere razón social, RFC, régimen fiscal y código postal. Los RFC genéricos usan CustomerGenericCreateInput. + /// Permite cancelar la solicitud. + /// Un objeto `Customer` con la misma información ya existía + /// + public Task CreateNationalAsync(CustomerNationalCreateInput data, CancellationToken cancellationToken = default) + { + return CreateAsync(data, null, cancellationToken); + } + + /// + /// Crear cliente + /// + /// Registra un nuevo cliente en Facturapi. + /// + /// Esta llamada valida que los datos fiscales coincidan con + /// los registros del SAT para ese RFC, de lo contrario, la llamada + /// devolverá un error indicando el problema. + /// + /// Una vez creado el cliente y obtenido un objeto de respuesta, + /// te recomendamos guardar el ID en tu base de datos junto a la información + /// de tu cliente. Posteriormente, puedes llamar al endpoint de Crear Factura + /// pasando el ID del cliente en lugar de repetir la información. + /// + /// Por último, ten en cuenta que los clientes que crees en ambiente _Test_ **no se + /// comparten** con el ambiente _Live_. + /// + /// + /// Requiere razón social y domicilio con un país explícito distinto de MEX. El identificador fiscal y el código postal son opcionales; el régimen fiscal predeterminado es 616. + /// Permite cancelar la solicitud. + /// Un objeto `Customer` con la misma información ya existía + /// + public Task CreateForeignAsync(CustomerForeignCreateInput data, CancellationToken cancellationToken = default) + { + return CreateAsync(data, null, cancellationToken); + } + + /// + /// Crear cliente + /// + /// Registra un nuevo cliente en Facturapi. + /// + /// Esta llamada valida que los datos fiscales coincidan con + /// los registros del SAT para ese RFC, de lo contrario, la llamada + /// devolverá un error indicando el problema. + /// + /// Una vez creado el cliente y obtenido un objeto de respuesta, + /// te recomendamos guardar el ID en tu base de datos junto a la información + /// de tu cliente. Posteriormente, puedes llamar al endpoint de Crear Factura + /// pasando el ID del cliente en lugar de repetir la información. + /// + /// Por último, ten en cuenta que los clientes que crees en ambiente _Test_ **no se + /// comparten** con el ambiente _Live_. + /// + /// + /// RFC de público en general XAXX010101000 o RFC genérico extranjero XEXX010101000. Requiere razón social y RFC. El régimen fiscal predeterminado es 616. El código postal es opcional; null o una cadena vacía se tratan como omitidos. + /// Permite cancelar la solicitud. + /// Un objeto `Customer` con la misma información ya existía + /// + public Task CreateGenericAsync(CustomerGenericCreateInput data, CancellationToken cancellationToken = default) + { + return CreateAsync(data, null, cancellationToken); + } + + /// + /// Crear cliente + /// + /// Registra un nuevo cliente en Facturapi. + /// + /// Esta llamada valida que los datos fiscales coincidan con + /// los registros del SAT para ese RFC, de lo contrario, la llamada + /// devolverá un error indicando el problema. + /// + /// Una vez creado el cliente y obtenido un objeto de respuesta, + /// te recomendamos guardar el ID en tu base de datos junto a la información + /// de tu cliente. Posteriormente, puedes llamar al endpoint de Crear Factura + /// pasando el ID del cliente en lugar de repetir la información. + /// + /// Por último, ten en cuenta que los clientes que crees en ambiente _Test_ **no se + /// comparten** con el ambiente _Live_. + /// + /// + /// La información del cliente puede estar incompleta cuando createEditLink=true. Los campos opcionales con valor null se tratan como omitidos. Los valores no nulos deben conservar formatos válidos. + /// Permite cancelar la solicitud. + /// Un objeto `Customer` con la misma información ya existía + /// + public Task CreateWithEditLinkAsync(CustomerCreateWithEditLinkInput data, CancellationToken cancellationToken = default) + { + return CreateAsync(data, new Dictionary { ["createEditLink"] = true }, cancellationToken); + } + + /// + /// Editar cliente + /// + /// Actualiza la información de un cliente existente, asignando los valores de los parámetros enviados. Los parámetros que no se envíen en la petición no se modificarán. + /// + /// ID del cliente. + /// Con createEditLink=true, los campos omitidos conservan su valor y null borra el valor existente, incluidos los datos fiscales. Los valores no nulos deben ser válidos. En email, phone y los campos opcionales street, exterior, interior, neighborhood, city, municipality y state del domicilio, una cadena vacía o sólo espacios se normaliza a null. El código postal vacío no se acepta. + /// Permite cancelar la solicitud. + /// Objeto `Customer` editado correctamente + /// + public Task UpdateWithEditLinkAsync(string id, CustomerUpdateWithEditLinkInput data, CancellationToken cancellationToken = default) + { + return UpdateAsync(id, data, new Dictionary { ["createEditLink"] = true }, cancellationToken); + } + } } diff --git a/Wrappers/ICustomerWrapper.cs b/Wrappers/ICustomerWrapper.cs index 9006fd1..3ae7d38 100644 --- a/Wrappers/ICustomerWrapper.cs +++ b/Wrappers/ICustomerWrapper.cs @@ -1,17 +1,228 @@ +// Generated by pnpm generate:sdk. Do not edit directly. using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace Facturapi.Wrappers { + /// + /// Operaciones de clientes para inyección de dependencias. + /// public interface ICustomerWrapper { - Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default); + /// + /// Crear cliente + /// + /// Registra un nuevo cliente en Facturapi. + /// + /// Esta llamada valida que los datos fiscales coincidan con + /// los registros del SAT para ese RFC, de lo contrario, la llamada + /// devolverá un error indicando el problema. + /// + /// Una vez creado el cliente y obtenido un objeto de respuesta, + /// te recomendamos guardar el ID en tu base de datos junto a la información + /// de tu cliente. Posteriormente, puedes llamar al endpoint de Crear Factura + /// pasando el ID del cliente en lugar de repetir la información. + /// + /// Por último, ten en cuenta que los clientes que crees en ambiente _Test_ **no se + /// comparten** con el ambiente _Live_. + /// + /// + /// Datos de la solicitud. Admite los modelos Customer*Input. + /// Parámetros de consulta. Admite CustomerCreateParams. + /// Permite cancelar la solicitud. + /// Un objeto `Customer` con la misma información ya existía + /// Task CreateAsync(Dictionary data, Dictionary queryParams = null, CancellationToken cancellationToken = default); + + /// + /// Listar clientes + /// + /// Regresa una lista paginada de todos los clientes de una organización o realiza una búsqueda de acuerdo a parámetros + /// + /// Parámetros de consulta. Admite CustomerListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default); + + /// + /// Obtener cliente por ID + /// + /// Regresa el objeto 'Customer' relacionado al `id` especificado. + /// + /// ID del objeto a obtener + /// Permite cancelar la solicitud. + /// Objeto `Customer` + /// Task RetrieveAsync(string id, CancellationToken cancellationToken = default); - Task DeleteAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Editar cliente + /// + /// Actualiza la información de un cliente existente, asignando los valores de los parámetros enviados. Los parámetros que no se envíen en la petición no se modificarán. + /// + /// ID del objeto a editar + /// Datos de la solicitud. Admite los modelos Customer*Input. + /// Parámetros de consulta. Admite CustomerUpdateParams. + /// Permite cancelar la solicitud. + /// Objeto `Customer` editado correctamente + /// Task UpdateAsync(string id, Dictionary data, Dictionary queryParams = null, CancellationToken cancellationToken = default); + + /// + /// Eliminar cliente + /// + /// Elimina el cliente de tu organización. Las facturas asociadas al cliente **no** se eliminarán. + /// + /// ID del objeto a eliminar + /// Permite cancelar la solicitud. + /// Objeto `Customer` eliminado correctamente + /// + Task DeleteAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Validar información fiscal + /// + /// Valida que la información fiscal del cliente coincida con los registros del SAT. + /// + /// Su función principal es validar que los datos del cliente registrado siguen cumpliendo la validación del SAT. + /// + /// :::tip + /// Las operaciones de crear cliente, editar cliente y crear factura ya realizan una + /// validación de la información del cliente, por lo que **no** es necesario llamar a este endpoint + /// antes de realizar dichas operaciones. + /// ::: + /// + /// + /// ID del objeto `Customer` a validar + /// Permite cancelar la solicitud. + /// Resultado de la validación + /// Task ValidateTaxInfoAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Enviar enlace de edición por correo electrónico + /// + /// Envía un enlace para que el cliente pueda editar su información fiscal. + /// + /// Este enlace estará disponible en el campo `edit_link`, será válido por 3 días y sólo se podrá usar una vez. + /// + /// + /// ID del objeto `Customer` a editar + /// Datos de la solicitud. Admite CustomerEditLinkEmailInput. + /// Permite cancelar la solicitud. + /// Enlace de edición enviado correctamente + /// Task SendEditLinkByEmailAsync(string id, Dictionary data, CancellationToken cancellationToken = default); + + /// + /// Crear cliente + /// + /// Registra un nuevo cliente en Facturapi. + /// + /// Esta llamada valida que los datos fiscales coincidan con + /// los registros del SAT para ese RFC, de lo contrario, la llamada + /// devolverá un error indicando el problema. + /// + /// Una vez creado el cliente y obtenido un objeto de respuesta, + /// te recomendamos guardar el ID en tu base de datos junto a la información + /// de tu cliente. Posteriormente, puedes llamar al endpoint de Crear Factura + /// pasando el ID del cliente en lugar de repetir la información. + /// + /// Por último, ten en cuenta que los clientes que crees en ambiente _Test_ **no se + /// comparten** con el ambiente _Live_. + /// + /// + /// País MEX, u omitido. Requiere razón social, RFC, régimen fiscal y código postal. Los RFC genéricos usan CustomerGenericCreateInput. + /// Permite cancelar la solicitud. + /// Un objeto `Customer` con la misma información ya existía + /// + Task CreateNationalAsync(CustomerNationalCreateInput data, CancellationToken cancellationToken = default); + + /// + /// Crear cliente + /// + /// Registra un nuevo cliente en Facturapi. + /// + /// Esta llamada valida que los datos fiscales coincidan con + /// los registros del SAT para ese RFC, de lo contrario, la llamada + /// devolverá un error indicando el problema. + /// + /// Una vez creado el cliente y obtenido un objeto de respuesta, + /// te recomendamos guardar el ID en tu base de datos junto a la información + /// de tu cliente. Posteriormente, puedes llamar al endpoint de Crear Factura + /// pasando el ID del cliente en lugar de repetir la información. + /// + /// Por último, ten en cuenta que los clientes que crees en ambiente _Test_ **no se + /// comparten** con el ambiente _Live_. + /// + /// + /// Requiere razón social y domicilio con un país explícito distinto de MEX. El identificador fiscal y el código postal son opcionales; el régimen fiscal predeterminado es 616. + /// Permite cancelar la solicitud. + /// Un objeto `Customer` con la misma información ya existía + /// + Task CreateForeignAsync(CustomerForeignCreateInput data, CancellationToken cancellationToken = default); + + /// + /// Crear cliente + /// + /// Registra un nuevo cliente en Facturapi. + /// + /// Esta llamada valida que los datos fiscales coincidan con + /// los registros del SAT para ese RFC, de lo contrario, la llamada + /// devolverá un error indicando el problema. + /// + /// Una vez creado el cliente y obtenido un objeto de respuesta, + /// te recomendamos guardar el ID en tu base de datos junto a la información + /// de tu cliente. Posteriormente, puedes llamar al endpoint de Crear Factura + /// pasando el ID del cliente en lugar de repetir la información. + /// + /// Por último, ten en cuenta que los clientes que crees en ambiente _Test_ **no se + /// comparten** con el ambiente _Live_. + /// + /// + /// RFC de público en general XAXX010101000 o RFC genérico extranjero XEXX010101000. Requiere razón social y RFC. El régimen fiscal predeterminado es 616. El código postal es opcional; null o una cadena vacía se tratan como omitidos. + /// Permite cancelar la solicitud. + /// Un objeto `Customer` con la misma información ya existía + /// + Task CreateGenericAsync(CustomerGenericCreateInput data, CancellationToken cancellationToken = default); + + /// + /// Crear cliente + /// + /// Registra un nuevo cliente en Facturapi. + /// + /// Esta llamada valida que los datos fiscales coincidan con + /// los registros del SAT para ese RFC, de lo contrario, la llamada + /// devolverá un error indicando el problema. + /// + /// Una vez creado el cliente y obtenido un objeto de respuesta, + /// te recomendamos guardar el ID en tu base de datos junto a la información + /// de tu cliente. Posteriormente, puedes llamar al endpoint de Crear Factura + /// pasando el ID del cliente en lugar de repetir la información. + /// + /// Por último, ten en cuenta que los clientes que crees en ambiente _Test_ **no se + /// comparten** con el ambiente _Live_. + /// + /// + /// La información del cliente puede estar incompleta cuando createEditLink=true. Los campos opcionales con valor null se tratan como omitidos. Los valores no nulos deben conservar formatos válidos. + /// Permite cancelar la solicitud. + /// Un objeto `Customer` con la misma información ya existía + /// + Task CreateWithEditLinkAsync(CustomerCreateWithEditLinkInput data, CancellationToken cancellationToken = default); + + /// + /// Editar cliente + /// + /// Actualiza la información de un cliente existente, asignando los valores de los parámetros enviados. Los parámetros que no se envíen en la petición no se modificarán. + /// + /// ID del cliente. + /// Con createEditLink=true, los campos omitidos conservan su valor y null borra el valor existente, incluidos los datos fiscales. Los valores no nulos deben ser válidos. En email, phone y los campos opcionales street, exterior, interior, neighborhood, city, municipality y state del domicilio, una cadena vacía o sólo espacios se normaliza a null. El código postal vacío no se acepta. + /// Permite cancelar la solicitud. + /// Objeto `Customer` editado correctamente + /// + Task UpdateWithEditLinkAsync(string id, CustomerUpdateWithEditLinkInput data, CancellationToken cancellationToken = default); + } } diff --git a/facturapi-net.csproj b/facturapi-net.csproj index 0ea2c8c..a14475e 100644 --- a/facturapi-net.csproj +++ b/facturapi-net.csproj @@ -11,7 +11,7 @@ SDK oficial de Facturapi para .NET para facturación electrónica en México (CFDI), envío de documentos, búsqueda y trazabilidad. factura factura-electronica facturacion cfdi cfdi40 sat invoice invoicing facturapi mexico Facturapi - 7.1.0 + 8.0.0 $(Version) MIT false diff --git a/openapi/generated.json b/openapi/generated.json new file mode 100644 index 0000000..3525915 --- /dev/null +++ b/openapi/generated.json @@ -0,0 +1,29 @@ +[ + ".gitattributes", + "Models/Address.cs", + "Models/Customer.cs", + "Models/CustomerEditLinkEmailResult.cs", + "Models/Inputs/CustomerCreateParams.cs", + "Models/Inputs/CustomerCreateWithEditLinkInput.cs", + "Models/Inputs/CustomerCreateWithEditLinkInputAddress.cs", + "Models/Inputs/CustomerEditLinkEmailInput.cs", + "Models/Inputs/CustomerForeignAddressInput.cs", + "Models/Inputs/CustomerForeignCreateInput.cs", + "Models/Inputs/CustomerGenericCreateInput.cs", + "Models/Inputs/CustomerGenericCreateInputAddress.cs", + "Models/Inputs/CustomerListParams.cs", + "Models/Inputs/CustomerNationalAddressInput.cs", + "Models/Inputs/CustomerNationalCreateInput.cs", + "Models/Inputs/CustomerUpdateInput.cs", + "Models/Inputs/CustomerUpdateInputAddress.cs", + "Models/Inputs/CustomerUpdateParams.cs", + "Models/Inputs/CustomerUpdateWithEditLinkInput.cs", + "Models/Inputs/CustomerUpdateWithEditLinkInputAddress.cs", + "Models/Inputs/DateRangeInput.cs", + "Models/SearchResult.cs", + "Models/TaxInfoError.cs", + "Models/TaxInfoValidation.cs", + "Router/CustomerRouter.cs", + "Wrappers/CustomerWrapper.cs", + "Wrappers/ICustomerWrapper.cs" +] diff --git a/openapi/source.json b/openapi/source.json new file mode 100644 index 0000000..18a92f8 --- /dev/null +++ b/openapi/source.json @@ -0,0 +1,5 @@ +{ + "repository": "FacturAPI/facturapi-docs", + "revision": "57b2bd16f8b0f02e31f01631a3a50d41868a6a93", + "path": "website/openapi_v2.yaml" +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..a13ddec --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "private": true, + "type": "module", + "scripts": { + "generate:sdk": "node scripts/generate-sdk.mjs", + "generate:sdk:check": "node scripts/generate-sdk.mjs --check", + "sync:openapi": "node scripts/sync-openapi.mjs", + "test:codegen": "node --test scripts/sdk/*.test.mjs" + }, + "devDependencies": { + "js-yaml": "5.5.0", + "openapi-typescript": "7.13.0", + "typescript": "6.0.3" + }, + "packageManager": "pnpm@11.9.0", + "engines": { + "node": ">=24" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..1da4336 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,276 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + js-yaml: + specifier: 5.5.0 + version: 5.5.0 + openapi-typescript: + specifier: 7.13.0 + version: 7.13.0(typescript@6.0.3) + typescript: + specifier: 6.0.3 + version: 6.0.3 + +packages: + + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + + '@redocly/ajv@8.11.2': + resolution: {integrity: sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==} + + '@redocly/config@0.22.0': + resolution: {integrity: sha512-gAy93Ddo01Z3bHuVdPWfCwzgfaYgMdaZPcfL7JZ7hWJoK9V0lXDbigTWkhiPFAaLWzbOJ+kbUQG1+XwIm0KRGQ==} + + '@redocly/openapi-core@1.34.24': + resolution: {integrity: sha512-jDFMu4zirFVOF9nEWCT31s7OzzVhkxZkb4lO3yZhkdPXAOspLo10ED9thVgm6gtI0dJBTLa+mNP0IYeZpVSYGA==} + engines: {node: '>=18.17.0', npm: '>=9.5.0'} + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + argparse@3.0.4: + resolution: {integrity: sha512-fwWK3Zq22l4XJJjx5mcBHGikIk+hJqO+32dPm0Jur7+rtG5x1scOjSfdT9ZKeWHPpsya/l0HHK4tDImBkTrtvA==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@2.1.8: + resolution: {integrity: sha512-BnlDzDYQoplTsZSvPi86CNzmbcb07X8ufR8fk1zivaiEJlXJkiq1MQyDCVmlWcsWbj6aWXqHnrwwevbrm/Saig==} + + change-case@5.4.4: + resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} + + colorette@1.4.0: + resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + index-to-position@1.2.0: + resolution: {integrity: sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==} + engines: {node: '>=18'} + + js-levenshtein@1.1.6: + resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==} + engines: {node: '>=0.10.0'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.3.2: + resolution: {integrity: sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==} + hasBin: true + + js-yaml@5.5.0: + resolution: {integrity: sha512-paNr4LFIFPjeeSmwNYdrb8FafLLG/Cr2Af3GjbsHJ5CxIjH4r0c2emlmRdAtpPAieP1gRVzk6buBbVP5gBMGAg==} + hasBin: true + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + openapi-typescript@7.13.0: + resolution: {integrity: sha512-EFP392gcqXS7ntPvbhBzbF8TyBA+baIYEm791Hy5YkjDYKTnk/Tn5OQeKm5BIZvJihpp8Zzr4hzx0Irde1LNGQ==} + hasBin: true + peerDependencies: + typescript: ^5.x + + parse-json@8.3.0: + resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} + engines: {node: '>=18'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + supports-color@10.2.2: + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} + engines: {node: '>=18'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + + uri-js-replace@1.0.2: + resolution: {integrity: sha512-VeBBt/nMxedczht3KDL2yBBMJqIxpCQLMZp3UJ1otcWwUHdQW4IiyHpJivExzSK+FdxTowRfGL4FmwDqH9+S8Q==} + + yaml-ast-parser@0.0.43: + resolution: {integrity: sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + +snapshots: + + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/helper-validator-identifier@7.29.7': {} + + '@redocly/ajv@8.11.2': + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js-replace: 1.0.2 + + '@redocly/config@0.22.0': {} + + '@redocly/openapi-core@1.34.24(supports-color@10.2.2)': + dependencies: + '@redocly/ajv': 8.11.2 + '@redocly/config': 0.22.0 + colorette: 1.4.0 + https-proxy-agent: 7.0.6(supports-color@10.2.2) + js-levenshtein: 1.1.6 + js-yaml: 4.3.2 + minimatch: 5.1.9 + pluralize: 8.0.0 + yaml-ast-parser: 0.0.43 + transitivePeerDependencies: + - supports-color + + agent-base@7.1.4: {} + + ansi-colors@4.1.3: {} + + argparse@2.0.1: {} + + argparse@3.0.4: {} + + balanced-match@1.0.2: {} + + brace-expansion@2.1.8: + dependencies: + balanced-match: 1.0.2 + + change-case@5.4.4: {} + + colorette@1.4.0: {} + + debug@4.4.3(supports-color@10.2.2): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 10.2.2 + + fast-deep-equal@3.1.3: {} + + https-proxy-agent@7.0.6(supports-color@10.2.2): + dependencies: + agent-base: 7.1.4 + debug: 4.4.3(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + + index-to-position@1.2.0: {} + + js-levenshtein@1.1.6: {} + + js-tokens@4.0.0: {} + + js-yaml@4.3.2: + dependencies: + argparse: 2.0.1 + + js-yaml@5.5.0: + dependencies: + argparse: 3.0.4 + + json-schema-traverse@1.0.0: {} + + minimatch@5.1.9: + dependencies: + brace-expansion: 2.1.8 + + ms@2.1.3: {} + + openapi-typescript@7.13.0(typescript@6.0.3): + dependencies: + '@redocly/openapi-core': 1.34.24(supports-color@10.2.2) + ansi-colors: 4.1.3 + change-case: 5.4.4 + parse-json: 8.3.0 + supports-color: 10.2.2 + typescript: 6.0.3 + yargs-parser: 21.1.1 + + parse-json@8.3.0: + dependencies: + '@babel/code-frame': 7.29.7 + index-to-position: 1.2.0 + type-fest: 4.41.0 + + picocolors@1.1.1: {} + + pluralize@8.0.0: {} + + require-from-string@2.0.2: {} + + supports-color@10.2.2: {} + + type-fest@4.41.0: {} + + typescript@6.0.3: {} + + uri-js-replace@1.0.2: {} + + yaml-ast-parser@0.0.43: {} + + yargs-parser@21.1.1: {} diff --git a/scripts/generate-sdk.mjs b/scripts/generate-sdk.mjs new file mode 100644 index 0000000..30db1ce --- /dev/null +++ b/scripts/generate-sdk.mjs @@ -0,0 +1,92 @@ +import assert from "node:assert/strict"; +import { readFile, writeFile, mkdir, unlink } from "node:fs/promises"; +import { banner } from "./sdk/render-models.mjs"; +import { readSpecification } from "./sdk/openapi-source.mjs"; +import { compileContract } from "./sdk/compiler.mjs"; +import { renderModels } from "./sdk/render-models.mjs"; +import { renderResources } from "./sdk/render-resources.mjs"; + +const root = new URL("../", import.meta.url); +const config = JSON.parse( + await readFile(new URL("scripts/sdk/config.json", root), "utf8"), +); +const contract = await compileContract( + await readSpecification( + JSON.parse(await readFile(new URL("openapi/source.json", root), "utf8")), + ), + config, +); +const outputs = new Map([ + ...renderModels(contract), + ...renderResources(contract), +]); +for (const [filename, content] of outputs) + outputs.set(filename, content.replace(/[ \t]+$/gm, "")); +let attributes = ""; +try { + attributes = await readFile(new URL(".gitattributes", root), "utf8"); +} catch (error) { + if (error.code !== "ENOENT") throw error; +} +const generatedAttributes = + "# BEGIN generated SDK\n" + + [...outputs.keys()] + .sort() + .map((filename) => `${filename} linguist-generated=true`) + .join("\n") + + "\n# END generated SDK"; +outputs.set( + ".gitattributes", + attributes.includes("# BEGIN generated SDK") + ? attributes.replace( + /# BEGIN generated SDK[\s\S]*?# END generated SDK/, + generatedAttributes, + ) + : attributes.trimEnd() + + (attributes ? "\n\n" : "") + + generatedAttributes + + "\n", +); +// The manifest detects removed as well as changed artifacts in check mode. +outputs.set( + "openapi/generated.json", + JSON.stringify([...outputs.keys()].sort(), null, 2) + "\n", +); +let previous = []; +try { + previous = JSON.parse( + await readFile(new URL("openapi/generated.json", root), "utf8"), + ); +} catch (error) { + if (error.code !== "ENOENT") throw error; +} +for (const filename of previous.filter((filename) => !outputs.has(filename))) { + assert( + !process.argv.includes("--check"), + `Obsolete generated file: ${filename}. Run pnpm generate:sdk.`, + ); + assert( + !filename.includes("..") && !filename.startsWith("/"), + "Invalid generated path.", + ); + assert( + (await readFile(new URL(filename, root), "utf8")).includes(banner), + `Refusing to remove handwritten file: ${filename}`, + ); + await unlink(new URL(filename, root)); +} +for (const [filename, content] of outputs) { + if (process.argv.includes("--check")) { + assert.equal( + await readFile(new URL(filename, root), "utf8"), + content, + `${filename} is stale. Run pnpm generate:sdk.`, + ); + } else { + await mkdir(new URL(".", new URL(filename, root)), { recursive: true }); + await writeFile(new URL(filename, root), content); + } +} +console.log( + `${process.argv.includes("--check") ? "Verified" : "Generated"} Customers: ${contract.methods.length} operations, ${contract.models.length} models.`, +); diff --git a/scripts/sdk/compiler.mjs b/scripts/sdk/compiler.mjs new file mode 100644 index 0000000..cfd8df3 --- /dev/null +++ b/scripts/sdk/compiler.mjs @@ -0,0 +1,289 @@ +import assert from "node:assert/strict"; +import openapiTS, { astToString } from "openapi-typescript"; +import ts from "typescript"; + +export const pascal = (value) => + value.replace(/(^|[_-])([a-z])/g, (_, prefix, letter) => + letter.toUpperCase(), + ); +export const camel = (value) => + pascal(value).replace(/^./, (letter) => letter.toLowerCase()); + +// Let openapi-typescript and the TypeScript checker resolve references, +// intersections and nullability. Rendering never reinterprets JSON Schema. +export async function compileContract(spec, config) { + const operations = new Map(); + for (const [path, item] of Object.entries(spec.paths)) { + for (const [verb, operation] of Object.entries(item)) { + if ( + !operation.operationId || + !( + path === "/" + config.resource || + path.startsWith("/" + config.resource + "/") + ) + ) + continue; + assert( + !operations.has(operation.operationId), + `Duplicate operation: ${operation.operationId}`, + ); + operations.set(operation.operationId, { ...operation, path, verb }); + } + } + assert.deepEqual( + [...operations.keys()].sort(), + Object.values(config.methods).sort(), + "Every Customers operation must have a method binding.", + ); + const filename = "/contract.ts"; + const content = + "type Integer = number & { readonly __integer: unique symbol };\n" + + astToString( + await openapiTS(spec, { + defaultNonNullable: false, + transform(schema) { + const type = + schema.format === "date-time" + ? ts.factory.createTypeReferenceNode("Date") + : schema.type === "integer" || + (Array.isArray(schema.type) && + schema.type.includes("integer") && + schema.type.every( + (type) => type === "integer" || type === "null", + )) + ? ts.factory.createTypeReferenceNode("Integer") + : null; + if (type) + return Array.isArray(schema.type) && schema.type.includes("null") + ? ts.factory.createUnionTypeNode([ + type, + ts.factory.createLiteralTypeNode(ts.factory.createNull()), + ]) + : type; + }, + }), + ); + const options = { + strict: true, + target: ts.ScriptTarget.ES2022, + skipLibCheck: true, + }; + const host = ts.createCompilerHost(options); + const original = host.getSourceFile.bind(host); + host.getSourceFile = (path, version, ...rest) => + path === filename + ? ts.createSourceFile(path, content, version, true) + : original(path, version, ...rest); + const program = ts.createProgram([filename], options, host); + assert.equal( + program.getSemanticDiagnostics().length, + 0, + "The generated OpenAPI types must compile.", + ); + const checker = program.getTypeChecker(); + const source = program.getSourceFile(filename); + const at = (symbol) => checker.getTypeOfSymbolAtLocation(symbol, source); + const property = (type, name) => { + const symbol = checker.getPropertyOfType( + checker.getNonNullableType(type), + name, + ); + assert(symbol, `Missing contract property: ${name}`); + return at(symbol); + }; + const schemas = property( + checker.getTypeAtLocation( + source.statements.find( + (node) => + ts.isInterfaceDeclaration(node) && node.name.text === "components", + ), + ), + "schemas", + ); + const operationTypes = checker.getTypeAtLocation( + source.statements.find( + (node) => + ts.isInterfaceDeclaration(node) && node.name.text === "operations", + ), + ); + const models = new Map(); + const names = new Map(); + for (const symbol of checker.getPropertiesOfType(schemas)) { + names.set( + checker.getNonNullableType(at(symbol)), + config.modelNames[symbol.name] || symbol.name, + ); + } + const compiled = new Map(); + const prose = (symbol) => + [ + ts.displayPartsToString(symbol.getDocumentationComment(checker)), + ...symbol + .getJsDocTags(checker) + .filter((tag) => ["description", "deprecated"].includes(tag.name)) + .map((tag) => ts.displayPartsToString(tag.text)), + ] + .filter(Boolean) + .join("\n"); + function compile(type, hint, input) { + const nullable = + type.isUnion() && + type.types.some((item) => item.flags & ts.TypeFlags.Null); + type = checker.getNonNullableType(type); + if (type.aliasSymbol?.name === "Integer") + return { kind: "integer", nullable }; + if (type.symbol?.name === "Date") + return { kind: input ? "string" : "date", nullable }; + if ( + type.flags & ts.TypeFlags.BooleanLike || + (type.isUnion() && + type.types.every((item) => item.flags & ts.TypeFlags.BooleanLike)) + ) + return { kind: "boolean", nullable }; + if (type.flags & ts.TypeFlags.NumberLike) + return { kind: "number", nullable }; + if ( + type.flags & ts.TypeFlags.String || + (type.isUnion() && + type.types.every((item) => item.flags & ts.TypeFlags.StringLike) && + type.types.some((item) => !item.isStringLiteral())) + ) + return { kind: "string", nullable }; + if ( + type.isStringLiteral() || + (type.isUnion() && type.types.every((item) => item.isStringLiteral())) + ) { + // Literal constraints remain visible in docs; strings preserve compatibility + // with catalog values and allow response enums to evolve without parse errors. + return { + kind: "string", + nullable, + values: (type.isUnion() ? type.types : [type]).map( + (item) => item.value, + ), + }; + } + if (checker.isArrayType(type)) + return { + kind: "array", + nullable, + item: compile( + checker.getIndexTypeOfType(type, ts.IndexKind.Number), + hint + "Item", + input, + ), + }; + assert( + !( + type.flags & + (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Never) + ), + `Unsupported open type at ${hint}`, + ); + assert( + !type.isUnion(), + `Unsupported union at ${hint}: ${checker.typeToString(type)}. Add an explicit binding instead of widening the type.`, + ); + assert( + !checker.getIndexTypeOfType(type, ts.IndexKind.String), + `Unsupported open dictionary at ${hint}`, + ); + assert( + checker.getPropertiesOfType(type).length > 0, + `Unsupported open type at ${hint}`, + ); + if (compiled.has(type)) + return { kind: "model", ref: compiled.get(type), nullable }; + const name = + config.modelNames[names.get(type) || hint] || names.get(type) || hint; + assert.match(name, /^[A-Za-z][A-Za-z0-9]*$/, `Invalid model name: ${name}`); + assert(!models.has(name), `Conflicting generated model: ${name}`); + compiled.set(type, name); + const model = { + name, + input, + description: + spec.components.schemas[name]?.description || + spec.components.schemas[name]?.title || + name, + properties: [], + }; + models.set(name, model); + model.properties = checker.getPropertiesOfType(type).map((symbol) => ({ + name: symbol.name, + required: !(symbol.flags & ts.SymbolFlags.Optional), + description: prose(symbol), + ...compile(at(symbol), name + pascal(symbol.name), input), + })); + return { kind: "model", ref: name, nullable }; + } + for (const name of config.inputs) + compile(property(schemas, name), name, true); + compile(property(schemas, "Customer"), "Customer", false); + const methods = []; + for (const [name, id] of Object.entries(config.methods)) { + const operation = operations.get(id); + const type = property(operationTypes, id); + const parameters = property(type, "parameters"); + const query = property(parameters, "query"); + const hasQuery = !( + checker.getNonNullableType(query).flags & ts.TypeFlags.Never + ); + const method = { name, id, ...operation }; + if (hasQuery) + method.query = compile(query, "Customer" + pascal(name) + "Params", true); + if (name === "sendEditLinkByEmail") + method.body = compile( + property( + property(property(type, "requestBody"), "content"), + "application/json", + ), + "CustomerEditLinkEmailInput", + true, + ); + const responses = property(type, "responses"); + const success = checker + .getPropertiesOfType(responses) + .filter((symbol) => /^2\d\d$/.test(symbol.name)); + assert(success.length > 0, `Missing success response for ${id}`); + assert( + success.every( + (response) => + property(property(at(response), "content"), "application/json") === + property(property(at(success[0]), "content"), "application/json"), + ), + `Bind the response variants for ${id}`, + ); + method.response = compile( + property(property(at(success[0]), "content"), "application/json"), + name === "validateTaxInfo" + ? "TaxInfoValidation" + : name === "sendEditLinkByEmail" + ? "CustomerEditLinkEmailResult" + : "Customer" + pascal(name) + "Result", + false, + ); + const body = operation.requestBody?.$ref + ? operation.requestBody.$ref + .slice(2) + .split("/") + .reduce((target, part) => target[part], spec) + : operation.requestBody; + method.bodyRequired = body && body.required !== false; + method.responseDescription = + operation.responses[success[0].name].description; + method.parameters = [ + ...(spec.paths[operation.path].parameters || []), + ...(operation.parameters || []), + ].map((parameter) => + parameter.$ref + ? parameter.$ref + .slice(2) + .split("/") + .reduce((target, part) => target[part], spec) + : parameter, + ); + methods.push(method); + } + return { models: [...models.values()], methods }; +} diff --git a/scripts/sdk/compiler.test.mjs b/scripts/sdk/compiler.test.mjs new file mode 100644 index 0000000..7ac1c03 --- /dev/null +++ b/scripts/sdk/compiler.test.mjs @@ -0,0 +1,165 @@ +import test from "node:test"; +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; +import { compileContract } from "./compiler.mjs"; +import { renderModels } from "./render-models.mjs"; + +const config = JSON.parse( + await readFile(new URL("./config.json", import.meta.url)), +); +function fixture() { + return { + openapi: "3.1.0", + info: { title: "Contract", version: "1" }, + paths: { + "/customers/{id}": { + get: { + operationId: "getCustomer", + parameters: [ + { + in: "path", + name: "id", + required: true, + schema: { type: "string" }, + }, + ], + responses: { + 200: { + description: "Customer", + content: { + "application/json": { + schema: { $ref: "#/components/schemas/Customer" }, + }, + }, + }, + }, + }, + }, + }, + components: { + schemas: { + Customer: { + allOf: [ + { $ref: "#/components/schemas/Base" }, + { + type: "object", + properties: { + created_at: { type: ["string", "null"], format: "date-time" }, + contact: { $ref: "#/components/schemas/Contact" }, + }, + }, + ], + }, + Base: { + type: "object", + required: ["id"], + properties: { + id: { type: "string", description: "Public identifier." }, + }, + }, + Contact: { + type: "object", + properties: { email: { type: ["string", "null"] } }, + }, + CustomerUpdateInput: { + type: "object", + properties: { + legal_name: { type: "string" }, + email: { type: ["string", "null"] }, + country: { type: "string", default: "MEX" }, + page: { type: ["integer", "null"] }, + }, + }, + }, + }, + }; +} +const binding = { + ...config, + methods: { retrieve: "getCustomer" }, + inputs: ["CustomerUpdateInput"], +}; + +test("resolves references and intersections, preserving integer, defaults, optionality and explicit null", async () => { + const contract = await compileContract(fixture(), binding); + const customer = contract.models.find((model) => model.name === "Customer"); + assert.equal( + customer.properties.find((field) => field.name === "id").required, + true, + ); + assert.match( + customer.properties.find((field) => field.name === "id").description, + /Public identifier/, + ); + assert.equal( + customer.properties.find((field) => field.name === "created_at").nullable, + true, + ); + assert.equal( + customer.properties.find((field) => field.name === "created_at").kind, + "date", + ); + assert.equal( + customer.properties.find((field) => field.name === "contact").ref, + "Contact", + ); + const input = contract.models.find( + (model) => model.name === "CustomerUpdateInput", + ); + assert.equal( + input.properties.find((field) => field.name === "country").required, + false, + ); + assert.equal( + input.properties.find((field) => field.name === "legal_name").nullable, + false, + ); + assert.equal( + input.properties.find((field) => field.name === "email").nullable, + true, + ); + assert.equal( + input.properties.find((field) => field.name === "page").kind, + "integer", + ); + assert.equal( + input.properties.find((field) => field.name === "page").nullable, + true, + ); +}); + +test("a new contract field flows through to source without a handwritten property inventory", async () => { + const spec = fixture(); + spec.components.schemas.Base.properties.new_field = { + type: "string", + description: "New documented value.", + }; + const outputs = renderModels(await compileContract(spec, binding)); + assert.match([...outputs.values()].join("\n"), /New documented value/); + assert.match([...outputs.values()].join("\n"), /new_field/); +}); + +test("requires a public method for every resource operation", async () => { + const spec = fixture(); + spec.paths["/customers/new"] = { + get: { ...spec.paths["/customers/{id}"].get, operationId: "newOperation" }, + }; + await assert.rejects( + compileContract(spec, binding), + /Every Customers operation/, + ); +}); + +test("fails on unsupported open types instead of generating an untyped model", async () => { + const spec = fixture(); + spec.components.schemas.Base.properties.unknown = {}; + await assert.rejects(compileContract(spec, binding), /Unsupported open type/); +}); + +test("fails on an unsupported union instead of flattening incompatible variants", async () => { + const spec = fixture(); + spec.components.schemas.Base.properties.variant = { + oneOf: [{ type: "string" }, { type: "integer" }], + }; + await assert.rejects(compileContract(spec, binding), /Unsupported union/); +}); diff --git a/scripts/sdk/config.json b/scripts/sdk/config.json new file mode 100644 index 0000000..fb3dc27 --- /dev/null +++ b/scripts/sdk/config.json @@ -0,0 +1,25 @@ +{ + "resource": "customers", + "methods": { + "create": "createCustomer", + "list": "listCustomers", + "retrieve": "getCustomer", + "update": "editCustomer", + "delete": "deleteCustomer", + "validateTaxInfo": "validateCustomerTaxInfo", + "sendEditLinkByEmail": "sendEditLinkByEmail" + }, + "inputs": [ + "CustomerNationalCreateInput", + "CustomerForeignCreateInput", + "CustomerGenericCreateInput", + "CustomerCreateWithEditLinkInput", + "CustomerUpdateInput", + "CustomerUpdateWithEditLinkInput" + ], + "modelNames": { + "CustomerAddress": "Address", + "ValidateCustomerTaxInfoResponse": "TaxInfoValidation", + "TaxInfoValidationErrorsItem": "TaxInfoValidationError" + } +} diff --git a/scripts/sdk/openapi-source.mjs b/scripts/sdk/openapi-source.mjs new file mode 100644 index 0000000..df1780e --- /dev/null +++ b/scripts/sdk/openapi-source.mjs @@ -0,0 +1,81 @@ +import assert from "node:assert/strict"; +import * as yaml from "js-yaml"; + +export async function resolveRevision(repository, ref = "main") { + if (/^[a-f0-9]{40}$/.test(ref)) return ref; + const response = await fetch( + `https://api.github.com/repos/${repository}/commits/${encodeURIComponent(ref)}`, + { + headers: { Accept: "application/vnd.github+json" }, + signal: AbortSignal.timeout(30_000), + }, + ); + assert( + response.ok, + `Could not resolve the public documentation ref: HTTP ${response.status}`, + ); + const { sha } = await response.json(); + assert.match( + sha, + /^[a-f0-9]{40}$/, + "Expected a complete documentation commit SHA.", + ); + return sha; +} + +export async function readSpecification(source) { + assert.match( + source.revision, + /^[a-f0-9]{40}$/, + "Pin a complete documentation commit SHA with pnpm sync:openapi.", + ); + const response = await fetch( + `https://raw.githubusercontent.com/${source.repository}/${source.revision}/${source.path}`, + { signal: AbortSignal.timeout(30_000) }, + ); + assert( + response.ok, + `Could not read the public specification: HTTP ${response.status}`, + ); + const content = Buffer.from(await response.arrayBuffer()); + const spec = yaml.load(content.toString("utf8")); + assert(spec.openapi === "3.1.0", "Expected the public OpenAPI 3.1 contract."); + const presentation = new Set([ + "x-codeSamples", + "x-logo", + "example", + "examples", + "externalDocs", + ]); + // Annotation names can also be real property/parameter/schema names. + const dictionaries = new WeakSet(); + const dictionaryKeys = new Set([ + "properties", + "patternProperties", + "$defs", + "schemas", + "parameters", + "headers", + "paths", + "webhooks", + "responses", + "content", + "securitySchemes", + "requestBodies", + "callbacks", + "links", + ]); + return JSON.parse( + JSON.stringify(spec, function (key, value) { + assert( + key !== "<<", + "YAML merge keys are not supported in the public specification.", + ); + if (value && typeof value === "object" && dictionaryKeys.has(key)) + dictionaries.add(value); + return presentation.has(key) && !dictionaries.has(this) + ? undefined + : value; + }), + ); +} diff --git a/scripts/sdk/render-models.mjs b/scripts/sdk/render-models.mjs new file mode 100644 index 0000000..24905db --- /dev/null +++ b/scripts/sdk/render-models.mjs @@ -0,0 +1,103 @@ +import { pascal, camel } from "./compiler.mjs"; + +export const banner = + "// Generated by pnpm generate:sdk. Do not edit directly.\n"; +export function text(value = "") { + return value + .replace( + /\]\((#[^)]*|\/[^)]*)\)/g, + (_, url) => + `](${url.startsWith("#") ? "https://docs.facturapi.io/api/" : "https://docs.facturapi.io"}${url})`, + ) + .replaceAll("*/", "* /"); +} +export function doc(value, indent = "") { + return `${indent}/// \n${text(value) + .split("\n") + .map( + (line) => + `${indent}/// ${line.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">")}`, + ) + .join("\n")}\n${indent}/// \n`; +} +export function fieldType(field, optional = true) { + const type = + field.kind === "model" + ? field.ref + : field.kind === "array" + ? `${fieldType(field.item, false)}[]` + : { + string: "string", + date: "DateTime", + boolean: "bool", + integer: "int", + number: "double", + }[field.kind]; + return ["boolean", "integer", "number", "date"].includes(field.kind) && + (field.nullable || (optional && !field.required)) + ? type + "?" + : type; +} +export function description(field) { + return [ + field.description || field.name, + field.values && + `Valores: ${field.values.map((value) => JSON.stringify(value)).join(", ")}.`, + field.required ? "Requerido." : "Opcional.", + field.nullable && "Admite null.", + ] + .filter(Boolean) + .join("\n"); +} + +export function renderModels(contract) { + const outputs = new Map(); + for (const model of contract.models) { + const name = + model.name === "CustomerSearchResult" + ? "SearchResult" + : model.name === "TaxInfoValidationError" + ? "TaxInfoError" + : model.name; + let content = + banner + + "using System;\nusing System.Collections.Generic;\nusing Newtonsoft.Json;\n\nnamespace Facturapi\n{\n"; + content += + doc( + model.name === "CustomerSearchResult" + ? "Resultados paginados." + : model.description, + " ", + ) + + ` public class ${name}${model.input ? " : Dictionary" : ""}\n {\n`; + const required = model.input + ? model.properties.filter((field) => field.required) + : []; + if (required.length) { + content += doc(`Crea ${name}.`, " "); + for (const field of required) + content += ` /// ${text(description(field)).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\n", " ")}\n`; + content += ` public ${name}(${required.map((field) => `${fieldType(field)} ${camel(field.name)}`).join(", ")})\n {\n${required.map((field) => ` this[${JSON.stringify(field.name)}] = ${camel(field.name)};`).join("\n")}\n }\n\n`; + } + for (const field of model.properties) { + const type = + model.name === "CustomerSearchResult" && field.name === "data" + ? "List" + : field.kind === "array" && + field.item.ref === "TaxInfoValidationError" + ? "TaxInfoError[]" + : fieldType(field); + content += doc(description(field), " "); + if (model.input) + content += ` [JsonIgnore]\n public ${type} ${pascal(field.name)}\n {\n get => TryGetValue(${JSON.stringify(field.name)}, out var value) ? (${type})value : default;\n set => this[${JSON.stringify(field.name)}] = value;\n }\n\n`; + else + content += ` [JsonProperty(${JSON.stringify(field.name)})]\n public ${type} ${pascal(field.name)} { get; set; }\n\n`; + } + content += " }\n}\n"; + outputs.set( + `Models/${model.input ? "Inputs/" : ""}${name.replace("", "")}.cs`, + content, + ); + } + return outputs; +} diff --git a/scripts/sdk/render-resources.mjs b/scripts/sdk/render-resources.mjs new file mode 100644 index 0000000..6803842 --- /dev/null +++ b/scripts/sdk/render-resources.mjs @@ -0,0 +1,142 @@ +import { pascal } from "./compiler.mjs"; +import { banner, doc, text } from "./render-models.mjs"; + +const convenience = [ + ["createNational", "CustomerNationalCreateInput", "create"], + ["createForeign", "CustomerForeignCreateInput", "create"], + ["createGeneric", "CustomerGenericCreateInput", "create"], + ["createWithEditLink", "CustomerCreateWithEditLinkInput", "create"], + ["updateWithEditLink", "CustomerUpdateWithEditLinkInput", "update"], +]; + +function methodProse(method, parameters) { + return ( + doc( + [method.summary, method.description].filter(Boolean).join("\n\n"), + " ", + ) + + parameters + .map( + ([name, type, description]) => + ` /// ${text(description).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\n", " ")}\n`, + ) + .join("") + + ` /// ${text( + method.responseDescription || "Respuesta de la API.", + ) + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll( + ">", + ">", + )}\n /// \n` + ); +} + +export function renderResources(contract) { + const outputs = new Map(); + let content = + banner + + "using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\nnamespace Facturapi.Wrappers\n{\n" + + doc("Operaciones de clientes.", " ") + + " public class CustomerWrapper : BaseWrapper, ICustomerWrapper\n {\n internal CustomerWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) {}\n\n"; + let interfaces = + banner + + "using System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Facturapi.Wrappers\n{\n" + + doc("Operaciones de clientes para inyección de dependencias.", " ") + + " public interface ICustomerWrapper\n {\n"; + let router = + banner + + "using System;\nusing System.Collections.Generic;\n\nnamespace Facturapi\n{\n internal static partial class Router\n {\n"; + for (const method of contract.methods) { + const id = method.parameters.find((parameter) => parameter.in === "path"); + const hasBody = Boolean(method.requestBody); + const paramsName = method.name === "list" ? "query" : "queryParams"; + const parameters = [ + ...(id ? [["id", "string", id.description]] : []), + ...(hasBody + ? [ + [ + "data", + "Dictionary", + `Datos de la solicitud. ${method.name === "sendEditLinkByEmail" ? "Admite CustomerEditLinkEmailInput." : "Admite los modelos Customer*Input."}`, + ], + ] + : []), + ...(method.query + ? [ + [ + paramsName, + "Dictionary", + `Parámetros de consulta. Admite ${method.query.ref}.`, + ], + ] + : []), + [ + "cancellationToken", + "CancellationToken", + "Permite cancelar la solicitud.", + ], + ]; + const signature = parameters + .map( + ([name, type]) => + `${type} ${name}${name === paramsName ? " = null" : name === "cancellationToken" ? " = default" : ""}`, + ) + .join(", "); + const returnType = + method.name === "sendEditLinkByEmail" + ? "Task" + : `Task<${method.name === "list" ? "SearchResult" : method.response.ref}>`; + const declaration = `${returnType} ${pascal(method.name)}Async(${signature})`; + interfaces += + methodProse(method, parameters) + ` ${declaration};\n\n`; + content += + methodProse(method, parameters) + + ` public async ${declaration}\n {\n`; + const routeName = { + list: "ListCustomers", + retrieve: "RetrieveCustomer", + create: "CreateCustomer", + update: "UpdateCustomer", + delete: "DeleteCustomer", + validateTaxInfo: "ValidateCustomerTaxInfo", + sendEditLinkByEmail: "SendEditLinkByEmail", + }[method.name]; + router += ` public static string ${routeName}(${[...(id ? ["string id"] : []), ...(method.query ? ["Dictionary query = null"] : [])].join(", ")})\n {\n return UriWithQuery($"${method.path.slice(1).replace(/\{[^}]+\}/g, "{Uri.EscapeDataString(id)}")}"${method.query ? ", query" : ""});\n }\n\n`; + const route = `Router.${routeName}(${[...(id ? ["id"] : []), ...(method.query ? [paramsName] : [])].join(", ")})`; + if (hasBody) + content += + ' using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json"))\n'; + content += ` using (var response = await client.${pascal(method.verb)}Async(${route}${hasBody ? ", content" : ""}, cancellationToken).ConfigureAwait(false))\n {\n await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false);\n`; + if (method.name !== "sendEditLinkByEmail") + content += ` return JsonConvert.DeserializeObject<${method.name === "list" ? "SearchResult" : method.response.ref}>(await response.Content.ReadAsStringAsync().ConfigureAwait(false), jsonSettings);\n`; + content += " }\n }\n\n"; + } + for (const [name, model, operation] of convenience) { + const method = contract.methods.find((method) => method.name === operation); + const parameters = [ + ...(operation === "update" ? [["id", "string", "ID del cliente."]] : []), + [ + "data", + model, + contract.models.find((item) => item.name === model).description, + ], + [ + "cancellationToken", + "CancellationToken", + "Permite cancelar la solicitud.", + ], + ]; + const declaration = `Task ${pascal(name)}Async(${parameters.map(([name, type]) => `${type} ${name}${name === "cancellationToken" ? " = default" : ""}`).join(", ")})`; + interfaces += + methodProse(method, parameters) + ` ${declaration};\n\n`; + content += + methodProse(method, parameters) + + ` public ${declaration}\n {\n return ${pascal(operation)}Async(${operation === "update" ? "id, " : ""}data, ${name.endsWith("WithEditLink") ? 'new Dictionary { ["createEditLink"] = true }' : "null"}, cancellationToken);\n }\n\n`; + } + outputs.set("Wrappers/CustomerWrapper.cs", content + " }\n}\n"); + outputs.set("Wrappers/ICustomerWrapper.cs", interfaces + " }\n}\n"); + outputs.set("Router/CustomerRouter.cs", router + " }\n}\n"); + return outputs; +} diff --git a/scripts/sync-openapi.mjs b/scripts/sync-openapi.mjs new file mode 100644 index 0000000..dea7459 --- /dev/null +++ b/scripts/sync-openapi.mjs @@ -0,0 +1,24 @@ +import { readFile, writeFile } from "node:fs/promises"; +import { readSpecification, resolveRevision } from "./sdk/openapi-source.mjs"; + +const root = new URL("../", import.meta.url); +const previous = JSON.parse( + await readFile(new URL("openapi/source.json", root), "utf8"), +); +const source = { + repository: previous.repository, + revision: await resolveRevision( + previous.repository, + process.argv[2] || "main", + ), + path: previous.path, +}; +// Resolve first, then read from that exact commit even if the branch moves. +await readSpecification(source); +await writeFile( + new URL("openapi/source.json", root), + JSON.stringify(source, null, 2) + "\n", +); +console.log( + `Pinned the public specification to ${source.revision}. Run pnpm generate:sdk.`, +); From 0966ed97c9912e51e60696d2b4b592733b305c1b Mon Sep 17 00:00:00 2001 From: javorosas Date: Fri, 13 Nov 2026 20:15:59 +0100 Subject: [PATCH 2/2] feat(sdk)!: generate the complete API v2 client Cover all public API operations with generated wrappers, typed inputs and responses, XML documentation and schema-selected workflow variants. Preserve dictionary calls and add local webhook verification. BREAKING CHANGE: Response models and method results now follow the API v2 contract, including retention models, typed ZIP requests, nullable fields, decimals and collection results. Update manual interfaces and follow the v8 migration guide. --- .gitattributes | 352 ++++- .github/workflows/ci.yml | 2 +- CHANGELOG.md | 14 +- FacturAPIException.cs | 4 +- FacturapiClient.cs | 3 + FacturapiTest/ClientCompatibilityTests.cs | 5 +- FacturapiTest/WrapperBehaviorTests.cs | 225 ++- IFacturapiClient.cs | 4 +- Models/Address.cs | 21 +- Models/ApiEvent.cs | 68 + Models/ApiEventData.JsonConverter.cs | 34 + Models/ApiEventData.cs | 33 + Models/CartaPorteAutotransporte.cs | 52 + Models/CartaPorteCantidadTransporta.cs | 45 + Models/CartaPorteCarroFerroviario.cs | 52 + Models/CartaPorteContenedorFerroviario.cs | 38 + Models/CartaPorteContenedorMaritimo.cs | 66 + ...PorteContenedorMaritimoRemolquesCCPItem.cs | 31 + Models/CartaPorteDataProperties.cs | 108 ++ ...PorteDataPropertiesFiguraTransporteItem.cs | 73 + ...iguraTransporteItemPartesTransporteItem.cs | 24 + ...CartaPorteDataPropertiesUbicacionesItem.cs | 108 ++ Models/CartaPorteDerechosDePaso.cs | 31 + Models/CartaPorteDetalleMercancia.cs | 52 + Models/CartaPorteDocumentacionAduanera.cs | 45 + Models/CartaPorteDomicilio.cs | 87 + Models/CartaPorteGuiaIdentificacion.cs | 38 + Models/CartaPorteIdentificacionVehicular.cs | 45 + Models/CartaPorteMercancia.cs | 311 ++++ Models/CartaPorteMercancias.cs | 94 ++ Models/CartaPorteRemolque.cs | 31 + Models/CartaPorteSeguros.cs | 66 + Models/CartaPorteTransporteAereo.cs | 101 ++ Models/CartaPorteTransporteFerroviario.cs | 59 + Models/CartaPorteTransporteMaritimo.cs | 178 +++ Models/CatalogItem.cs | 38 +- Models/Certificate.cs | 44 +- Models/CheckApiHealthResponse.cs | 24 + Models/ComercioExteriorDataProperties.cs | 123 ++ ...oExteriorDataPropertiesDestinatarioItem.cs | 45 + ...ioExteriorDataPropertiesPropietarioItem.cs | 38 + .../ComercioExteriorDataPropertiesReceptor.cs | 38 + ...omercioExteriorDescripcionesEspecificas.cs | 45 + Models/ComercioExteriorDomicilio.cs | 87 + Models/ComercioExteriorEmisor.cs | 31 + Models/ComercioExteriorMercancia.cs | 66 + Models/ComercioExteriorMercancias.cs | 24 + Models/CompletionStep.cs | 28 +- Models/CreateInvoiceResponse.cs | 366 +++++ Models/CreateToInvoiceFromReceiptsResponse.cs | 403 +++++ ...reateToInvoiceFromReceiptsResponseTaxes.cs | 73 + Models/Customer.cs | 35 +- Models/CustomerEditLinkEmailResult.cs | 5 +- Models/CustomerInfo.cs | 63 + Models/Customization.cs | 59 +- Models/CustomizationDefaultSeries.cs | 52 + Models/CustomizationPdfExtra.cs | 122 ++ Models/CustomizationPdfExtraPayrollOptions.cs | 45 + Models/DomainAvailability.cs | 19 +- Models/Efos.cs | 35 + Models/EfosData.cs | 39 + Models/EfosDetalle.cs | 100 ++ Models/ErrorDetail.cs | 54 + Models/FielCertificate.cs | 47 + Models/GenericError.cs | 70 + Models/Global.cs | 33 +- Models/HidroYPetroComplement.cs | 50 + Models/IeduComplement.cs | 56 + Models/Inputs/CancellationQueryInput.cs | 42 + .../CancellationWithSubstitutionInput.cs | 51 + .../Inputs/CartaPorteAutotransporteInput.cs | 87 + .../CartaPorteCantidadTransportaInput.cs | 74 + .../Inputs/CartaPorteCarroFerroviarioInput.cs | 72 + .../CartaPorteContenedorFerroviarioInput.cs | 50 + .../CartaPorteContenedorMaritimoInput.cs | 94 ++ ...ContenedorMaritimoInputRemolquesCCPItem.cs | 39 + .../Inputs/CartaPorteDataPropertiesInput.cs | 175 +++ ...DataPropertiesInputFiguraTransporteItem.cs | 116 ++ ...iguraTransporteItemPartesTransporteItem.cs | 37 + ...PorteDataPropertiesInputUbicacionesItem.cs | 173 ++ .../Inputs/CartaPorteDerechosDePasoInput.cs | 39 + .../Inputs/CartaPorteDetalleMercanciaInput.cs | 87 + .../CartaPorteDocumentacionAduaneraInput.cs | 61 + Models/Inputs/CartaPorteDomicilioInput.cs | 140 ++ .../CartaPorteGuiaIdentificacionInput.cs | 50 + .../CartaPorteIdentificacionVehicularInput.cs | 76 + Models/Inputs/CartaPorteInput.cs | 48 + Models/Inputs/CartaPorteMercanciaInput.cs | 496 ++++++ Models/Inputs/CartaPorteMercanciasInput.cs | 153 ++ Models/Inputs/CartaPorteRemolqueInput.cs | 39 + Models/Inputs/CartaPorteSegurosInput.cs | 105 ++ .../Inputs/CartaPorteTransporteAereoInput.cs | 149 ++ .../CartaPorteTransporteFerroviarioInput.cs | 83 + .../CartaPorteTransporteMaritimoInput.cs | 281 ++++ ...rteCatalogSearchAirTransportCodesParams.cs | 84 + ...orteCatalogSearchCustomsDocumentsParams.cs | 84 + ...teCatalogSearchHazardousMaterialsParams.cs | 84 + ...orteCatalogSearchMarineContainersParams.cs | 84 + ...eCatalogSearchNavalAuthorizationsParams.cs | 84 + ...aporteCatalogSearchPackagingTypesParams.cs | 84 + ...rtaporteCatalogSearchPortStationsParams.cs | 84 + ...porteCatalogSearchRightsOfPassageParams.cs | 84 + ...rtaporteCatalogSearchTrailerTypesParams.cs | 84 + ...orteCatalogSearchTransportConfigsParams.cs | 84 + .../Inputs/CatalogGetProductCategoryParams.cs | 73 + Models/Inputs/CatalogSearchCountriesParams.cs | 50 + .../Inputs/CatalogSearchInvoiceUsesParams.cs | 50 + Models/Inputs/CatalogSearchProductsParams.cs | 95 ++ .../Inputs/CatalogSearchTaxSystemsParams.cs | 50 + Models/Inputs/CatalogSearchUnitsParams.cs | 84 + Models/Inputs/CatalogSearchZipCodesParams.cs | 95 ++ ...eriorCatalogSearchTariffFractionsParams.cs | 84 + Models/Inputs/ComercioExteriorDataInput.cs | 200 +++ ...mercioExteriorDataInputDestinatarioItem.cs | 61 + ...omercioExteriorDataInputPropietarioItem.cs | 50 + ...ioExteriorDescripcionesEspecificasInput.cs | 70 + .../Inputs/ComercioExteriorDomicilioInput.cs | 142 ++ Models/Inputs/ComercioExteriorEmisorInput.cs | 48 + Models/Inputs/ComercioExteriorInput.cs | 48 + .../Inputs/ComercioExteriorMercanciaInput.cs | 105 ++ .../Inputs/ComercioExteriorMercanciasInput.cs | 37 + .../Inputs/ComercioExteriorReceptorInput.cs | 39 + Models/Inputs/CustomComplementInput.cs | 50 + .../Inputs/CustomerComercioExteriorInput.cs | 28 + Models/Inputs/CustomerCreateCommonInput.cs | 73 + Models/Inputs/CustomerCreateInput.cs | 114 ++ Models/Inputs/CustomerCreateParams.cs | 7 +- .../Inputs/CustomerCreateWithEditLinkInput.cs | 37 +- .../CustomerCreateWithEditLinkInputAddress.cs | 41 +- Models/Inputs/CustomerEditableInput.cs | 101 ++ Models/Inputs/CustomerEditableInputAddress.cs | 124 ++ Models/Inputs/CustomerForeignAddressInput.cs | 43 +- Models/Inputs/CustomerForeignCreateInput.cs | 39 +- Models/Inputs/CustomerGenericCreateInput.cs | 39 +- .../CustomerGenericCreateInputAddress.cs | 41 +- Models/Inputs/CustomerListParams.cs | 29 +- Models/Inputs/CustomerNationalAddressInput.cs | 43 +- Models/Inputs/CustomerNationalCreateInput.cs | 43 +- Models/Inputs/CustomerUpdateInput.cs | 37 +- Models/Inputs/CustomerUpdateInputAddress.cs | 41 +- Models/Inputs/CustomerUpdateParams.cs | 7 +- .../Inputs/CustomerUpdateWithEditLinkInput.cs | 37 +- .../CustomerUpdateWithEditLinkInputAddress.cs | 41 +- Models/Inputs/DateRangeInput.cs | 29 +- Models/Inputs/GlobalInvoiceCommonInput.cs | 148 ++ Models/Inputs/GlobalInvoiceInput.cs | 149 ++ Models/Inputs/HidroYPetroComplementInput.cs | 79 + Models/Inputs/IeduComplementInput.cs | 88 ++ Models/Inputs/InvoiceCommonEditInput.cs | 155 ++ .../Inputs/InvoiceCommonEditInputAddress.cs | 105 ++ Models/Inputs/InvoiceCommonInput.cs | 161 ++ Models/Inputs/InvoiceCommonInputAddress.cs | 105 ++ Models/Inputs/InvoiceComplementInput.cs | 49 + Models/Inputs/InvoiceCreateInput.cs | 367 +++++ Models/Inputs/InvoiceCreateInputGlobal.cs | 71 + Models/Inputs/InvoiceCreateParams.cs | 30 + Models/Inputs/InvoiceDraftCommonInput.cs | 166 ++ Models/Inputs/InvoiceEgresoDraftInput.cs | 275 ++++ Models/Inputs/InvoiceEgresoEditInput.cs | 275 ++++ Models/Inputs/InvoiceEgresoInput.cs | 281 ++++ .../Inputs/InvoiceGetPaymentSummaryParams.cs | 37 + Models/Inputs/InvoiceIngresoDraftInput.cs | 323 ++++ Models/Inputs/InvoiceIngresoEditInput.cs | 323 ++++ Models/Inputs/InvoiceIngresoInput.cs | 330 ++++ Models/Inputs/InvoiceItemEgresoInput.cs | 103 ++ Models/Inputs/InvoiceItemInput.cs | 114 ++ Models/Inputs/InvoiceItemInputThirdParty.cs | 61 + .../Inputs/InvoiceItemProductEgresoInput.cs | 143 ++ Models/Inputs/InvoiceItemProductInput.cs | 160 ++ .../Inputs/InvoiceItemProductTrasladoInput.cs | 82 + Models/Inputs/InvoiceItemThirdPartyInput.cs | 61 + Models/Inputs/InvoiceItemTrasladoInput.cs | 93 ++ .../InvoiceItemTrasladoInputThirdParty.cs | 76 + Models/Inputs/InvoiceListParams.cs | 233 +++ Models/Inputs/InvoiceListZipRequestsParams.cs | 107 ++ Models/Inputs/InvoiceNominaDraftInput.cs | 201 +++ Models/Inputs/InvoiceNominaEditInput.cs | 201 +++ Models/Inputs/InvoiceNominaInput.cs | 205 +++ Models/Inputs/InvoicePagoDraftInput.cs | 212 +++ Models/Inputs/InvoicePagoEditInput.cs | 212 +++ Models/Inputs/InvoicePagoInput.cs | 216 +++ Models/Inputs/InvoiceReceiptInput.cs | 122 ++ Models/Inputs/InvoiceStampDraftParams.cs | 30 + Models/Inputs/InvoiceTrasladoDraftInput.cs | 253 +++ Models/Inputs/InvoiceTrasladoEditInput.cs | 253 +++ Models/Inputs/InvoiceTrasladoInput.cs | 257 +++ Models/Inputs/InvoiceZipRequestCreateInput.cs | 84 + Models/Inputs/InvoiceableCommonEditInput.cs | 87 + .../InvoiceableCommonEditInputPdfOptions.cs | 193 +++ ...CommonEditInputPdfOptionsPayrollOptions.cs | 61 + Models/Inputs/InvoiceableCommonInput.cs | 87 + .../InvoiceableCommonInputPdfOptions.cs | 193 +++ ...ableCommonInputPdfOptionsPayrollOptions.cs | 61 + Models/Inputs/LeyendasFiscalesDataInput.cs | 37 + .../LeyendasFiscalesDataInputLeyendasItem.cs | 59 + Models/Inputs/LeyendasFiscalesInput.cs | 48 + Models/Inputs/LocalTaxInput.cs | 85 + Models/Inputs/NamespaceInput.cs | 65 + Models/Inputs/NominaAccionesInput.cs | 50 + .../NominaCatalogSearchDeductionsParams.cs | 50 + .../NominaCatalogSearchPerceptionsParams.cs | 50 + Models/Inputs/NominaCompensacionInput.cs | 63 + Models/Inputs/NominaComplementDataInput.cs | 158 ++ ...NominaComplementDataInputOtrosPagosItem.cs | 100 ++ .../Inputs/NominaComplementDataNestedInput.cs | 83 + Models/Inputs/NominaComplementInput.cs | 48 + Models/Inputs/NominaDeduccionInput.cs | 74 + Models/Inputs/NominaEmisorInput.cs | 61 + Models/Inputs/NominaEmisorInputEntidadSncf.cs | 53 + Models/Inputs/NominaEntidadSncfInput.cs | 49 + Models/Inputs/NominaHorasExtraInput.cs | 76 + Models/Inputs/NominaIncapacidadInput.cs | 61 + Models/Inputs/NominaJubilacionInput.cs | 83 + Models/Inputs/NominaOtroPagoInput.cs | 100 ++ Models/Inputs/NominaPercepcionInput.cs | 110 ++ Models/Inputs/NominaPercepcionNestedInput.cs | 39 + Models/Inputs/NominaPercepcionesInput.cs | 59 + Models/Inputs/NominaReceptorInput.cs | 245 +++ Models/Inputs/NominaReceptorNestedInput.cs | 28 + Models/Inputs/NominaSeparacionInput.cs | 89 ++ Models/Inputs/NominaSubContratacionInput.cs | 50 + Models/Inputs/OrganizationCertsInput.cs | 65 + ...rganizationCheckDomainIsAvailableParams.cs | 37 + Models/Inputs/OrganizationCreateInput.cs | 37 + .../Inputs/OrganizationCustomizationInput.cs | 62 + .../OrganizationCustomizationInputPdfExtra.cs | 182 +++ ...ustomizationInputPdfExtraPayrollOptions.cs | 61 + Models/Inputs/OrganizationDomainInput.cs | 37 + Models/Inputs/OrganizationFielInput.cs | 65 + .../Inputs/OrganizationInviteCreateInput.cs | 49 + .../Inputs/OrganizationInviteRespondInput.cs | 37 + Models/Inputs/OrganizationLegalInput.cs | 109 ++ .../Inputs/OrganizationLegalInputAddress.cs | 116 ++ Models/Inputs/OrganizationListParams.cs | 95 ++ Models/Inputs/OrganizationLogoInput.cs | 42 + .../OrganizationPermissionRoleCreateInput.cs | 72 + .../OrganizationPermissionRoleUpdateInput.cs | 63 + Models/Inputs/OrganizationReceiptsInput.cs | 93 ++ Models/Inputs/OrganizationSelfInvoiceInput.cs | 52 + .../Inputs/OrganizationSeriesCreateInput.cs | 59 + .../Inputs/OrganizationSeriesDefaultInput.cs | 52 + .../Inputs/OrganizationSeriesUpdateInput.cs | 39 + .../OrganizationUserAccessRoleUpdateInput.cs | 37 + Models/Inputs/PagoComplementInput.cs | 48 + Models/Inputs/PartInput.cs | 105 ++ Models/Inputs/PaymentInput.cs | 198 +++ .../PaymentInputRelatedDocumentsItem.cs | 161 ++ ...ymentInputRelatedDocumentsItemTaxesItem.cs | 87 + Models/Inputs/ProductCreateInput.cs | 159 ++ Models/Inputs/ProductListParams.cs | 95 ++ Models/Inputs/ProductUpdateInput.cs | 146 ++ Models/Inputs/ReceiptAssignCustomerInput.cs | 37 + Models/Inputs/ReceiptInput.cs | 153 ++ Models/Inputs/ReceiptInputAddress.cs | 105 ++ Models/Inputs/ReceiptListParams.cs | 150 ++ Models/Inputs/RelatedDocumentInput.cs | 48 + Models/Inputs/RetentionInput.cs | 191 +++ Models/Inputs/RetentionInputPeriodo.cs | 63 + Models/Inputs/RetentionInputTotales.cs | 85 + .../RetentionInputTotalesImpRetenidosItem.cs | 77 + Models/Inputs/RetentionListParams.cs | 117 ++ Models/Inputs/RetentionUpdateInput.cs | 191 +++ ...ilInput.cs => SendEditLinkByEmailInput.cs} | 11 +- Models/Inputs/SendInvoiceByEmailInput.cs | 28 + Models/Inputs/SendReceiptByEmailInput.cs | 37 + Models/Inputs/SendRetentionByEmailInput.cs | 28 + Models/Inputs/TaxInput.cs | 96 ++ Models/Inputs/ToInvoiceInput.cs | 85 + Models/Inputs/ToInvoicePreviewInput.cs | 60 + Models/Inputs/ToolValidateTaxIdParams.cs | 37 + Models/Inputs/UpdateDraftInvoiceInput.cs | 360 +++++ .../Inputs/ValidateWebhookSignatureInput.cs | 63 + Models/Inputs/WebhookCreateInput.cs | 51 + Models/Inputs/WebhookListParams.cs | 73 + Models/Inputs/WebhookUpdateInput.cs | 51 + Models/Invoice.cs | 395 ++++- Models/InvoiceCancellation.cs | 64 + Models/InvoiceComplementProperties.cs | 32 + Models/InvoiceDraft.cs | 365 +++++ Models/InvoiceFailed.cs | 366 +++++ Models/InvoiceItem.cs | 72 +- Models/InvoiceItemPart.cs | 66 + Models/InvoiceItemThirdParty.cs | 45 + Models/InvoicePending.cs | 366 +++++ Models/InvoiceStamped.cs | 361 +++++ Models/InvoiceZipRequest.cs | 153 ++ Models/Legal.cs | 86 +- Models/LegalAddress.cs | 85 + Models/LeyendasFiscalesData.cs | 24 + Models/LeyendasFiscalesDataLeyendasItem.cs | 38 + Models/LiveApiKey.cs | 35 +- Models/LocalTax.cs | 54 + Models/Namespace.cs | 40 + Models/NominaAccionesProperties.cs | 31 + Models/NominaCompensacionProperties.cs | 38 + Models/NominaComplementDataProperties.cs | 97 ++ ...aComplementDataPropertiesOtrosPagosItem.cs | 63 + Models/NominaDeduccionProperties.cs | 45 + Models/NominaEmisorProperties.cs | 45 + Models/NominaEmisorPropertiesEntidadSncf.cs | 36 + Models/NominaHorasExtraProperties.cs | 45 + Models/NominaIncapacidadProperties.cs | 38 + Models/NominaJubilacionProperties.cs | 52 + Models/NominaPercepcionProperties.cs | 66 + Models/NominaPercepcionesProperties.cs | 38 + Models/NominaReceptorProperties.cs | 150 ++ Models/NominaSeparacionProperties.cs | 52 + Models/NominaSubContratacionProperties.cs | 31 + Models/OkResponse.cs | 24 + Models/OneOf2.cs | 42 + Models/OneOf3.cs | 46 + Models/OneOf4.cs | 50 + Models/OneOf6.cs | 58 + Models/OneOf7.cs | 62 + Models/Organization.cs | 150 +- Models/OrganizationDeleteCerts.cs | 25 + Models/OrganizationInvite.cs | 78 +- Models/OrganizationPendingAddOnsUpdate.cs | 31 + Models/OrganizationPendingPlanUpdate.cs | 31 + Models/OrganizationReceipts.cs | 68 + Models/OrganizationSeriesDeletion.cs | 52 + Models/OrganizationTeamRole.cs | 95 +- Models/OrganizationTeamRoleTemplate.cs | 35 +- Models/OrganizationUserAccess.cs | 86 +- Models/Payment.cs | 133 +- Models/PaymentRelated.cs | 31 + Models/PaymentRelatedDocumentsItem.cs | 104 ++ .../PaymentRelatedDocumentsItemTaxesItem.cs | 54 + Models/PaymentSummary.cs | 89 +- Models/PaymentSummaryTax.cs | 54 + Models/Product.cs | 141 +- Models/ProductCategory.cs | 39 + Models/ProductCategoryDetail.cs | 53 + Models/ProductCategoryList.cs | 24 + Models/ProductInfo.cs | 114 ++ Models/Receipt.cs | 190 ++- Models/ReceiptInvoiceSummaryTax.cs | 72 + Models/RelatedResourceMessage.cs | 61 + Models/Retention.cs | 230 ++- Models/RetentionPeriod.cs | 38 + Models/RetentionRetainedTax.cs | 57 + Models/RetentionTotals.cs | 52 + ...orteNavalAuthorizationsResponseDataItem.cs | 24 + Models/SearchResult.cs | 19 +- Models/SelfInvoiceSettings.cs | 52 +- Models/SendInvoiceByEmailResponse.cs | 24 + Models/SendReceiptByEmailResponse.cs | 24 + Models/SendRetentionByEmailResponse.cs | 24 + Models/SeriesGroup.cs | 32 +- Models/SignedDownloadUrl.cs | 47 + Models/Stamp.cs | 73 +- Models/Tax.cs | 71 +- Models/TaxIdValidation.cs | 50 +- Models/TaxInfoError.cs | 13 +- Models/TaxInfoValidation.cs | 7 +- Models/ToInvoiceSummary.cs | 66 + Models/Webhook.cs | 81 +- Models/ZipCode.cs | 62 + README.md | 74 +- Router/CartaporteCatalogRouter.cs | 58 - Router/CatalogRouter.cs | 17 - Router/CustomerRouter.cs | 45 - Router/HealthRouter.cs | 10 - Router/InvoiceRouter.cs | 99 -- Router/NominaCatalogRouter.cs | 17 - Router/OrganizationRouter.cs | 184 --- Router/ProductRouter.cs | 36 - Router/ReceiptRouter.cs | 61 - Router/RetentionRouter.cs | 56 - Router/Router.cs | 17 +- Router/ToolRouter.cs | 12 - Router/WebhookRouter.cs | 40 - Serialization/OneOfConverter.cs | 45 + Wrappers/BaseWrapper.Requests.cs | 53 + Wrappers/BaseWrapper.cs | 7 +- Wrappers/CartaporteCatalogWrapper.cs | 293 +++- Wrappers/CatalogWrapper.cs | 244 ++- Wrappers/ComercioExteriorCatalogWrapper.cs | 51 + Wrappers/CustomerWrapper.cs | 167 +- Wrappers/ICartaporteCatalogWrapper.cs | 244 ++- Wrappers/ICatalogWrapper.cs | 191 ++- Wrappers/IComercioExteriorCatalogWrapper.cs | 42 + Wrappers/ICustomerWrapper.cs | 100 +- Wrappers/IInvoiceWrapper.cs | 731 ++++++++- Wrappers/INominaCatalogWrapper.cs | 58 +- Wrappers/IOrganizationWrapper.cs | 778 ++++++++- Wrappers/IProductWrapper.cs | 115 +- Wrappers/IReceiptWrapper.cs | 393 ++++- Wrappers/IRetentionWrapper.cs | 289 +++- Wrappers/IToolWrapper.cs | 45 +- Wrappers/IWebhookWrapper.cs | 138 +- Wrappers/InvoiceWrapper.cs | 950 +++++++++-- Wrappers/NominaCatalogWrapper.cs | 72 +- Wrappers/OrganizationWrapper.cs | 1397 +++++++++++------ Wrappers/ProductWrapper.cs | 173 +- Wrappers/ReceiptWrapper.cs | 517 +++++- Wrappers/RetentionWrapper.cs | 385 ++++- Wrappers/ToolWrapper.cs | 85 +- Wrappers/WebhookWrapper.Signatures.cs | 55 + Wrappers/WebhookWrapper.cs | 202 ++- openapi/generated.json | 354 ++++- scripts/generate-sdk.mjs | 4 +- scripts/sdk/compiler.mjs | 632 ++++++-- scripts/sdk/compiler.test.mjs | 129 +- scripts/sdk/config.json | 858 +++++++++- scripts/sdk/render-models.mjs | 282 +++- scripts/sdk/render-resources.mjs | 397 +++-- 407 files changed, 40408 insertions(+), 2753 deletions(-) create mode 100644 Models/ApiEvent.cs create mode 100644 Models/ApiEventData.JsonConverter.cs create mode 100644 Models/ApiEventData.cs create mode 100644 Models/CartaPorteAutotransporte.cs create mode 100644 Models/CartaPorteCantidadTransporta.cs create mode 100644 Models/CartaPorteCarroFerroviario.cs create mode 100644 Models/CartaPorteContenedorFerroviario.cs create mode 100644 Models/CartaPorteContenedorMaritimo.cs create mode 100644 Models/CartaPorteContenedorMaritimoRemolquesCCPItem.cs create mode 100644 Models/CartaPorteDataProperties.cs create mode 100644 Models/CartaPorteDataPropertiesFiguraTransporteItem.cs create mode 100644 Models/CartaPorteDataPropertiesFiguraTransporteItemPartesTransporteItem.cs create mode 100644 Models/CartaPorteDataPropertiesUbicacionesItem.cs create mode 100644 Models/CartaPorteDerechosDePaso.cs create mode 100644 Models/CartaPorteDetalleMercancia.cs create mode 100644 Models/CartaPorteDocumentacionAduanera.cs create mode 100644 Models/CartaPorteDomicilio.cs create mode 100644 Models/CartaPorteGuiaIdentificacion.cs create mode 100644 Models/CartaPorteIdentificacionVehicular.cs create mode 100644 Models/CartaPorteMercancia.cs create mode 100644 Models/CartaPorteMercancias.cs create mode 100644 Models/CartaPorteRemolque.cs create mode 100644 Models/CartaPorteSeguros.cs create mode 100644 Models/CartaPorteTransporteAereo.cs create mode 100644 Models/CartaPorteTransporteFerroviario.cs create mode 100644 Models/CartaPorteTransporteMaritimo.cs create mode 100644 Models/CheckApiHealthResponse.cs create mode 100644 Models/ComercioExteriorDataProperties.cs create mode 100644 Models/ComercioExteriorDataPropertiesDestinatarioItem.cs create mode 100644 Models/ComercioExteriorDataPropertiesPropietarioItem.cs create mode 100644 Models/ComercioExteriorDataPropertiesReceptor.cs create mode 100644 Models/ComercioExteriorDescripcionesEspecificas.cs create mode 100644 Models/ComercioExteriorDomicilio.cs create mode 100644 Models/ComercioExteriorEmisor.cs create mode 100644 Models/ComercioExteriorMercancia.cs create mode 100644 Models/ComercioExteriorMercancias.cs create mode 100644 Models/CreateInvoiceResponse.cs create mode 100644 Models/CreateToInvoiceFromReceiptsResponse.cs create mode 100644 Models/CreateToInvoiceFromReceiptsResponseTaxes.cs create mode 100644 Models/CustomerInfo.cs create mode 100644 Models/CustomizationDefaultSeries.cs create mode 100644 Models/CustomizationPdfExtra.cs create mode 100644 Models/CustomizationPdfExtraPayrollOptions.cs create mode 100644 Models/Efos.cs create mode 100644 Models/EfosData.cs create mode 100644 Models/EfosDetalle.cs create mode 100644 Models/ErrorDetail.cs create mode 100644 Models/FielCertificate.cs create mode 100644 Models/GenericError.cs create mode 100644 Models/HidroYPetroComplement.cs create mode 100644 Models/IeduComplement.cs create mode 100644 Models/Inputs/CancellationQueryInput.cs create mode 100644 Models/Inputs/CancellationWithSubstitutionInput.cs create mode 100644 Models/Inputs/CartaPorteAutotransporteInput.cs create mode 100644 Models/Inputs/CartaPorteCantidadTransportaInput.cs create mode 100644 Models/Inputs/CartaPorteCarroFerroviarioInput.cs create mode 100644 Models/Inputs/CartaPorteContenedorFerroviarioInput.cs create mode 100644 Models/Inputs/CartaPorteContenedorMaritimoInput.cs create mode 100644 Models/Inputs/CartaPorteContenedorMaritimoInputRemolquesCCPItem.cs create mode 100644 Models/Inputs/CartaPorteDataPropertiesInput.cs create mode 100644 Models/Inputs/CartaPorteDataPropertiesInputFiguraTransporteItem.cs create mode 100644 Models/Inputs/CartaPorteDataPropertiesInputFiguraTransporteItemPartesTransporteItem.cs create mode 100644 Models/Inputs/CartaPorteDataPropertiesInputUbicacionesItem.cs create mode 100644 Models/Inputs/CartaPorteDerechosDePasoInput.cs create mode 100644 Models/Inputs/CartaPorteDetalleMercanciaInput.cs create mode 100644 Models/Inputs/CartaPorteDocumentacionAduaneraInput.cs create mode 100644 Models/Inputs/CartaPorteDomicilioInput.cs create mode 100644 Models/Inputs/CartaPorteGuiaIdentificacionInput.cs create mode 100644 Models/Inputs/CartaPorteIdentificacionVehicularInput.cs create mode 100644 Models/Inputs/CartaPorteInput.cs create mode 100644 Models/Inputs/CartaPorteMercanciaInput.cs create mode 100644 Models/Inputs/CartaPorteMercanciasInput.cs create mode 100644 Models/Inputs/CartaPorteRemolqueInput.cs create mode 100644 Models/Inputs/CartaPorteSegurosInput.cs create mode 100644 Models/Inputs/CartaPorteTransporteAereoInput.cs create mode 100644 Models/Inputs/CartaPorteTransporteFerroviarioInput.cs create mode 100644 Models/Inputs/CartaPorteTransporteMaritimoInput.cs create mode 100644 Models/Inputs/CartaporteCatalogSearchAirTransportCodesParams.cs create mode 100644 Models/Inputs/CartaporteCatalogSearchCustomsDocumentsParams.cs create mode 100644 Models/Inputs/CartaporteCatalogSearchHazardousMaterialsParams.cs create mode 100644 Models/Inputs/CartaporteCatalogSearchMarineContainersParams.cs create mode 100644 Models/Inputs/CartaporteCatalogSearchNavalAuthorizationsParams.cs create mode 100644 Models/Inputs/CartaporteCatalogSearchPackagingTypesParams.cs create mode 100644 Models/Inputs/CartaporteCatalogSearchPortStationsParams.cs create mode 100644 Models/Inputs/CartaporteCatalogSearchRightsOfPassageParams.cs create mode 100644 Models/Inputs/CartaporteCatalogSearchTrailerTypesParams.cs create mode 100644 Models/Inputs/CartaporteCatalogSearchTransportConfigsParams.cs create mode 100644 Models/Inputs/CatalogGetProductCategoryParams.cs create mode 100644 Models/Inputs/CatalogSearchCountriesParams.cs create mode 100644 Models/Inputs/CatalogSearchInvoiceUsesParams.cs create mode 100644 Models/Inputs/CatalogSearchProductsParams.cs create mode 100644 Models/Inputs/CatalogSearchTaxSystemsParams.cs create mode 100644 Models/Inputs/CatalogSearchUnitsParams.cs create mode 100644 Models/Inputs/CatalogSearchZipCodesParams.cs create mode 100644 Models/Inputs/ComercioExteriorCatalogSearchTariffFractionsParams.cs create mode 100644 Models/Inputs/ComercioExteriorDataInput.cs create mode 100644 Models/Inputs/ComercioExteriorDataInputDestinatarioItem.cs create mode 100644 Models/Inputs/ComercioExteriorDataInputPropietarioItem.cs create mode 100644 Models/Inputs/ComercioExteriorDescripcionesEspecificasInput.cs create mode 100644 Models/Inputs/ComercioExteriorDomicilioInput.cs create mode 100644 Models/Inputs/ComercioExteriorEmisorInput.cs create mode 100644 Models/Inputs/ComercioExteriorInput.cs create mode 100644 Models/Inputs/ComercioExteriorMercanciaInput.cs create mode 100644 Models/Inputs/ComercioExteriorMercanciasInput.cs create mode 100644 Models/Inputs/ComercioExteriorReceptorInput.cs create mode 100644 Models/Inputs/CustomComplementInput.cs create mode 100644 Models/Inputs/CustomerComercioExteriorInput.cs create mode 100644 Models/Inputs/CustomerCreateCommonInput.cs create mode 100644 Models/Inputs/CustomerCreateInput.cs create mode 100644 Models/Inputs/CustomerEditableInput.cs create mode 100644 Models/Inputs/CustomerEditableInputAddress.cs create mode 100644 Models/Inputs/GlobalInvoiceCommonInput.cs create mode 100644 Models/Inputs/GlobalInvoiceInput.cs create mode 100644 Models/Inputs/HidroYPetroComplementInput.cs create mode 100644 Models/Inputs/IeduComplementInput.cs create mode 100644 Models/Inputs/InvoiceCommonEditInput.cs create mode 100644 Models/Inputs/InvoiceCommonEditInputAddress.cs create mode 100644 Models/Inputs/InvoiceCommonInput.cs create mode 100644 Models/Inputs/InvoiceCommonInputAddress.cs create mode 100644 Models/Inputs/InvoiceComplementInput.cs create mode 100644 Models/Inputs/InvoiceCreateInput.cs create mode 100644 Models/Inputs/InvoiceCreateInputGlobal.cs create mode 100644 Models/Inputs/InvoiceCreateParams.cs create mode 100644 Models/Inputs/InvoiceDraftCommonInput.cs create mode 100644 Models/Inputs/InvoiceEgresoDraftInput.cs create mode 100644 Models/Inputs/InvoiceEgresoEditInput.cs create mode 100644 Models/Inputs/InvoiceEgresoInput.cs create mode 100644 Models/Inputs/InvoiceGetPaymentSummaryParams.cs create mode 100644 Models/Inputs/InvoiceIngresoDraftInput.cs create mode 100644 Models/Inputs/InvoiceIngresoEditInput.cs create mode 100644 Models/Inputs/InvoiceIngresoInput.cs create mode 100644 Models/Inputs/InvoiceItemEgresoInput.cs create mode 100644 Models/Inputs/InvoiceItemInput.cs create mode 100644 Models/Inputs/InvoiceItemInputThirdParty.cs create mode 100644 Models/Inputs/InvoiceItemProductEgresoInput.cs create mode 100644 Models/Inputs/InvoiceItemProductInput.cs create mode 100644 Models/Inputs/InvoiceItemProductTrasladoInput.cs create mode 100644 Models/Inputs/InvoiceItemThirdPartyInput.cs create mode 100644 Models/Inputs/InvoiceItemTrasladoInput.cs create mode 100644 Models/Inputs/InvoiceItemTrasladoInputThirdParty.cs create mode 100644 Models/Inputs/InvoiceListParams.cs create mode 100644 Models/Inputs/InvoiceListZipRequestsParams.cs create mode 100644 Models/Inputs/InvoiceNominaDraftInput.cs create mode 100644 Models/Inputs/InvoiceNominaEditInput.cs create mode 100644 Models/Inputs/InvoiceNominaInput.cs create mode 100644 Models/Inputs/InvoicePagoDraftInput.cs create mode 100644 Models/Inputs/InvoicePagoEditInput.cs create mode 100644 Models/Inputs/InvoicePagoInput.cs create mode 100644 Models/Inputs/InvoiceReceiptInput.cs create mode 100644 Models/Inputs/InvoiceStampDraftParams.cs create mode 100644 Models/Inputs/InvoiceTrasladoDraftInput.cs create mode 100644 Models/Inputs/InvoiceTrasladoEditInput.cs create mode 100644 Models/Inputs/InvoiceTrasladoInput.cs create mode 100644 Models/Inputs/InvoiceZipRequestCreateInput.cs create mode 100644 Models/Inputs/InvoiceableCommonEditInput.cs create mode 100644 Models/Inputs/InvoiceableCommonEditInputPdfOptions.cs create mode 100644 Models/Inputs/InvoiceableCommonEditInputPdfOptionsPayrollOptions.cs create mode 100644 Models/Inputs/InvoiceableCommonInput.cs create mode 100644 Models/Inputs/InvoiceableCommonInputPdfOptions.cs create mode 100644 Models/Inputs/InvoiceableCommonInputPdfOptionsPayrollOptions.cs create mode 100644 Models/Inputs/LeyendasFiscalesDataInput.cs create mode 100644 Models/Inputs/LeyendasFiscalesDataInputLeyendasItem.cs create mode 100644 Models/Inputs/LeyendasFiscalesInput.cs create mode 100644 Models/Inputs/LocalTaxInput.cs create mode 100644 Models/Inputs/NamespaceInput.cs create mode 100644 Models/Inputs/NominaAccionesInput.cs create mode 100644 Models/Inputs/NominaCatalogSearchDeductionsParams.cs create mode 100644 Models/Inputs/NominaCatalogSearchPerceptionsParams.cs create mode 100644 Models/Inputs/NominaCompensacionInput.cs create mode 100644 Models/Inputs/NominaComplementDataInput.cs create mode 100644 Models/Inputs/NominaComplementDataInputOtrosPagosItem.cs create mode 100644 Models/Inputs/NominaComplementDataNestedInput.cs create mode 100644 Models/Inputs/NominaComplementInput.cs create mode 100644 Models/Inputs/NominaDeduccionInput.cs create mode 100644 Models/Inputs/NominaEmisorInput.cs create mode 100644 Models/Inputs/NominaEmisorInputEntidadSncf.cs create mode 100644 Models/Inputs/NominaEntidadSncfInput.cs create mode 100644 Models/Inputs/NominaHorasExtraInput.cs create mode 100644 Models/Inputs/NominaIncapacidadInput.cs create mode 100644 Models/Inputs/NominaJubilacionInput.cs create mode 100644 Models/Inputs/NominaOtroPagoInput.cs create mode 100644 Models/Inputs/NominaPercepcionInput.cs create mode 100644 Models/Inputs/NominaPercepcionNestedInput.cs create mode 100644 Models/Inputs/NominaPercepcionesInput.cs create mode 100644 Models/Inputs/NominaReceptorInput.cs create mode 100644 Models/Inputs/NominaReceptorNestedInput.cs create mode 100644 Models/Inputs/NominaSeparacionInput.cs create mode 100644 Models/Inputs/NominaSubContratacionInput.cs create mode 100644 Models/Inputs/OrganizationCertsInput.cs create mode 100644 Models/Inputs/OrganizationCheckDomainIsAvailableParams.cs create mode 100644 Models/Inputs/OrganizationCreateInput.cs create mode 100644 Models/Inputs/OrganizationCustomizationInput.cs create mode 100644 Models/Inputs/OrganizationCustomizationInputPdfExtra.cs create mode 100644 Models/Inputs/OrganizationCustomizationInputPdfExtraPayrollOptions.cs create mode 100644 Models/Inputs/OrganizationDomainInput.cs create mode 100644 Models/Inputs/OrganizationFielInput.cs create mode 100644 Models/Inputs/OrganizationInviteCreateInput.cs create mode 100644 Models/Inputs/OrganizationInviteRespondInput.cs create mode 100644 Models/Inputs/OrganizationLegalInput.cs create mode 100644 Models/Inputs/OrganizationLegalInputAddress.cs create mode 100644 Models/Inputs/OrganizationListParams.cs create mode 100644 Models/Inputs/OrganizationLogoInput.cs create mode 100644 Models/Inputs/OrganizationPermissionRoleCreateInput.cs create mode 100644 Models/Inputs/OrganizationPermissionRoleUpdateInput.cs create mode 100644 Models/Inputs/OrganizationReceiptsInput.cs create mode 100644 Models/Inputs/OrganizationSelfInvoiceInput.cs create mode 100644 Models/Inputs/OrganizationSeriesCreateInput.cs create mode 100644 Models/Inputs/OrganizationSeriesDefaultInput.cs create mode 100644 Models/Inputs/OrganizationSeriesUpdateInput.cs create mode 100644 Models/Inputs/OrganizationUserAccessRoleUpdateInput.cs create mode 100644 Models/Inputs/PagoComplementInput.cs create mode 100644 Models/Inputs/PartInput.cs create mode 100644 Models/Inputs/PaymentInput.cs create mode 100644 Models/Inputs/PaymentInputRelatedDocumentsItem.cs create mode 100644 Models/Inputs/PaymentInputRelatedDocumentsItemTaxesItem.cs create mode 100644 Models/Inputs/ProductCreateInput.cs create mode 100644 Models/Inputs/ProductListParams.cs create mode 100644 Models/Inputs/ProductUpdateInput.cs create mode 100644 Models/Inputs/ReceiptAssignCustomerInput.cs create mode 100644 Models/Inputs/ReceiptInput.cs create mode 100644 Models/Inputs/ReceiptInputAddress.cs create mode 100644 Models/Inputs/ReceiptListParams.cs create mode 100644 Models/Inputs/RelatedDocumentInput.cs create mode 100644 Models/Inputs/RetentionInput.cs create mode 100644 Models/Inputs/RetentionInputPeriodo.cs create mode 100644 Models/Inputs/RetentionInputTotales.cs create mode 100644 Models/Inputs/RetentionInputTotalesImpRetenidosItem.cs create mode 100644 Models/Inputs/RetentionListParams.cs create mode 100644 Models/Inputs/RetentionUpdateInput.cs rename Models/Inputs/{CustomerEditLinkEmailInput.cs => SendEditLinkByEmailInput.cs} (71%) create mode 100644 Models/Inputs/SendInvoiceByEmailInput.cs create mode 100644 Models/Inputs/SendReceiptByEmailInput.cs create mode 100644 Models/Inputs/SendRetentionByEmailInput.cs create mode 100644 Models/Inputs/TaxInput.cs create mode 100644 Models/Inputs/ToInvoiceInput.cs create mode 100644 Models/Inputs/ToInvoicePreviewInput.cs create mode 100644 Models/Inputs/ToolValidateTaxIdParams.cs create mode 100644 Models/Inputs/UpdateDraftInvoiceInput.cs create mode 100644 Models/Inputs/ValidateWebhookSignatureInput.cs create mode 100644 Models/Inputs/WebhookCreateInput.cs create mode 100644 Models/Inputs/WebhookListParams.cs create mode 100644 Models/Inputs/WebhookUpdateInput.cs create mode 100644 Models/InvoiceCancellation.cs create mode 100644 Models/InvoiceComplementProperties.cs create mode 100644 Models/InvoiceDraft.cs create mode 100644 Models/InvoiceFailed.cs create mode 100644 Models/InvoiceItemPart.cs create mode 100644 Models/InvoiceItemThirdParty.cs create mode 100644 Models/InvoicePending.cs create mode 100644 Models/InvoiceStamped.cs create mode 100644 Models/InvoiceZipRequest.cs create mode 100644 Models/LegalAddress.cs create mode 100644 Models/LeyendasFiscalesData.cs create mode 100644 Models/LeyendasFiscalesDataLeyendasItem.cs create mode 100644 Models/LocalTax.cs create mode 100644 Models/Namespace.cs create mode 100644 Models/NominaAccionesProperties.cs create mode 100644 Models/NominaCompensacionProperties.cs create mode 100644 Models/NominaComplementDataProperties.cs create mode 100644 Models/NominaComplementDataPropertiesOtrosPagosItem.cs create mode 100644 Models/NominaDeduccionProperties.cs create mode 100644 Models/NominaEmisorProperties.cs create mode 100644 Models/NominaEmisorPropertiesEntidadSncf.cs create mode 100644 Models/NominaHorasExtraProperties.cs create mode 100644 Models/NominaIncapacidadProperties.cs create mode 100644 Models/NominaJubilacionProperties.cs create mode 100644 Models/NominaPercepcionProperties.cs create mode 100644 Models/NominaPercepcionesProperties.cs create mode 100644 Models/NominaReceptorProperties.cs create mode 100644 Models/NominaSeparacionProperties.cs create mode 100644 Models/NominaSubContratacionProperties.cs create mode 100644 Models/OkResponse.cs create mode 100644 Models/OneOf2.cs create mode 100644 Models/OneOf3.cs create mode 100644 Models/OneOf4.cs create mode 100644 Models/OneOf6.cs create mode 100644 Models/OneOf7.cs create mode 100644 Models/OrganizationDeleteCerts.cs create mode 100644 Models/OrganizationPendingAddOnsUpdate.cs create mode 100644 Models/OrganizationPendingPlanUpdate.cs create mode 100644 Models/OrganizationReceipts.cs create mode 100644 Models/OrganizationSeriesDeletion.cs create mode 100644 Models/PaymentRelated.cs create mode 100644 Models/PaymentRelatedDocumentsItem.cs create mode 100644 Models/PaymentRelatedDocumentsItemTaxesItem.cs create mode 100644 Models/PaymentSummaryTax.cs create mode 100644 Models/ProductCategory.cs create mode 100644 Models/ProductCategoryDetail.cs create mode 100644 Models/ProductCategoryList.cs create mode 100644 Models/ProductInfo.cs create mode 100644 Models/ReceiptInvoiceSummaryTax.cs create mode 100644 Models/RelatedResourceMessage.cs create mode 100644 Models/RetentionPeriod.cs create mode 100644 Models/RetentionRetainedTax.cs create mode 100644 Models/RetentionTotals.cs create mode 100644 Models/SearchCartaPorteNavalAuthorizationsResponseDataItem.cs create mode 100644 Models/SendInvoiceByEmailResponse.cs create mode 100644 Models/SendReceiptByEmailResponse.cs create mode 100644 Models/SendRetentionByEmailResponse.cs create mode 100644 Models/SignedDownloadUrl.cs create mode 100644 Models/ToInvoiceSummary.cs create mode 100644 Models/ZipCode.cs delete mode 100644 Router/CartaporteCatalogRouter.cs delete mode 100644 Router/CatalogRouter.cs delete mode 100644 Router/CustomerRouter.cs delete mode 100644 Router/HealthRouter.cs delete mode 100644 Router/InvoiceRouter.cs delete mode 100644 Router/NominaCatalogRouter.cs delete mode 100644 Router/OrganizationRouter.cs delete mode 100644 Router/ProductRouter.cs delete mode 100644 Router/ReceiptRouter.cs delete mode 100644 Router/RetentionRouter.cs delete mode 100644 Router/ToolRouter.cs delete mode 100644 Router/WebhookRouter.cs create mode 100644 Serialization/OneOfConverter.cs create mode 100644 Wrappers/BaseWrapper.Requests.cs create mode 100644 Wrappers/ComercioExteriorCatalogWrapper.cs create mode 100644 Wrappers/IComercioExteriorCatalogWrapper.cs create mode 100644 Wrappers/WebhookWrapper.Signatures.cs diff --git a/.gitattributes b/.gitattributes index 2820e21..dff5e68 100644 --- a/.gitattributes +++ b/.gitattributes @@ -64,12 +64,128 @@ # BEGIN generated SDK Models/Address.cs linguist-generated=true +Models/ApiEvent.cs linguist-generated=true +Models/ApiEventData.JsonConverter.cs linguist-generated=true +Models/ApiEventData.cs linguist-generated=true +Models/CartaPorteAutotransporte.cs linguist-generated=true +Models/CartaPorteCantidadTransporta.cs linguist-generated=true +Models/CartaPorteCarroFerroviario.cs linguist-generated=true +Models/CartaPorteContenedorFerroviario.cs linguist-generated=true +Models/CartaPorteContenedorMaritimo.cs linguist-generated=true +Models/CartaPorteContenedorMaritimoRemolquesCCPItem.cs linguist-generated=true +Models/CartaPorteDataProperties.cs linguist-generated=true +Models/CartaPorteDataPropertiesFiguraTransporteItem.cs linguist-generated=true +Models/CartaPorteDataPropertiesFiguraTransporteItemPartesTransporteItem.cs linguist-generated=true +Models/CartaPorteDataPropertiesUbicacionesItem.cs linguist-generated=true +Models/CartaPorteDerechosDePaso.cs linguist-generated=true +Models/CartaPorteDetalleMercancia.cs linguist-generated=true +Models/CartaPorteDocumentacionAduanera.cs linguist-generated=true +Models/CartaPorteDomicilio.cs linguist-generated=true +Models/CartaPorteGuiaIdentificacion.cs linguist-generated=true +Models/CartaPorteIdentificacionVehicular.cs linguist-generated=true +Models/CartaPorteMercancia.cs linguist-generated=true +Models/CartaPorteMercancias.cs linguist-generated=true +Models/CartaPorteRemolque.cs linguist-generated=true +Models/CartaPorteSeguros.cs linguist-generated=true +Models/CartaPorteTransporteAereo.cs linguist-generated=true +Models/CartaPorteTransporteFerroviario.cs linguist-generated=true +Models/CartaPorteTransporteMaritimo.cs linguist-generated=true +Models/CatalogItem.cs linguist-generated=true +Models/Certificate.cs linguist-generated=true +Models/CheckApiHealthResponse.cs linguist-generated=true +Models/ComercioExteriorDataProperties.cs linguist-generated=true +Models/ComercioExteriorDataPropertiesDestinatarioItem.cs linguist-generated=true +Models/ComercioExteriorDataPropertiesPropietarioItem.cs linguist-generated=true +Models/ComercioExteriorDataPropertiesReceptor.cs linguist-generated=true +Models/ComercioExteriorDescripcionesEspecificas.cs linguist-generated=true +Models/ComercioExteriorDomicilio.cs linguist-generated=true +Models/ComercioExteriorEmisor.cs linguist-generated=true +Models/ComercioExteriorMercancia.cs linguist-generated=true +Models/ComercioExteriorMercancias.cs linguist-generated=true +Models/CompletionStep.cs linguist-generated=true +Models/CreateInvoiceResponse.cs linguist-generated=true +Models/CreateToInvoiceFromReceiptsResponse.cs linguist-generated=true +Models/CreateToInvoiceFromReceiptsResponseTaxes.cs linguist-generated=true Models/Customer.cs linguist-generated=true Models/CustomerEditLinkEmailResult.cs linguist-generated=true +Models/CustomerInfo.cs linguist-generated=true +Models/Customization.cs linguist-generated=true +Models/CustomizationDefaultSeries.cs linguist-generated=true +Models/CustomizationPdfExtra.cs linguist-generated=true +Models/CustomizationPdfExtraPayrollOptions.cs linguist-generated=true +Models/DomainAvailability.cs linguist-generated=true +Models/Efos.cs linguist-generated=true +Models/EfosData.cs linguist-generated=true +Models/EfosDetalle.cs linguist-generated=true +Models/ErrorDetail.cs linguist-generated=true +Models/FielCertificate.cs linguist-generated=true +Models/GenericError.cs linguist-generated=true +Models/Global.cs linguist-generated=true +Models/HidroYPetroComplement.cs linguist-generated=true +Models/IeduComplement.cs linguist-generated=true +Models/Inputs/CancellationQueryInput.cs linguist-generated=true +Models/Inputs/CancellationWithSubstitutionInput.cs linguist-generated=true +Models/Inputs/CartaPorteAutotransporteInput.cs linguist-generated=true +Models/Inputs/CartaPorteCantidadTransportaInput.cs linguist-generated=true +Models/Inputs/CartaPorteCarroFerroviarioInput.cs linguist-generated=true +Models/Inputs/CartaPorteContenedorFerroviarioInput.cs linguist-generated=true +Models/Inputs/CartaPorteContenedorMaritimoInput.cs linguist-generated=true +Models/Inputs/CartaPorteContenedorMaritimoInputRemolquesCCPItem.cs linguist-generated=true +Models/Inputs/CartaPorteDataPropertiesInput.cs linguist-generated=true +Models/Inputs/CartaPorteDataPropertiesInputFiguraTransporteItem.cs linguist-generated=true +Models/Inputs/CartaPorteDataPropertiesInputFiguraTransporteItemPartesTransporteItem.cs linguist-generated=true +Models/Inputs/CartaPorteDataPropertiesInputUbicacionesItem.cs linguist-generated=true +Models/Inputs/CartaPorteDerechosDePasoInput.cs linguist-generated=true +Models/Inputs/CartaPorteDetalleMercanciaInput.cs linguist-generated=true +Models/Inputs/CartaPorteDocumentacionAduaneraInput.cs linguist-generated=true +Models/Inputs/CartaPorteDomicilioInput.cs linguist-generated=true +Models/Inputs/CartaPorteGuiaIdentificacionInput.cs linguist-generated=true +Models/Inputs/CartaPorteIdentificacionVehicularInput.cs linguist-generated=true +Models/Inputs/CartaPorteInput.cs linguist-generated=true +Models/Inputs/CartaPorteMercanciaInput.cs linguist-generated=true +Models/Inputs/CartaPorteMercanciasInput.cs linguist-generated=true +Models/Inputs/CartaPorteRemolqueInput.cs linguist-generated=true +Models/Inputs/CartaPorteSegurosInput.cs linguist-generated=true +Models/Inputs/CartaPorteTransporteAereoInput.cs linguist-generated=true +Models/Inputs/CartaPorteTransporteFerroviarioInput.cs linguist-generated=true +Models/Inputs/CartaPorteTransporteMaritimoInput.cs linguist-generated=true +Models/Inputs/CartaporteCatalogSearchAirTransportCodesParams.cs linguist-generated=true +Models/Inputs/CartaporteCatalogSearchCustomsDocumentsParams.cs linguist-generated=true +Models/Inputs/CartaporteCatalogSearchHazardousMaterialsParams.cs linguist-generated=true +Models/Inputs/CartaporteCatalogSearchMarineContainersParams.cs linguist-generated=true +Models/Inputs/CartaporteCatalogSearchNavalAuthorizationsParams.cs linguist-generated=true +Models/Inputs/CartaporteCatalogSearchPackagingTypesParams.cs linguist-generated=true +Models/Inputs/CartaporteCatalogSearchPortStationsParams.cs linguist-generated=true +Models/Inputs/CartaporteCatalogSearchRightsOfPassageParams.cs linguist-generated=true +Models/Inputs/CartaporteCatalogSearchTrailerTypesParams.cs linguist-generated=true +Models/Inputs/CartaporteCatalogSearchTransportConfigsParams.cs linguist-generated=true +Models/Inputs/CatalogGetProductCategoryParams.cs linguist-generated=true +Models/Inputs/CatalogSearchCountriesParams.cs linguist-generated=true +Models/Inputs/CatalogSearchInvoiceUsesParams.cs linguist-generated=true +Models/Inputs/CatalogSearchProductsParams.cs linguist-generated=true +Models/Inputs/CatalogSearchTaxSystemsParams.cs linguist-generated=true +Models/Inputs/CatalogSearchUnitsParams.cs linguist-generated=true +Models/Inputs/CatalogSearchZipCodesParams.cs linguist-generated=true +Models/Inputs/ComercioExteriorCatalogSearchTariffFractionsParams.cs linguist-generated=true +Models/Inputs/ComercioExteriorDataInput.cs linguist-generated=true +Models/Inputs/ComercioExteriorDataInputDestinatarioItem.cs linguist-generated=true +Models/Inputs/ComercioExteriorDataInputPropietarioItem.cs linguist-generated=true +Models/Inputs/ComercioExteriorDescripcionesEspecificasInput.cs linguist-generated=true +Models/Inputs/ComercioExteriorDomicilioInput.cs linguist-generated=true +Models/Inputs/ComercioExteriorEmisorInput.cs linguist-generated=true +Models/Inputs/ComercioExteriorInput.cs linguist-generated=true +Models/Inputs/ComercioExteriorMercanciaInput.cs linguist-generated=true +Models/Inputs/ComercioExteriorMercanciasInput.cs linguist-generated=true +Models/Inputs/ComercioExteriorReceptorInput.cs linguist-generated=true +Models/Inputs/CustomComplementInput.cs linguist-generated=true +Models/Inputs/CustomerComercioExteriorInput.cs linguist-generated=true +Models/Inputs/CustomerCreateCommonInput.cs linguist-generated=true +Models/Inputs/CustomerCreateInput.cs linguist-generated=true Models/Inputs/CustomerCreateParams.cs linguist-generated=true Models/Inputs/CustomerCreateWithEditLinkInput.cs linguist-generated=true Models/Inputs/CustomerCreateWithEditLinkInputAddress.cs linguist-generated=true -Models/Inputs/CustomerEditLinkEmailInput.cs linguist-generated=true +Models/Inputs/CustomerEditableInput.cs linguist-generated=true +Models/Inputs/CustomerEditableInputAddress.cs linguist-generated=true Models/Inputs/CustomerForeignAddressInput.cs linguist-generated=true Models/Inputs/CustomerForeignCreateInput.cs linguist-generated=true Models/Inputs/CustomerGenericCreateInput.cs linguist-generated=true @@ -83,10 +199,242 @@ Models/Inputs/CustomerUpdateParams.cs linguist-generated=true Models/Inputs/CustomerUpdateWithEditLinkInput.cs linguist-generated=true Models/Inputs/CustomerUpdateWithEditLinkInputAddress.cs linguist-generated=true Models/Inputs/DateRangeInput.cs linguist-generated=true +Models/Inputs/GlobalInvoiceCommonInput.cs linguist-generated=true +Models/Inputs/GlobalInvoiceInput.cs linguist-generated=true +Models/Inputs/HidroYPetroComplementInput.cs linguist-generated=true +Models/Inputs/IeduComplementInput.cs linguist-generated=true +Models/Inputs/InvoiceCommonEditInput.cs linguist-generated=true +Models/Inputs/InvoiceCommonEditInputAddress.cs linguist-generated=true +Models/Inputs/InvoiceCommonInput.cs linguist-generated=true +Models/Inputs/InvoiceCommonInputAddress.cs linguist-generated=true +Models/Inputs/InvoiceComplementInput.cs linguist-generated=true +Models/Inputs/InvoiceCreateInput.cs linguist-generated=true +Models/Inputs/InvoiceCreateInputGlobal.cs linguist-generated=true +Models/Inputs/InvoiceCreateParams.cs linguist-generated=true +Models/Inputs/InvoiceDraftCommonInput.cs linguist-generated=true +Models/Inputs/InvoiceEgresoDraftInput.cs linguist-generated=true +Models/Inputs/InvoiceEgresoEditInput.cs linguist-generated=true +Models/Inputs/InvoiceEgresoInput.cs linguist-generated=true +Models/Inputs/InvoiceGetPaymentSummaryParams.cs linguist-generated=true +Models/Inputs/InvoiceIngresoDraftInput.cs linguist-generated=true +Models/Inputs/InvoiceIngresoEditInput.cs linguist-generated=true +Models/Inputs/InvoiceIngresoInput.cs linguist-generated=true +Models/Inputs/InvoiceItemEgresoInput.cs linguist-generated=true +Models/Inputs/InvoiceItemInput.cs linguist-generated=true +Models/Inputs/InvoiceItemInputThirdParty.cs linguist-generated=true +Models/Inputs/InvoiceItemProductEgresoInput.cs linguist-generated=true +Models/Inputs/InvoiceItemProductInput.cs linguist-generated=true +Models/Inputs/InvoiceItemProductTrasladoInput.cs linguist-generated=true +Models/Inputs/InvoiceItemThirdPartyInput.cs linguist-generated=true +Models/Inputs/InvoiceItemTrasladoInput.cs linguist-generated=true +Models/Inputs/InvoiceItemTrasladoInputThirdParty.cs linguist-generated=true +Models/Inputs/InvoiceListParams.cs linguist-generated=true +Models/Inputs/InvoiceListZipRequestsParams.cs linguist-generated=true +Models/Inputs/InvoiceNominaDraftInput.cs linguist-generated=true +Models/Inputs/InvoiceNominaEditInput.cs linguist-generated=true +Models/Inputs/InvoiceNominaInput.cs linguist-generated=true +Models/Inputs/InvoicePagoDraftInput.cs linguist-generated=true +Models/Inputs/InvoicePagoEditInput.cs linguist-generated=true +Models/Inputs/InvoicePagoInput.cs linguist-generated=true +Models/Inputs/InvoiceReceiptInput.cs linguist-generated=true +Models/Inputs/InvoiceStampDraftParams.cs linguist-generated=true +Models/Inputs/InvoiceTrasladoDraftInput.cs linguist-generated=true +Models/Inputs/InvoiceTrasladoEditInput.cs linguist-generated=true +Models/Inputs/InvoiceTrasladoInput.cs linguist-generated=true +Models/Inputs/InvoiceZipRequestCreateInput.cs linguist-generated=true +Models/Inputs/InvoiceableCommonEditInput.cs linguist-generated=true +Models/Inputs/InvoiceableCommonEditInputPdfOptions.cs linguist-generated=true +Models/Inputs/InvoiceableCommonEditInputPdfOptionsPayrollOptions.cs linguist-generated=true +Models/Inputs/InvoiceableCommonInput.cs linguist-generated=true +Models/Inputs/InvoiceableCommonInputPdfOptions.cs linguist-generated=true +Models/Inputs/InvoiceableCommonInputPdfOptionsPayrollOptions.cs linguist-generated=true +Models/Inputs/LeyendasFiscalesDataInput.cs linguist-generated=true +Models/Inputs/LeyendasFiscalesDataInputLeyendasItem.cs linguist-generated=true +Models/Inputs/LeyendasFiscalesInput.cs linguist-generated=true +Models/Inputs/LocalTaxInput.cs linguist-generated=true +Models/Inputs/NamespaceInput.cs linguist-generated=true +Models/Inputs/NominaAccionesInput.cs linguist-generated=true +Models/Inputs/NominaCatalogSearchDeductionsParams.cs linguist-generated=true +Models/Inputs/NominaCatalogSearchPerceptionsParams.cs linguist-generated=true +Models/Inputs/NominaCompensacionInput.cs linguist-generated=true +Models/Inputs/NominaComplementDataInput.cs linguist-generated=true +Models/Inputs/NominaComplementDataInputOtrosPagosItem.cs linguist-generated=true +Models/Inputs/NominaComplementDataNestedInput.cs linguist-generated=true +Models/Inputs/NominaComplementInput.cs linguist-generated=true +Models/Inputs/NominaDeduccionInput.cs linguist-generated=true +Models/Inputs/NominaEmisorInput.cs linguist-generated=true +Models/Inputs/NominaEmisorInputEntidadSncf.cs linguist-generated=true +Models/Inputs/NominaEntidadSncfInput.cs linguist-generated=true +Models/Inputs/NominaHorasExtraInput.cs linguist-generated=true +Models/Inputs/NominaIncapacidadInput.cs linguist-generated=true +Models/Inputs/NominaJubilacionInput.cs linguist-generated=true +Models/Inputs/NominaOtroPagoInput.cs linguist-generated=true +Models/Inputs/NominaPercepcionInput.cs linguist-generated=true +Models/Inputs/NominaPercepcionNestedInput.cs linguist-generated=true +Models/Inputs/NominaPercepcionesInput.cs linguist-generated=true +Models/Inputs/NominaReceptorInput.cs linguist-generated=true +Models/Inputs/NominaReceptorNestedInput.cs linguist-generated=true +Models/Inputs/NominaSeparacionInput.cs linguist-generated=true +Models/Inputs/NominaSubContratacionInput.cs linguist-generated=true +Models/Inputs/OrganizationCertsInput.cs linguist-generated=true +Models/Inputs/OrganizationCheckDomainIsAvailableParams.cs linguist-generated=true +Models/Inputs/OrganizationCreateInput.cs linguist-generated=true +Models/Inputs/OrganizationCustomizationInput.cs linguist-generated=true +Models/Inputs/OrganizationCustomizationInputPdfExtra.cs linguist-generated=true +Models/Inputs/OrganizationCustomizationInputPdfExtraPayrollOptions.cs linguist-generated=true +Models/Inputs/OrganizationDomainInput.cs linguist-generated=true +Models/Inputs/OrganizationFielInput.cs linguist-generated=true +Models/Inputs/OrganizationInviteCreateInput.cs linguist-generated=true +Models/Inputs/OrganizationInviteRespondInput.cs linguist-generated=true +Models/Inputs/OrganizationLegalInput.cs linguist-generated=true +Models/Inputs/OrganizationLegalInputAddress.cs linguist-generated=true +Models/Inputs/OrganizationListParams.cs linguist-generated=true +Models/Inputs/OrganizationLogoInput.cs linguist-generated=true +Models/Inputs/OrganizationPermissionRoleCreateInput.cs linguist-generated=true +Models/Inputs/OrganizationPermissionRoleUpdateInput.cs linguist-generated=true +Models/Inputs/OrganizationReceiptsInput.cs linguist-generated=true +Models/Inputs/OrganizationSelfInvoiceInput.cs linguist-generated=true +Models/Inputs/OrganizationSeriesCreateInput.cs linguist-generated=true +Models/Inputs/OrganizationSeriesDefaultInput.cs linguist-generated=true +Models/Inputs/OrganizationSeriesUpdateInput.cs linguist-generated=true +Models/Inputs/OrganizationUserAccessRoleUpdateInput.cs linguist-generated=true +Models/Inputs/PagoComplementInput.cs linguist-generated=true +Models/Inputs/PartInput.cs linguist-generated=true +Models/Inputs/PaymentInput.cs linguist-generated=true +Models/Inputs/PaymentInputRelatedDocumentsItem.cs linguist-generated=true +Models/Inputs/PaymentInputRelatedDocumentsItemTaxesItem.cs linguist-generated=true +Models/Inputs/ProductCreateInput.cs linguist-generated=true +Models/Inputs/ProductListParams.cs linguist-generated=true +Models/Inputs/ProductUpdateInput.cs linguist-generated=true +Models/Inputs/ReceiptAssignCustomerInput.cs linguist-generated=true +Models/Inputs/ReceiptInput.cs linguist-generated=true +Models/Inputs/ReceiptInputAddress.cs linguist-generated=true +Models/Inputs/ReceiptListParams.cs linguist-generated=true +Models/Inputs/RelatedDocumentInput.cs linguist-generated=true +Models/Inputs/RetentionInput.cs linguist-generated=true +Models/Inputs/RetentionInputPeriodo.cs linguist-generated=true +Models/Inputs/RetentionInputTotales.cs linguist-generated=true +Models/Inputs/RetentionInputTotalesImpRetenidosItem.cs linguist-generated=true +Models/Inputs/RetentionListParams.cs linguist-generated=true +Models/Inputs/RetentionUpdateInput.cs linguist-generated=true +Models/Inputs/SendEditLinkByEmailInput.cs linguist-generated=true +Models/Inputs/SendInvoiceByEmailInput.cs linguist-generated=true +Models/Inputs/SendReceiptByEmailInput.cs linguist-generated=true +Models/Inputs/SendRetentionByEmailInput.cs linguist-generated=true +Models/Inputs/TaxInput.cs linguist-generated=true +Models/Inputs/ToInvoiceInput.cs linguist-generated=true +Models/Inputs/ToInvoicePreviewInput.cs linguist-generated=true +Models/Inputs/ToolValidateTaxIdParams.cs linguist-generated=true +Models/Inputs/UpdateDraftInvoiceInput.cs linguist-generated=true +Models/Inputs/ValidateWebhookSignatureInput.cs linguist-generated=true +Models/Inputs/WebhookCreateInput.cs linguist-generated=true +Models/Inputs/WebhookListParams.cs linguist-generated=true +Models/Inputs/WebhookUpdateInput.cs linguist-generated=true +Models/Invoice.cs linguist-generated=true +Models/InvoiceCancellation.cs linguist-generated=true +Models/InvoiceComplementProperties.cs linguist-generated=true +Models/InvoiceDraft.cs linguist-generated=true +Models/InvoiceFailed.cs linguist-generated=true +Models/InvoiceItem.cs linguist-generated=true +Models/InvoiceItemPart.cs linguist-generated=true +Models/InvoiceItemThirdParty.cs linguist-generated=true +Models/InvoicePending.cs linguist-generated=true +Models/InvoiceStamped.cs linguist-generated=true +Models/InvoiceZipRequest.cs linguist-generated=true +Models/Legal.cs linguist-generated=true +Models/LegalAddress.cs linguist-generated=true +Models/LeyendasFiscalesData.cs linguist-generated=true +Models/LeyendasFiscalesDataLeyendasItem.cs linguist-generated=true +Models/LiveApiKey.cs linguist-generated=true +Models/LocalTax.cs linguist-generated=true +Models/Namespace.cs linguist-generated=true +Models/NominaAccionesProperties.cs linguist-generated=true +Models/NominaCompensacionProperties.cs linguist-generated=true +Models/NominaComplementDataProperties.cs linguist-generated=true +Models/NominaComplementDataPropertiesOtrosPagosItem.cs linguist-generated=true +Models/NominaDeduccionProperties.cs linguist-generated=true +Models/NominaEmisorProperties.cs linguist-generated=true +Models/NominaEmisorPropertiesEntidadSncf.cs linguist-generated=true +Models/NominaHorasExtraProperties.cs linguist-generated=true +Models/NominaIncapacidadProperties.cs linguist-generated=true +Models/NominaJubilacionProperties.cs linguist-generated=true +Models/NominaPercepcionProperties.cs linguist-generated=true +Models/NominaPercepcionesProperties.cs linguist-generated=true +Models/NominaReceptorProperties.cs linguist-generated=true +Models/NominaSeparacionProperties.cs linguist-generated=true +Models/NominaSubContratacionProperties.cs linguist-generated=true +Models/OkResponse.cs linguist-generated=true +Models/OneOf2.cs linguist-generated=true +Models/OneOf3.cs linguist-generated=true +Models/OneOf4.cs linguist-generated=true +Models/OneOf6.cs linguist-generated=true +Models/OneOf7.cs linguist-generated=true +Models/Organization.cs linguist-generated=true +Models/OrganizationDeleteCerts.cs linguist-generated=true +Models/OrganizationInvite.cs linguist-generated=true +Models/OrganizationPendingAddOnsUpdate.cs linguist-generated=true +Models/OrganizationPendingPlanUpdate.cs linguist-generated=true +Models/OrganizationReceipts.cs linguist-generated=true +Models/OrganizationSeriesDeletion.cs linguist-generated=true +Models/OrganizationTeamRole.cs linguist-generated=true +Models/OrganizationTeamRoleTemplate.cs linguist-generated=true +Models/OrganizationUserAccess.cs linguist-generated=true +Models/Payment.cs linguist-generated=true +Models/PaymentRelated.cs linguist-generated=true +Models/PaymentRelatedDocumentsItem.cs linguist-generated=true +Models/PaymentRelatedDocumentsItemTaxesItem.cs linguist-generated=true +Models/PaymentSummary.cs linguist-generated=true +Models/PaymentSummaryTax.cs linguist-generated=true +Models/Product.cs linguist-generated=true +Models/ProductCategory.cs linguist-generated=true +Models/ProductCategoryDetail.cs linguist-generated=true +Models/ProductCategoryList.cs linguist-generated=true +Models/ProductInfo.cs linguist-generated=true +Models/Receipt.cs linguist-generated=true +Models/ReceiptInvoiceSummaryTax.cs linguist-generated=true +Models/RelatedResourceMessage.cs linguist-generated=true +Models/Retention.cs linguist-generated=true +Models/RetentionPeriod.cs linguist-generated=true +Models/RetentionRetainedTax.cs linguist-generated=true +Models/RetentionTotals.cs linguist-generated=true +Models/SearchCartaPorteNavalAuthorizationsResponseDataItem.cs linguist-generated=true Models/SearchResult.cs linguist-generated=true +Models/SelfInvoiceSettings.cs linguist-generated=true +Models/SendInvoiceByEmailResponse.cs linguist-generated=true +Models/SendReceiptByEmailResponse.cs linguist-generated=true +Models/SendRetentionByEmailResponse.cs linguist-generated=true +Models/SeriesGroup.cs linguist-generated=true +Models/SignedDownloadUrl.cs linguist-generated=true +Models/Stamp.cs linguist-generated=true +Models/Tax.cs linguist-generated=true +Models/TaxIdValidation.cs linguist-generated=true Models/TaxInfoError.cs linguist-generated=true Models/TaxInfoValidation.cs linguist-generated=true -Router/CustomerRouter.cs linguist-generated=true +Models/ToInvoiceSummary.cs linguist-generated=true +Models/Webhook.cs linguist-generated=true +Models/ZipCode.cs linguist-generated=true +Wrappers/CartaporteCatalogWrapper.cs linguist-generated=true +Wrappers/CatalogWrapper.cs linguist-generated=true +Wrappers/ComercioExteriorCatalogWrapper.cs linguist-generated=true Wrappers/CustomerWrapper.cs linguist-generated=true +Wrappers/ICartaporteCatalogWrapper.cs linguist-generated=true +Wrappers/ICatalogWrapper.cs linguist-generated=true +Wrappers/IComercioExteriorCatalogWrapper.cs linguist-generated=true Wrappers/ICustomerWrapper.cs linguist-generated=true +Wrappers/IInvoiceWrapper.cs linguist-generated=true +Wrappers/INominaCatalogWrapper.cs linguist-generated=true +Wrappers/IOrganizationWrapper.cs linguist-generated=true +Wrappers/IProductWrapper.cs linguist-generated=true +Wrappers/IReceiptWrapper.cs linguist-generated=true +Wrappers/IRetentionWrapper.cs linguist-generated=true +Wrappers/IToolWrapper.cs linguist-generated=true +Wrappers/IWebhookWrapper.cs linguist-generated=true +Wrappers/InvoiceWrapper.cs linguist-generated=true +Wrappers/NominaCatalogWrapper.cs linguist-generated=true +Wrappers/OrganizationWrapper.cs linguist-generated=true +Wrappers/ProductWrapper.cs linguist-generated=true +Wrappers/ReceiptWrapper.cs linguist-generated=true +Wrappers/RetentionWrapper.cs linguist-generated=true +Wrappers/ToolWrapper.cs linguist-generated=true +Wrappers/WebhookWrapper.cs linguist-generated=true # END generated SDK diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e08b48e..842b768 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,7 +58,7 @@ jobs: run: dotnet test FacturapiTest/FacturapiTest.csproj --framework ${{ matrix.test_framework }} --configuration Release --no-build codegen: - name: Verify generated Customers SDK + name: Verify generated SDK runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/CHANGELOG.md b/CHANGELOG.md index 325e29c..3d51837 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,16 +9,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Breaking -- `Customer.SatValidatedAt` and `Customer.EditLinkExpiresAt` are nullable dates, matching responses that contain `null`. See the README migration guide. +- Align response models with the API contract, including nullable dates and optional fields, decimal numeric values, typed nested objects, and corrected property names. See the README migration guide. +- Retention methods return retention models; ZIP requests expose typed models; organization key and series operations return the documented lists. Receipt invoicing and email methods expose their API results. +- Webhook signature verification returns `ApiEvent` and runs locally. Explicit remote verification preserves string or object payload responses. ### Added -- Typed customer creation, update and search inputs, with helpers for national, foreign, generic and edit-link workflows. Existing dictionary calls remain supported. -- Expose customer organization, CURP and external ID, and stable fiscal-validation detail codes and sources. +- Typed inputs, filters and XML documentation across all public API operations, including invoice and retention downloads, signed URLs, receipt assignment and summaries, FIEL uploads, product categories, geographic and fiscal catalogs, and foreign-trade catalogs. +- Invoice creation variants for Ingreso, Egreso, Pago, Nómina and Traslado, partial draft inputs, and cancellation inputs that require a substitution document when applicable. +- Typed complements for payments, payroll, Carta Porte, foreign trade and fiscal legends, preserving custom XML and open JSON values. +- Typed API error details through `FacturapiException.ErrorDetails`, retaining the original `Errors` JSON. +- `OneOf` alternatives with implicit conversions and response inspection, and input dates accepting ISO strings, `DateTime` or `DateTimeOffset`. ### Fixed -- Serialize boolean query values as lowercase `true` and `false`. +- Preserve omitted fields versus explicit nulls and serialize boolean, numeric and date query values using their wire formats. +- Decode webhook event objects according to their declared resource type without making an HTTP request for local signature verification. ## [7.1.0] - 2026-10-07 diff --git a/FacturAPIException.cs b/FacturAPIException.cs index a87a792..d9c174a 100644 --- a/FacturAPIException.cs +++ b/FacturAPIException.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Newtonsoft.Json.Linq; @@ -11,6 +11,8 @@ public class FacturapiException : Exception public string Path { get; private set; } public string Location { get; private set; } public JArray Errors { get; private set; } + /// Detalles de error tipados. Errors conserva el JSON original para accesos dinámicos. + public IReadOnlyList ErrorDetails => Errors?.ToObject() ?? Array.Empty(); public string LogId { get; private set; } public IReadOnlyDictionary Headers { get; private set; } diff --git a/FacturapiClient.cs b/FacturapiClient.cs index 485b398..ae1eeaf 100644 --- a/FacturapiClient.cs +++ b/FacturapiClient.cs @@ -17,6 +17,8 @@ public sealed class FacturapiClient : IFacturapiClient public ICatalogWrapper Catalog { get; private set; } public ICartaporteCatalogWrapper CartaporteCatalog { get; private set; } public INominaCatalogWrapper NominaCatalog { get; private set; } + /// Busca claves y descripciones de fracciones arancelarias de comercio exterior. + public IComercioExteriorCatalogWrapper ComercioExteriorCatalog { get; private set; } public IToolWrapper Tool { get; private set; } public IWebhookWrapper Webhook { get; private set; } private readonly HttpClient httpClient; @@ -43,6 +45,7 @@ private FacturapiClient(string apiKey, string apiVersion, HttpClient httpClient, this.Catalog = new CatalogWrapper(apiKey, apiVersion, this.httpClient); this.CartaporteCatalog = new CartaporteCatalogWrapper(apiKey, apiVersion, this.httpClient); this.NominaCatalog = new NominaCatalogWrapper(apiKey, apiVersion, this.httpClient); + this.ComercioExteriorCatalog = new ComercioExteriorCatalogWrapper(apiKey, apiVersion, this.httpClient); this.Tool = new ToolWrapper(apiKey, apiVersion, this.httpClient); this.Webhook = new WebhookWrapper(apiKey, apiVersion, this.httpClient); } diff --git a/FacturapiTest/ClientCompatibilityTests.cs b/FacturapiTest/ClientCompatibilityTests.cs index b81826f..9eca8a8 100644 --- a/FacturapiTest/ClientCompatibilityTests.cs +++ b/FacturapiTest/ClientCompatibilityTests.cs @@ -22,7 +22,7 @@ public void Router_ListCustomers_SkipsNullQueryValues() [""] = "ignored" }; - var url = Router.ListCustomers(query); + var url = Router.UriWithQuery("customers", query); Assert.Equal("customers", url); } @@ -37,7 +37,7 @@ public void Router_ListCustomers_SendsExplicitEmptyQueryValues() ["disabled"] = false }; - var url = Router.ListCustomers(query); + var url = Router.UriWithQuery("customers", query); Assert.Equal("customers?foo=&enabled=true&disabled=false", url); } @@ -65,6 +65,7 @@ public async Task RetentionCancelAsync_ThrowsFacturapiExceptionWithStatus() Assert.Equal(400, exception.Status); Assert.Equal("bad retention", exception.Message); + Assert.Empty(exception.ErrorDetails); } [Fact] diff --git a/FacturapiTest/WrapperBehaviorTests.cs b/FacturapiTest/WrapperBehaviorTests.cs index 180ad63..3de7c53 100644 --- a/FacturapiTest/WrapperBehaviorTests.cs +++ b/FacturapiTest/WrapperBehaviorTests.cs @@ -134,13 +134,13 @@ public async Task OrganizationDeleteSeriesAsync_UsesDeleteSeriesRoute() Assert.Equal(HttpMethod.Delete, request.Method); Assert.NotNull(request.RequestUri); Assert.Equal("/v2/organizations/org_1/series-group/A", request.RequestUri.PathAndQuery); - return Task.FromResult(JsonResponse("{\"name\":\"A\"}")); + return Task.FromResult(JsonResponse("[{\"series\":\"A\"}]")); }); var wrapper = new OrganizationWrapper("test_key", "v2", CreateHttpClient(handler)); var result = await wrapper.DeleteSeriesAsync("org_1", "A"); - Assert.Equal("A", result.Name); + Assert.Equal("A", Assert.Single(result)?.Series); } [Fact] @@ -514,7 +514,7 @@ public async Task ErrorMapping_ExposesApiErrorFieldsAndHeaders() var response = new HttpResponseMessage((HttpStatusCode)429) { Content = new StringContent( - "{\"message\":\"too many requests\",\"status\":429,\"code\":\"RATE_LIMIT_EXCEEDED\",\"path\":\"date\",\"location\":\"query\",\"errors\":[{\"code\":\"required\",\"message\":\"date is required\",\"path\":\"date\",\"location\":\"query\"}]}", + "{\"message\":\"too many requests\",\"status\":429,\"code\":\"RATE_LIMIT_EXCEEDED\",\"path\":\"date\",\"location\":\"query\",\"errors\":[{\"source\":\"facturapi\",\"code\":\"required\",\"message\":\"date is required\",\"path\":\"date\",\"location\":\"query\"}]}", Encoding.UTF8, "application/json") }; @@ -533,6 +533,8 @@ public async Task ErrorMapping_ExposesApiErrorFieldsAndHeaders() Assert.Equal("query", exception.Location); Assert.Equal("log_123", exception.LogId); Assert.Equal("required", exception.Errors[0]["code"]?.ToString()); + Assert.Equal("required", Assert.Single(exception.ErrorDetails).Code); + Assert.Equal("facturapi", Assert.Single(exception.ErrorDetails).Source); Assert.Equal("3", exception.Headers["retry-after"]); Assert.Equal("log_123", exception.Headers["x-facturapi-log-id"]); } @@ -637,7 +639,7 @@ public async Task InvoiceCreateZipRequestAsync_UsesZipRequestsPostRoute() ["invoice_types"] = new[] { "I", "E" } }); - Assert.Equal("zip_1", result["id"]?.ToString()); + Assert.Equal("zip_1", result.Id); } [Fact] @@ -666,7 +668,7 @@ public async Task InvoiceListZipRequestsAsync_UsesZipRequestsQueryRoute() }); Assert.Single(result.Data); - Assert.Equal("zip_1", result.Data[0]["id"]?.ToString()); + Assert.Equal("zip_1", result.Data[0].Id); } [Fact] @@ -683,7 +685,7 @@ public async Task InvoiceRetrieveZipRequestAsync_UsesZipRequestRoute() var wrapper = new InvoiceWrapper("test_key", "v2", CreateHttpClient(handler)); var result = await wrapper.RetrieveZipRequestAsync("zip_1"); - Assert.Equal("finished", result["status"]?.ToString()); + Assert.Equal("finished", result.Status); } [Fact] @@ -760,7 +762,7 @@ public async Task GeneratedCustomerInputs_PreserveOmissionExplicitNullAndTypedRe Assert.Null(result.EditLinkExpiresAt); Assert.Equal("org_1", result.Organization); Assert.Equal("external_1", result.ExternalId); - Assert.Equal("86500", result.Address.Zip); + Assert.Equal("86500", result.Address!.Zip); } [Fact] @@ -800,6 +802,215 @@ public async Task GeneratedCustomerListParams_SerializeDateRangesAndReadCursorPa Assert.Equal("cus_1", Assert.Single(result.Data).Id); } + [Fact] + public async Task TypedInvoiceCreation_PreservesAlternativesAndOpaqueXml() + { + const string xml = "&value]]>"; + var handler = new RecordingHandler(async (request, cancellationToken) => + { + Assert.Equal("/v2/invoices", request.RequestUri!.AbsolutePath); + var body = JObject.Parse(await request.Content!.ReadAsStringAsync()); + Assert.Equal("I", (string?)body["type"]); + Assert.Equal("cus_1", (string?)body["customer"]); + Assert.Equal("prod_1", (string?)body["items"]![0]!["product"]); + Assert.Equal(100.25m, (decimal?)body["items"]![1]!["product"]!["price"]); + Assert.Equal("custom", (string?)body["complements"]![0]!["type"]); + Assert.Equal(xml, (string?)body["complements"]![0]!["data"]); + return JsonResponse("{\"id\":\"inv_1\",\"status\":\"draft\",\"date\":null,\"uuid\":null,\"stamp\":null,\"total\":300.25}"); + }); + IInvoiceWrapper wrapper = new InvoiceWrapper("test_key", "v2", CreateHttpClient(handler)); + var custom = new CustomComplementInput(xml); + InvoiceComplementInput baseComplement = custom; + Assert.Equal(xml, baseComplement.Data!.Value.Value); + var result = await wrapper.CreateIngresoAsync(new InvoiceIngresoInput(new List + { + new InvoiceItemInput("prod_1") { Quantity = 2 }, + new InvoiceItemInput(new InvoiceItemProductInput("Servicio", "84111506", 100.25m)) + }, PaymentForm.TRANSFERENCIA_ELECTRONICA) + { + Customer = "cus_1", Complements = new List { custom } + }); + Assert.Equal("inv_1", result.Id); + Assert.Equal(300.25m, result.Total); + Assert.Null(result.Date); + Assert.Null(result.Uuid); + Assert.Null(result.Stamp); + } + + [Fact] + public async Task TypedEmailRecipients_SerializeStringsAndListsWithoutEnvelopes() + { + var handler = new RecordingHandler(async (request, cancellationToken) => + { + Assert.Equal("/v2/invoices/inv_1/email", request.RequestUri!.AbsolutePath); + var body = JObject.Parse(await request.Content!.ReadAsStringAsync()); + Assert.True(body["email"]!.Type == JTokenType.Array || body["email"]!.Type == JTokenType.String); + Assert.Null(body["email"] as JObject); + return JsonResponse("{\"ok\":true}"); + }); + var wrapper = new InvoiceWrapper("test_key", "v2", CreateHttpClient(handler)); + Assert.True((await wrapper.SendByEmailAsync("inv_1", new SendInvoiceByEmailInput { Email = new List { "a@example.com", "b@example.com" } })).Ok); + Assert.True((await wrapper.SendByEmailAsync("inv_1", new SendInvoiceByEmailInput { Email = "a@example.com" })).Ok); + + } + + [Fact] + public async Task NativeDateAndNumericQueries_UseWireFormatsAcrossCultures() + { + var handler = new RecordingHandler((request, cancellationToken) => + { + var query = Uri.UnescapeDataString(request.RequestUri!.Query); + if (request.RequestUri.AbsolutePath.EndsWith("payment-summary")) + { + Assert.Equal("?amount=58.5", query); + return Task.FromResult(JsonResponse("{\"uuid\":\"uuid_1\",\"amount\":58.5,\"installment\":2,\"taxes\":[]}")); + } + Assert.Contains("date[gte]=2026-01-01T00:00:00.0000000Z", query); + Assert.Contains("date[lte]=2026-01-02T00:00:00.0000000+02:00", query); + Assert.Contains("cancellation_status=none&cancellation_status=canceled", query); + return Task.FromResult(JsonResponse("{\"next_cursor\":null,\"data\":[]}")); + }); + var wrapper = new InvoiceWrapper("test_key", "v2", CreateHttpClient(handler)); + await wrapper.ListAsync(new InvoiceListParams + { + Date = new DateRangeInput { Gte = new DateTime(2026, 1, 1, 0, 0, 0, DateTimeKind.Utc), Lte = new DateTimeOffset(2026, 1, 2, 0, 0, 0, TimeSpan.FromHours(2)) }, + CancellationStatus = new List { "none", "canceled" } + }); + var previous = System.Globalization.CultureInfo.CurrentCulture; + try + { + System.Globalization.CultureInfo.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo("sv-SE"); + Assert.Equal(58.5m, (await wrapper.GetPaymentSummaryAsync("inv_1", 58.5)).Amount); + } + finally { System.Globalization.CultureInfo.CurrentCulture = previous; } + } + + [Fact] + public async Task ExtendedCatalogs_AreWiredToTheClientAndReturnTypedResults() + { + var handler = new RecordingHandler((request, cancellationToken) => + { + Assert.Equal("Basic", request.Headers.Authorization!.Scheme); + if (request.RequestUri!.AbsolutePath == "/v2/catalogs/zip-codes/01000") + return Task.FromResult(JsonResponse("{\"key\":\"01000\",\"state\":{\"key\":\"CMX\",\"description\":\"Ciudad de México\"}}")); + Assert.Equal("/v2/catalogs/comercioexterior/2.0/tariff-fractions", request.RequestUri.AbsolutePath); + return Task.FromResult(JsonResponse("{\"data\":[{\"key\":\"0101\",\"description\":\"Caballos\"}]}")); + }); + using var http = CreateHttpClient(handler); + using var sdk = FacturapiClient.CreateWithCustomHttpClient("sk_test", http); + Assert.Equal("CMX", (await sdk.Catalog.GetZipCode("01000")).State!.Key); + Assert.Equal("0101", Assert.Single((await sdk.ComercioExteriorCatalog.SearchTariffFractions(new ComercioExteriorCatalogSearchTariffFractionsParams { Q = "0101" })).Data).Key); + } + + [Fact] + public async Task FielUploadAndLiveKeys_PreserveMultipartAndReadArrayResponses() + { + var handler = new RecordingHandler(async (request, cancellationToken) => + { + if (request.Method == HttpMethod.Put) + { + Assert.Equal("/v2/organizations/org_1/fiel", request.RequestUri!.AbsolutePath); + Assert.Equal("multipart/form-data", request.Content!.Headers.ContentType!.MediaType); + var content = await request.Content.ReadAsStringAsync(); + Assert.Contains("name=cer", content); + Assert.Contains("name=key", content); + Assert.Contains("name=password", content); + Assert.Contains("certificate", content); + return JsonResponse("{\"id\":\"org_1\"}"); + } + return JsonResponse("[{\"id\":\"key_1\",\"first_12\":\"prefix\",\"created_at\":\"2026-01-01T00:00:00Z\"}]"); + }); + var wrapper = new OrganizationWrapper("test_key", "v2", CreateHttpClient(handler)); + using var cer = new MemoryStream(Encoding.UTF8.GetBytes("certificate")); + using var key = new MemoryStream(Encoding.UTF8.GetBytes("private-key-fixture")); + Assert.Equal("org_1", (await wrapper.UploadFielAsync("org_1", cer, key, "password-fixture")).Id); + var liveKey = Assert.Single(await wrapper.ListLiveApiKeysAsync("org_1")); + Assert.Equal("key_1", liveKey.Id); + Assert.Equal(new DateTime(2026, 1, 1, 0, 0, 0, DateTimeKind.Utc), liveKey.CreatedAt); + } + + [Fact] + public async Task ReceiptSummary_SelectsDryRunWithoutMutatingTheInput() + { + var handler = new RecordingHandler(async (request, cancellationToken) => + { + Assert.Equal("/v2/receipts/to-invoice", request.RequestUri!.AbsolutePath); + var body = JObject.Parse(await request.Content!.ReadAsStringAsync()); + Assert.True((bool)body["dry_run"]!); + Assert.Equal("rec_1", (string?)body["keys"]![0]); + return JsonResponse("{\"subtotal\":100,\"discount\":0,\"total\":116,\"receipts\":[\"rec_1\"],\"payment_form\":\"03\",\"item_count\":1,\"taxes\":{\"totalAdded\":16,\"totalWithholding\":0,\"allAdded\":[],\"allWithholding\":[],\"localTotalAdded\":0,\"localTotalWithholding\":0,\"localAllAdded\":[],\"localAllWithholding\":[]}}"); + }); + var wrapper = new ReceiptWrapper("test_key", "v2", CreateHttpClient(handler)); + var input = new ToInvoiceInput(new List { "rec_1" }) { DryRun = false }; + var summary = await wrapper.SummarizeToInvoiceAsync(input); + Assert.Equal(116m, summary.Total); + Assert.Equal(1, summary.ItemCount); + Assert.False(input.DryRun); + } + + [Fact] + public async Task WebhookSignatures_AreVerifiedLocallyAgainstOriginalPayloadBytes() + { + const string payload = "{\"id\":\"evt_1\",\"created_at\":\"2026-01-01T00:00:00Z\",\"livemode\":false,\"organization\":\"org_1\",\"type\":\"customer.edit_link_completed\",\"data\":{\"type\":\"customer\",\"object\":{\"id\":\"cus_1\"}}}"; + const string signature = "b9522a72eaf13b9411ff1182ca4a611bd6fa42e42dffd25824b11b9429cc0ba7"; + var handler = new RecordingHandler((request, cancellationToken) => throw new InvalidOperationException("Signature verification must not call HTTP.")); + var wrapper = new WebhookWrapper("test_key", "v2", CreateHttpClient(handler)); + var result = await wrapper.ValidateSignatureAsync("test_secret", signature.ToUpperInvariant(), payload); + Assert.Equal("evt_1", result.Id); + Assert.Equal(new DateTime(2026, 1, 1, 0, 0, 0, DateTimeKind.Utc), result.CreatedAt); + Assert.True(result.Data.Object.TryGet(out var customer)); + Assert.Equal("cus_1", customer.Id); + await Assert.ThrowsAsync(() => wrapper.ValidateSignatureAsync(null!)); + await Assert.ThrowsAsync(() => wrapper.ValidateSignatureAsync("test_secret", signature, payload + " ")); + await Assert.ThrowsAsync(() => wrapper.ValidateSignatureAsync("test_secret", new string('z', 64), payload)); + await Assert.ThrowsAsync(() => wrapper.ValidateSignatureAsync("test_secret", signature, payload, new CancellationToken(true))); + } + + [Fact] + public async Task RemoteWebhookVerification_PreservesStringsAndOpenObjectValues() + { + var count = 0; + const string payload = "{\"id\":\"evt_1\"}"; + var handler = new RecordingHandler(async (request, cancellationToken) => + { + Assert.Equal("/v2/webhooks/validate-signature", request.RequestUri!.AbsolutePath); + var body = JObject.Parse(await request.Content!.ReadAsStringAsync()); + Assert.Equal(payload, (string?)body["payload"]); + return ++count == 1 ? JsonResponse(Newtonsoft.Json.JsonConvert.SerializeObject(payload)) : JsonResponse("{\"metadata\":{\"at\":\"2026-01-01T00:00:00Z\",\"xml\":\"\"}}"); + }); + var wrapper = new WebhookWrapper("test_key", "v2", CreateHttpClient(handler)); + var input = new ValidateWebhookSignatureInput("test_secret", payload, "signature-fixture"); + Assert.True((await wrapper.ValidateSignatureRemotelyAsync(input)).TryGet(out var verified)); + Assert.Equal(payload, verified); + Assert.True((await wrapper.ValidateSignatureRemotelyAsync(input)).TryGet>(out var response)); + var metadata = Assert.IsType(response["metadata"]); + Assert.Equal(JTokenType.String, metadata["at"]!.Type); + Assert.Equal("", (string?)metadata["xml"]); + } + + [Fact] + public async Task DraftAndCancellationVariants_SelectRequiredFieldsFromTheContract() + { + var handler = new RecordingHandler(async (request, cancellationToken) => + { + if (request.Method == HttpMethod.Post) + { + var body = JObject.Parse(await request.Content!.ReadAsStringAsync()); + Assert.Equal("I", (string?)body["type"]); + Assert.Equal("draft", (string?)body["status"]); + Assert.Null(body["items"]); + Assert.Null(body["payment_form"]); + return JsonResponse("{\"id\":\"draft_1\",\"status\":\"draft\",\"date\":null}"); + } + Assert.Equal("?motive=01&substitution=replacement_1", request.RequestUri!.Query); + return JsonResponse("{\"id\":\"inv_1\",\"status\":\"canceled\"}"); + }); + IInvoiceWrapper wrapper = new InvoiceWrapper("test_key", "v2", CreateHttpClient(handler)); + Assert.Equal("draft_1", (await wrapper.CreateDraftIngresoAsync(new InvoiceIngresoDraftInput())).Id); + Assert.Equal("inv_1", (await wrapper.CancelAsync("inv_1", new CancellationWithSubstitutionInput( + CancellationMotive.COMPROBANTE_EMITIDO_CON_ERRORES_CON_RELACION, "replacement_1"))).Id); + } + private static HttpClient CreateHttpClient(HttpMessageHandler handler) { return new HttpClient(handler) diff --git a/IFacturapiClient.cs b/IFacturapiClient.cs index dad3419..88e2aa7 100644 --- a/IFacturapiClient.cs +++ b/IFacturapiClient.cs @@ -1,4 +1,4 @@ -using Facturapi.Wrappers; +using Facturapi.Wrappers; using System; namespace Facturapi @@ -14,6 +14,8 @@ public interface IFacturapiClient : IDisposable ICatalogWrapper Catalog { get; } ICartaporteCatalogWrapper CartaporteCatalog { get; } INominaCatalogWrapper NominaCatalog { get; } + /// Busca claves y descripciones de fracciones arancelarias de comercio exterior. + IComercioExteriorCatalogWrapper ComercioExteriorCatalog { get; } IToolWrapper Tool { get; } IWebhookWrapper Webhook { get; } } diff --git a/Models/Address.cs b/Models/Address.cs index a2a22a8..f17acf6 100644 --- a/Models/Address.cs +++ b/Models/Address.cs @@ -1,7 +1,10 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { @@ -16,7 +19,7 @@ public class Address /// Admite null. /// [JsonProperty("street")] - public string Street { get; set; } + public string? Street { get; set; } = default!; /// /// exterior @@ -24,7 +27,7 @@ public class Address /// Admite null. /// [JsonProperty("exterior")] - public string Exterior { get; set; } + public string? Exterior { get; set; } = default!; /// /// interior @@ -32,7 +35,7 @@ public class Address /// Admite null. /// [JsonProperty("interior")] - public string Interior { get; set; } + public string? Interior { get; set; } = default!; /// /// neighborhood @@ -40,7 +43,7 @@ public class Address /// Admite null. /// [JsonProperty("neighborhood")] - public string Neighborhood { get; set; } + public string? Neighborhood { get; set; } = default!; /// /// city @@ -48,7 +51,7 @@ public class Address /// Admite null. /// [JsonProperty("city")] - public string City { get; set; } + public string? City { get; set; } = default!; /// /// municipality @@ -56,7 +59,7 @@ public class Address /// Admite null. /// [JsonProperty("municipality")] - public string Municipality { get; set; } + public string? Municipality { get; set; } = default!; /// /// zip @@ -64,7 +67,7 @@ public class Address /// Admite null. /// [JsonProperty("zip")] - public string Zip { get; set; } + public string? Zip { get; set; } = default!; /// /// state @@ -72,7 +75,7 @@ public class Address /// Admite null. /// [JsonProperty("state")] - public string State { get; set; } + public string? State { get; set; } = default!; /// /// country @@ -80,7 +83,7 @@ public class Address /// Admite null. /// [JsonProperty("country")] - public string Country { get; set; } + public string? Country { get; set; } = default!; } } diff --git a/Models/ApiEvent.cs b/Models/ApiEvent.cs new file mode 100644 index 0000000..e8e12a0 --- /dev/null +++ b/Models/ApiEvent.cs @@ -0,0 +1,68 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ApiEvent + /// + public class ApiEvent + { + /// + /// ID del evento + /// Requerido. + /// + [JsonProperty("id")] + public string Id { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha y hora de creación del evento + /// Requerido. + /// + [JsonProperty("created_at")] + public DateTime CreatedAt { get; set; } = default!; + + /// + /// Indica si el evento se generó en modo test (false) o en modo producción (true). + /// Requerido. + /// + [JsonProperty("livemode")] + public bool Livemode { get; set; } = default!; + + /// + /// ID de la organización a la que pertenece el evento + /// Requerido. + /// + [JsonProperty("organization")] + public string Organization { get; set; } = default!; + + /// + /// Mensajes relacionados con el recurso asociado al evento. + /// Opcional. + /// + [JsonProperty("related_resource_messages")] + public List? RelatedResourceMessages { get; set; } = default!; + + /// + /// Tipo de evento + /// Valores: "invoice.global_invoice_created", "invoice.status_updated", "invoice.created_from_dashboard", "invoice.cancellation_status_updated", "receipt.self_invoice_complete", "receipt.status_updated", "customer.edit_link_completed". + /// Requerido. + /// + [JsonProperty("type")] + public string Type { get; set; } = default!; + + /// + /// data + /// Requerido. + /// + [JsonProperty("data")] + public ApiEventData Data { get; set; } = default!; + + } +} diff --git a/Models/ApiEventData.JsonConverter.cs b/Models/ApiEventData.JsonConverter.cs new file mode 100644 index 0000000..75c301b --- /dev/null +++ b/Models/ApiEventData.JsonConverter.cs @@ -0,0 +1,34 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +namespace Facturapi +{ + internal sealed class ApiEventDataJsonConverter : JsonConverter + { + public override bool CanWrite => false; + public override bool CanConvert(Type type) => type == typeof(ApiEventData); + public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) => throw new NotSupportedException(); + public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var data = JObject.Load(reader); + var result = new ApiEventData(); + var @object = data["object"]; + data.Remove("object"); + using (var content = data.CreateReader()) serializer.Populate(content, result); + if (@object != null && @object.Type != JTokenType.Null) + { + switch ((string?)data["type"]) + { + case "invoice": result.Object = @object.ToObject(serializer)!; break; + case "receipt": result.Object = @object.ToObject(serializer)!; break; + case "customer": result.Object = @object.ToObject(serializer)!; break; + default: throw new JsonSerializationException("Unknown discriminator value for a documented response alternative."); + } + } + return result; + } + } +} diff --git a/Models/ApiEventData.cs b/Models/ApiEventData.cs new file mode 100644 index 0000000..0a15f8f --- /dev/null +++ b/Models/ApiEventData.cs @@ -0,0 +1,33 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ApiEventData + /// + [JsonConverter(typeof(ApiEventDataJsonConverter))] + public class ApiEventData + { + /// + /// Tipo de objeto asociado al evento + /// Valores: "invoice", "receipt", "customer". + /// Requerido. + /// + [JsonProperty("type")] + public string Type { get; set; } = default!; + + /// + /// object + /// Requerido. + /// + [JsonProperty("object")] + public OneOf Object { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteAutotransporte.cs b/Models/CartaPorteAutotransporte.cs new file mode 100644 index 0000000..e2dba61 --- /dev/null +++ b/Models/CartaPorteAutotransporte.cs @@ -0,0 +1,52 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteAutotransporte + /// + public class CartaPorteAutotransporte + { + /// + /// Clave del permiso SCT del autotransporte. + /// Requerido. + /// + [JsonProperty("PermSCT")] + public string PermSCT { get; set; } = default!; + + /// + /// Número del permiso SCT. + /// Requerido. + /// + [JsonProperty("NumPermisoSCT")] + public string NumPermisoSCT { get; set; } = default!; + + /// + /// Datos de identificación del vehículo principal. + /// Requerido. + /// + [JsonProperty("IdentificacionVehicular")] + public CartaPorteIdentificacionVehicular IdentificacionVehicular { get; set; } = default!; + + /// + /// Información de seguros aplicables. + /// Requerido. + /// + [JsonProperty("Seguros")] + public CartaPorteSeguros Seguros { get; set; } = default!; + + /// + /// Lista de remolques acoplados. + /// Opcional. + /// + [JsonProperty("Remolques")] + public List? Remolques { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteCantidadTransporta.cs b/Models/CartaPorteCantidadTransporta.cs new file mode 100644 index 0000000..d43ec4b --- /dev/null +++ b/Models/CartaPorteCantidadTransporta.cs @@ -0,0 +1,45 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteCantidadTransporta + /// + public class CartaPorteCantidadTransporta + { + /// + /// Cantidad + /// Requerido. + /// + [JsonProperty("Cantidad")] + public decimal Cantidad { get; set; } = default!; + + /// + /// IDOrigen + /// Requerido. + /// + [JsonProperty("IDOrigen")] + public string IDOrigen { get; set; } = default!; + + /// + /// IDDestino + /// Requerido. + /// + [JsonProperty("IDDestino")] + public string IDDestino { get; set; } = default!; + + /// + /// Clave del medio de transporte. + /// Opcional. + /// + [JsonProperty("CvesTransporte")] + public string? CvesTransporte { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteCarroFerroviario.cs b/Models/CartaPorteCarroFerroviario.cs new file mode 100644 index 0000000..3063fb8 --- /dev/null +++ b/Models/CartaPorteCarroFerroviario.cs @@ -0,0 +1,52 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteCarroFerroviario + /// + public class CartaPorteCarroFerroviario + { + /// + /// Tipo de carro ferroviario. + /// Opcional. + /// + [JsonProperty("TipoCarro")] + public string? TipoCarro { get; set; } = default!; + + /// + /// Matrícula o número identificador del carro. + /// Opcional. + /// + [JsonProperty("MatriculaCarro")] + public string? MatriculaCarro { get; set; } = default!; + + /// + /// Número de guía asociado al carro. + /// Opcional. + /// + [JsonProperty("GuiaCarro")] + public string? GuiaCarro { get; set; } = default!; + + /// + /// Toneladas netas transportadas en el carro. + /// Opcional. + /// + [JsonProperty("ToneladasNetasCarro")] + public decimal? ToneladasNetasCarro { get; set; } = default!; + + /// + /// Contenedores asociados al carro. + /// Opcional. + /// + [JsonProperty("Contenedor")] + public List? Contenedor { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteContenedorFerroviario.cs b/Models/CartaPorteContenedorFerroviario.cs new file mode 100644 index 0000000..916c2ff --- /dev/null +++ b/Models/CartaPorteContenedorFerroviario.cs @@ -0,0 +1,38 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteContenedorFerroviario + /// + public class CartaPorteContenedorFerroviario + { + /// + /// Tipo de contenedor ferroviario. + /// Opcional. + /// + [JsonProperty("TipoContenedor")] + public string? TipoContenedor { get; set; } = default!; + + /// + /// Peso del contenedor vacío. + /// Opcional. + /// + [JsonProperty("PesoContenedorVacio")] + public decimal? PesoContenedorVacio { get; set; } = default!; + + /// + /// Peso neto de la mercancía contenida. + /// Opcional. + /// + [JsonProperty("PesoNetoMercancia")] + public decimal? PesoNetoMercancia { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteContenedorMaritimo.cs b/Models/CartaPorteContenedorMaritimo.cs new file mode 100644 index 0000000..8f77809 --- /dev/null +++ b/Models/CartaPorteContenedorMaritimo.cs @@ -0,0 +1,66 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteContenedorMaritimo + /// + public class CartaPorteContenedorMaritimo + { + /// + /// Tipo de contenedor marítimo (ISO / catálogo SAT). + /// Opcional. + /// + [JsonProperty("TipoContenedor")] + public string? TipoContenedor { get; set; } = default!; + + /// + /// Matrícula o número identificador del contenedor. + /// Opcional. + /// + [JsonProperty("MatriculaContenedor")] + public string? MatriculaContenedor { get; set; } = default!; + + /// + /// Número de precinto o sello de seguridad. + /// Opcional. + /// + [JsonProperty("NumPrecinto")] + public string? NumPrecinto { get; set; } = default!; + + /// + /// Identificador CCP relacionado cuando se reutiliza información. + /// Opcional. + /// + [JsonProperty("IdCCPRelacionado")] + public string? IdCCPRelacionado { get; set; } = default!; + + /// + /// Placa del vehículo motor asociado (si aplica en transbordo). + /// Opcional. + /// + [JsonProperty("PlacaVMCCP")] + public string? PlacaVMCCP { get; set; } = default!; + + /// + /// Fecha de certificación CCP del contenedor. + /// Opcional. + /// + [JsonProperty("FechaCertificacionCCP")] + public string? FechaCertificacionCCP { get; set; } = default!; + + /// + /// RemolquesCCP + /// Opcional. + /// + [JsonProperty("RemolquesCCP")] + public List? RemolquesCCP { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteContenedorMaritimoRemolquesCCPItem.cs b/Models/CartaPorteContenedorMaritimoRemolquesCCPItem.cs new file mode 100644 index 0000000..a3955cb --- /dev/null +++ b/Models/CartaPorteContenedorMaritimoRemolquesCCPItem.cs @@ -0,0 +1,31 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteContenedorMaritimoRemolquesCCPItem + /// + public class CartaPorteContenedorMaritimoRemolquesCCPItem + { + /// + /// Subtipo de remolque relacionado (CCP). + /// Opcional. + /// + [JsonProperty("SubTipoRemCCP")] + public string? SubTipoRemCCP { get; set; } = default!; + + /// + /// Placa del remolque relacionado (CCP). + /// Opcional. + /// + [JsonProperty("PlacaCCP")] + public string? PlacaCCP { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteDataProperties.cs b/Models/CartaPorteDataProperties.cs new file mode 100644 index 0000000..19b13bc --- /dev/null +++ b/Models/CartaPorteDataProperties.cs @@ -0,0 +1,108 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Complemento Carta Porte versión 3.1. (Beta) + /// + public class CartaPorteDataProperties + { + /// + /// Identificador único de la Carta Porte. + /// Requerido. + /// + [JsonProperty("IdCCP")] + public string IdCCP { get; set; } = default!; + + /// + /// Indica si el transporte es internacional. + /// Requerido. + /// + [JsonProperty("TranspInternac")] + public string TranspInternac { get; set; } = default!; + + /// + /// Entrada o salida de mercancías. + /// Opcional. + /// + [JsonProperty("EntradaSalidaMerc")] + public string? EntradaSalidaMerc { get; set; } = default!; + + /// + /// País de origen o destino. + /// Opcional. + /// + [JsonProperty("PaisOrigenDestino")] + public string? PaisOrigenDestino { get; set; } = default!; + + /// + /// Vía de entrada o salida. + /// Opcional. + /// + [JsonProperty("ViaEntradaSalida")] + public string? ViaEntradaSalida { get; set; } = default!; + + /// + /// Distancia total recorrida. + /// Opcional. + /// + [JsonProperty("TotalDistRec")] + public decimal? TotalDistRec { get; set; } = default!; + + /// + /// Registro del programa ISTMO. + /// Opcional. + /// + [JsonProperty("RegistroISTMO")] + public string? RegistroISTMO { get; set; } = default!; + + /// + /// Polo origen. + /// Opcional. + /// + [JsonProperty("UbicacionPoloOrigen")] + public string? UbicacionPoloOrigen { get; set; } = default!; + + /// + /// Polo destino. + /// Opcional. + /// + [JsonProperty("UbicacionPoloDestino")] + public string? UbicacionPoloDestino { get; set; } = default!; + + /// + /// Objeto con los regímenes aduaneros aplicables. + /// Opcional. + /// + [JsonProperty("RegimenesAduaneros")] + public Dictionary? RegimenesAduaneros { get; set; } = default!; + + /// + /// Arreglo de ubicaciones. + /// Requerido. + /// + [JsonProperty("Ubicaciones")] + public List Ubicaciones { get; set; } = default!; + + /// + /// Mercancias + /// Requerido. + /// + [JsonProperty("Mercancias")] + public CartaPorteMercancias Mercancias { get; set; } = default!; + + /// + /// Figuras de transporte. + /// Opcional. + /// + [JsonProperty("FiguraTransporte")] + public List? FiguraTransporte { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteDataPropertiesFiguraTransporteItem.cs b/Models/CartaPorteDataPropertiesFiguraTransporteItem.cs new file mode 100644 index 0000000..19ca4ed --- /dev/null +++ b/Models/CartaPorteDataPropertiesFiguraTransporteItem.cs @@ -0,0 +1,73 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteDataPropertiesFiguraTransporteItem + /// + public class CartaPorteDataPropertiesFiguraTransporteItem + { + /// + /// Atributo requerido. Clave que identifica el tipo de figura de transporte conforme al catálogo correspondiente (operador, propietario, arrendatario, notificado). Debe coincidir con c_TipoFigura. + /// Requerido. + /// + [JsonProperty("TipoFigura")] + public string TipoFigura { get; set; } = default!; + + /// + /// RFC del operador/propietario/arrendatario o figura interveniente. + /// Opcional. + /// + [JsonProperty("RFCFigura")] + public string? RFCFigura { get; set; } = default!; + + /// + /// Número de licencia del operador cuando TipoFigura corresponde a operador. + /// Opcional. + /// + [JsonProperty("NumLicencia")] + public string? NumLicencia { get; set; } = default!; + + /// + /// Nombre o razón social de la figura de transporte (requerido). + /// Requerido. + /// + [JsonProperty("NombreFigura")] + public string NombreFigura { get; set; } = default!; + + /// + /// Número de registro fiscal en el extranjero de la figura cuando aplica. + /// Opcional. + /// + [JsonProperty("NumRegIdTribFigura")] + public string? NumRegIdTribFigura { get; set; } = default!; + + /// + /// Clave del país de residencia fiscal de la figura (c_Pais) cuando es extranjero. + /// Opcional. + /// + [JsonProperty("ResidenciaFiscalFigura")] + public string? ResidenciaFiscalFigura { get; set; } = default!; + + /// + /// Arreglo opcional con las partes del transporte que se relacionan a la figura. + /// Opcional. + /// + [JsonProperty("PartesTransporte")] + public List? PartesTransporte { get; set; } = default!; + + /// + /// Domicilio asociado a la figura del transporte. + /// Opcional. + /// + [JsonProperty("Domicilio")] + public CartaPorteDomicilio? Domicilio { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteDataPropertiesFiguraTransporteItemPartesTransporteItem.cs b/Models/CartaPorteDataPropertiesFiguraTransporteItemPartesTransporteItem.cs new file mode 100644 index 0000000..9cfdcb2 --- /dev/null +++ b/Models/CartaPorteDataPropertiesFiguraTransporteItemPartesTransporteItem.cs @@ -0,0 +1,24 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteDataPropertiesFiguraTransporteItemPartesTransporteItem + /// + public class CartaPorteDataPropertiesFiguraTransporteItemPartesTransporteItem + { + /// + /// Clave de la parte del transporte conforme al catálogo c_ParteTransporte. + /// Requerido. + /// + [JsonProperty("ParteTransporte")] + public string ParteTransporte { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteDataPropertiesUbicacionesItem.cs b/Models/CartaPorteDataPropertiesUbicacionesItem.cs new file mode 100644 index 0000000..302e0f8 --- /dev/null +++ b/Models/CartaPorteDataPropertiesUbicacionesItem.cs @@ -0,0 +1,108 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteDataPropertiesUbicacionesItem + /// + public class CartaPorteDataPropertiesUbicacionesItem + { + /// + /// Atributo requerido para precisar si el tipo de ubicación corresponde al origen o destino de las ubicaciones para el traslado de los bienes y/o mercancías en los distintos medios de transporte. Valores: "Origen" | "Destino". + /// Requerido. + /// + [JsonProperty("TipoUbicacion")] + public string TipoUbicacion { get; set; } = default!; + + /// + /// Atributo condicional para registrar una clave que identifique el punto de salida o entrada de los bienes y/o mercancías. Formato: "OR" o "DE" seguido de 6 dígitos numéricos (expresión regular (OR|DE)[0-9]{6}). + /// Opcional. + /// + [JsonProperty("IDUbicacion")] + public string? IDUbicacion { get; set; } = default!; + + /// + /// Atributo requerido para registrar el RFC del remitente o destinatario de los bienes y/o mercancías que se trasladan. + /// Requerido. + /// + [JsonProperty("RFCRemitenteDestinatario")] + public string RFCRemitenteDestinatario { get; set; } = default!; + + /// + /// Atributo opcional para registrar el nombre del remitente o destinatario de los bienes y/o mercancías (longitud 1 a 254 caracteres). + /// Opcional. + /// + [JsonProperty("NombreRemitenteDestinatario")] + public string? NombreRemitenteDestinatario { get; set; } = default!; + + /// + /// Atributo condicional para el número de identificación o registro fiscal del país de residencia del remitente o destinatario cuando se trate de residentes en el extranjero (longitud 6 a 40 caracteres). + /// Opcional. + /// + [JsonProperty("NumRegIdTrib")] + public string? NumRegIdTrib { get; set; } = default!; + + /// + /// Atributo condicional para registrar la clave del país de residencia fiscal conforme al catálogo c_Pais (ISO 3166-1). + /// Opcional. + /// + [JsonProperty("ResidenciaFiscal")] + public string? ResidenciaFiscal { get; set; } = default!; + + /// + /// Atributo condicional para la clave de la estación de origen o destino conforme al catálogo c_Estaciones del complemento Carta Porte y al tipo de transporte. + /// Opcional. + /// + [JsonProperty("NumEstacion")] + public string? NumEstacion { get; set; } = default!; + + /// + /// Atributo condicional para el nombre de la estación de origen o destino conforme al catálogo c_Estaciones (longitud 1 a 50 caracteres). + /// Opcional. + /// + [JsonProperty("NombreEstacion")] + public string? NombreEstacion { get; set; } = default!; + + /// + /// Atributo condicional para registrar el tipo de puerto de origen o destino en transporte marítimo. Valores: "Altura" | "Cabotaje". + /// Opcional. + /// + [JsonProperty("NavegacionTrafico")] + public string? NavegacionTrafico { get; set; } = default!; + + /// + /// Atributo requerido para registrar la fecha y hora estimada de salida o llegada en formato AAAA-MM-DDThh:mm:ss. + /// Requerido. + /// + [JsonProperty("FechaHoraSalidaLlegada")] + public string FechaHoraSalidaLlegada { get; set; } = default!; + + /// + /// Atributo condicional para registrar el tipo de estación por la que pasan las mercancías conforme al catálogo c_TipoEstacion. + /// Opcional. + /// + [JsonProperty("TipoEstacion")] + public string? TipoEstacion { get; set; } = default!; + + /// + /// Atributo condicional para registrar en kilómetros la distancia recorrida entre la ubicación de origen y la de destino parcial o final. + /// Opcional. + /// + [JsonProperty("DistanciaRecorrida")] + public decimal? DistanciaRecorrida { get; set; } = default!; + + /// + /// Domicilio + /// Opcional. + /// + [JsonProperty("Domicilio")] + public CartaPorteDomicilio? Domicilio { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteDerechosDePaso.cs b/Models/CartaPorteDerechosDePaso.cs new file mode 100644 index 0000000..e1c17ad --- /dev/null +++ b/Models/CartaPorteDerechosDePaso.cs @@ -0,0 +1,31 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteDerechosDePaso + /// + public class CartaPorteDerechosDePaso + { + /// + /// Tipo de derecho de paso ferroviario. + /// Opcional. + /// + [JsonProperty("TipoDerechoDePaso")] + public string? TipoDerechoDePaso { get; set; } = default!; + + /// + /// Kilometraje cubierto/pagado en el derecho de paso. + /// Opcional. + /// + [JsonProperty("KilometrajePagado")] + public decimal? KilometrajePagado { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteDetalleMercancia.cs b/Models/CartaPorteDetalleMercancia.cs new file mode 100644 index 0000000..7c88b84 --- /dev/null +++ b/Models/CartaPorteDetalleMercancia.cs @@ -0,0 +1,52 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteDetalleMercancia + /// + public class CartaPorteDetalleMercancia + { + /// + /// Clave de la unidad de peso de la mercancía conforme al catálogo correspondiente. + /// Requerido. + /// + [JsonProperty("UnidadPesoMerc")] + public string UnidadPesoMerc { get; set; } = default!; + + /// + /// Peso bruto de la mercancía incluyendo embalajes y tare. + /// Requerido. + /// + [JsonProperty("PesoBruto")] + public decimal PesoBruto { get; set; } = default!; + + /// + /// Peso neto de la mercancía sin incluir embalajes ni tara. + /// Requerido. + /// + [JsonProperty("PesoNeto")] + public decimal PesoNeto { get; set; } = default!; + + /// + /// Peso de la tara (contenedores, embalajes) asociado a la mercancía. + /// Requerido. + /// + [JsonProperty("PesoTara")] + public decimal PesoTara { get; set; } = default!; + + /// + /// Número de piezas que conforman la mercancía detallada. + /// Opcional. + /// + [JsonProperty("NumPiezas")] + public decimal? NumPiezas { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteDocumentacionAduanera.cs b/Models/CartaPorteDocumentacionAduanera.cs new file mode 100644 index 0000000..ffb2a6c --- /dev/null +++ b/Models/CartaPorteDocumentacionAduanera.cs @@ -0,0 +1,45 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// RFC del importador cuando aplica. + /// + public class CartaPorteDocumentacionAduanera + { + /// + /// Tipo de documento aduanero (pedimento, guía, conocimiento) relacionado. + /// Opcional. + /// + [JsonProperty("TipoDocumento")] + public string? TipoDocumento { get; set; } = default!; + + /// + /// Número de pedimento de importación/exportación. + /// Opcional. + /// + [JsonProperty("NumPedimento")] + public string? NumPedimento { get; set; } = default!; + + /// + /// Identificador alterno del documento aduanero. + /// Opcional. + /// + [JsonProperty("IdentDocAduanero")] + public string? IdentDocAduanero { get; set; } = default!; + + /// + /// RFCImpo + /// Opcional. + /// + [JsonProperty("RFCImpo")] + public string? RFCImpo { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteDomicilio.cs b/Models/CartaPorteDomicilio.cs new file mode 100644 index 0000000..f1bbef9 --- /dev/null +++ b/Models/CartaPorteDomicilio.cs @@ -0,0 +1,87 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Domicilio relacionado a la ubicación en el complemento Carta Porte. + /// + public class CartaPorteDomicilio + { + /// + /// Calle del domicilio de origen y/o destino (requerida en XSD). + /// Opcional. + /// + [JsonProperty("Calle")] + public string? Calle { get; set; } = default!; + + /// + /// Número exterior donde se ubica el domicilio. + /// Opcional. + /// + [JsonProperty("NumeroExterior")] + public string? NumeroExterior { get; set; } = default!; + + /// + /// Número interior del domicilio, si existe. + /// Opcional. + /// + [JsonProperty("NumeroInterior")] + public string? NumeroInterior { get; set; } = default!; + + /// + /// Colonia o dato análogo del domicilio. + /// Opcional. + /// + [JsonProperty("Colonia")] + public string? Colonia { get; set; } = default!; + + /// + /// Ciudad, población o distrito del domicilio. + /// Opcional. + /// + [JsonProperty("Localidad")] + public string? Localidad { get; set; } = default!; + + /// + /// Referencia geográfica adicional (ej. coordenadas GPS). + /// Opcional. + /// + [JsonProperty("Referencia")] + public string? Referencia { get; set; } = default!; + + /// + /// Municipio, delegación, alcaldía o análogo del domicilio. + /// Opcional. + /// + [JsonProperty("Municipio")] + public string? Municipio { get; set; } = default!; + + /// + /// Clave de estado, entidad o región (ISO 3166-2 conforme catálogo SAT). + /// Requerido. + /// + [JsonProperty("Estado")] + public string Estado { get; set; } = default!; + + /// + /// Clave del país (catálogo c_Pais, ISO 3166-1). + /// Requerido. + /// + [JsonProperty("Pais")] + public string Pais { get; set; } = default!; + + /// + /// Código postal del domicilio. + /// Requerido. + /// + [JsonProperty("CodigoPostal")] + public string CodigoPostal { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteGuiaIdentificacion.cs b/Models/CartaPorteGuiaIdentificacion.cs new file mode 100644 index 0000000..dcdce11 --- /dev/null +++ b/Models/CartaPorteGuiaIdentificacion.cs @@ -0,0 +1,38 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteGuiaIdentificacion + /// + public class CartaPorteGuiaIdentificacion + { + /// + /// Número de la guía de identificación asociada a la mercancía. + /// Opcional. + /// + [JsonProperty("NumeroGuiaIdentificacion")] + public string? NumeroGuiaIdentificacion { get; set; } = default!; + + /// + /// Descripción detallada de la guía de identificación. + /// Opcional. + /// + [JsonProperty("DescripGuiaIdentificacion")] + public string? DescripGuiaIdentificacion { get; set; } = default!; + + /// + /// Peso amparado por la guía de identificación. + /// Opcional. + /// + [JsonProperty("PesoGuiaIdentificacion")] + public decimal? PesoGuiaIdentificacion { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteIdentificacionVehicular.cs b/Models/CartaPorteIdentificacionVehicular.cs new file mode 100644 index 0000000..9415db7 --- /dev/null +++ b/Models/CartaPorteIdentificacionVehicular.cs @@ -0,0 +1,45 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteIdentificacionVehicular + /// + public class CartaPorteIdentificacionVehicular + { + /// + /// Configuración vehicular (catCartaPorte:c_ConfigAutotransporte) del vehículo primario. + /// Requerido. + /// + [JsonProperty("ConfigVehicular")] + public string ConfigVehicular { get; set; } = default!; + + /// + /// Peso bruto vehicular máximo permitido. + /// Requerido. + /// + [JsonProperty("PesoBrutoVehicular")] + public decimal PesoBrutoVehicular { get; set; } = default!; + + /// + /// Placa del vehículo motor. + /// Requerido. + /// + [JsonProperty("PlacaVM")] + public string PlacaVM { get; set; } = default!; + + /// + /// Año modelo del vehículo motor. + /// Requerido. + /// + [JsonProperty("AnioModeloVM")] + public string AnioModeloVM { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteMercancia.cs b/Models/CartaPorteMercancia.cs new file mode 100644 index 0000000..4040277 --- /dev/null +++ b/Models/CartaPorteMercancia.cs @@ -0,0 +1,311 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteMercancia + /// + public class CartaPorteMercancia + { + /// + /// Clave del bien o producto transportado (catCartaPorte:c_BienesTransp). + /// Requerido. + /// + [JsonProperty("BienesTransp")] + public string BienesTransp { get; set; } = default!; + + /// + /// Clave STCC para transporte ferroviario cuando corresponda. + /// Opcional. + /// + [JsonProperty("ClaveSTCC")] + public string? ClaveSTCC { get; set; } = default!; + + /// + /// Descripción comercial del bien transportado. + /// Requerido. + /// + [JsonProperty("Descripcion")] + public string Descripcion { get; set; } = default!; + + /// + /// Cantidad total de unidades del bien. + /// Requerido. + /// + [JsonProperty("Cantidad")] + public decimal Cantidad { get; set; } = default!; + + /// + /// Clave de unidad (c_ClaveUnidad) aplicable a la cantidad. + /// Requerido. + /// + [JsonProperty("ClaveUnidad")] + public string ClaveUnidad { get; set; } = default!; + + /// + /// Texto descriptivo de la unidad de medida. + /// Opcional. + /// + [JsonProperty("Unidad")] + public string? Unidad { get; set; } = default!; + + /// + /// Dimensiones físicas de la mercancía (largo x ancho x alto) si aplica. + /// Opcional. + /// + [JsonProperty("Dimensiones")] + public string? Dimensiones { get; set; } = default!; + + /// + /// Indicador de si la mercancía es material peligroso ("Sí" / "No"). + /// Opcional. + /// + [JsonProperty("MaterialPeligroso")] + public string? MaterialPeligroso { get; set; } = default!; + + /// + /// Clave del material peligroso (c_MaterialPeligroso) cuando MaterialPeligroso es Sí. + /// Opcional. + /// + [JsonProperty("CveMaterialPeligroso")] + public string? CveMaterialPeligroso { get; set; } = default!; + + /// + /// Clave del tipo de embalaje utilizado (c_TipoEmbalaje). + /// Opcional. + /// + [JsonProperty("Embalaje")] + public string? Embalaje { get; set; } = default!; + + /// + /// Descripción adicional del embalaje. + /// Opcional. + /// + [JsonProperty("DescripEmbalaje")] + public string? DescripEmbalaje { get; set; } = default!; + + /// + /// Sector regulado por COFEPRIS al que pertenece el producto. + /// Opcional. + /// + [JsonProperty("SectorCOFEPRIS")] + public string? SectorCOFEPRIS { get; set; } = default!; + + /// + /// Nombre del ingrediente activo (productos regulados). + /// Opcional. + /// + [JsonProperty("NombreIngredienteActivo")] + public string? NombreIngredienteActivo { get; set; } = default!; + + /// + /// Nombre químico del producto cuando aplica. + /// Opcional. + /// + [JsonProperty("NomQuimico")] + public string? NomQuimico { get; set; } = default!; + + /// + /// Denominación genérica del producto farmacéutico. + /// Opcional. + /// + [JsonProperty("DenominacionGenericaProd")] + public string? DenominacionGenericaProd { get; set; } = default!; + + /// + /// Denominación distintiva (marca) del producto farmacéutico. + /// Opcional. + /// + [JsonProperty("DenominacionDistintivaProd")] + public string? DenominacionDistintivaProd { get; set; } = default!; + + /// + /// Nombre o razón social del fabricante. + /// Opcional. + /// + [JsonProperty("Fabricante")] + public string? Fabricante { get; set; } = default!; + + /// + /// Fecha de caducidad del producto (AAAAMMDD o formato aplicable). + /// Opcional. + /// + [JsonProperty("FechaCaducidad")] + public string? FechaCaducidad { get; set; } = default!; + + /// + /// Número de lote del medicamento. + /// Opcional. + /// + [JsonProperty("LoteMedicamento")] + public string? LoteMedicamento { get; set; } = default!; + + /// + /// Forma farmacéutica (tableta, cápsula, solución, etc.). + /// Opcional. + /// + [JsonProperty("FormaFarmaceutica")] + public string? FormaFarmaceutica { get; set; } = default!; + + /// + /// Condiciones especiales de transporte (refrigeración, frágil, etc.). + /// Opcional. + /// + [JsonProperty("CondicionesEspTransp")] + public string? CondicionesEspTransp { get; set; } = default!; + + /// + /// Registro sanitario o folio de autorización. + /// Opcional. + /// + [JsonProperty("RegistroSanitarioFolioAutorizacion")] + public string? RegistroSanitarioFolioAutorizacion { get; set; } = default!; + + /// + /// Número de permiso de importación. + /// Opcional. + /// + [JsonProperty("PermisoImportacion")] + public string? PermisoImportacion { get; set; } = default!; + + /// + /// Folio VUCEM de importación. + /// Opcional. + /// + [JsonProperty("FolioImpoVUCEM")] + public string? FolioImpoVUCEM { get; set; } = default!; + + /// + /// Número CAS para sustancias químicas. + /// Opcional. + /// + [JsonProperty("NumCAS")] + public string? NumCAS { get; set; } = default!; + + /// + /// Razón social de la empresa importadora. + /// Opcional. + /// + [JsonProperty("RazonSocialEmpImp")] + public string? RazonSocialEmpImp { get; set; } = default!; + + /// + /// Número de registro sanitario o plaguicida COFEPRIS. + /// Opcional. + /// + [JsonProperty("NumRegSanPlagCOFEPRIS")] + public string? NumRegSanPlagCOFEPRIS { get; set; } = default!; + + /// + /// Información adicional del fabricante. + /// Opcional. + /// + [JsonProperty("DatosFabricante")] + public string? DatosFabricante { get; set; } = default!; + + /// + /// Información del formulador del producto. + /// Opcional. + /// + [JsonProperty("DatosFormulador")] + public string? DatosFormulador { get; set; } = default!; + + /// + /// Información del maquilador (si aplica). + /// Opcional. + /// + [JsonProperty("DatosMaquilador")] + public string? DatosMaquilador { get; set; } = default!; + + /// + /// Uso autorizado del producto. + /// Opcional. + /// + [JsonProperty("UsoAutorizado")] + public string? UsoAutorizado { get; set; } = default!; + + /// + /// Peso en kilogramos de la mercancía (puede ser peso neto o bruto según contexto). + /// Requerido. + /// + [JsonProperty("PesoEnKg")] + public decimal PesoEnKg { get; set; } = default!; + + /// + /// Valor monetario de la mercancía. + /// Opcional. + /// + [JsonProperty("ValorMercancia")] + public decimal? ValorMercancia { get; set; } = default!; + + /// + /// Clave de moneda (c_Moneda) del valor de la mercancía. + /// Opcional. + /// + [JsonProperty("Moneda")] + public string? Moneda { get; set; } = default!; + + /// + /// Fracción arancelaria aplicable (c_FraccionArancelaria). + /// Opcional. + /// + [JsonProperty("FraccionArancelaria")] + public string? FraccionArancelaria { get; set; } = default!; + + /// + /// UUID asociado al complemento de Comercio Exterior relacionado. + /// Opcional. + /// + [JsonProperty("UUIDComercioExt")] + public string? UUIDComercioExt { get; set; } = default!; + + /// + /// Tipo de materia prima (si aplica para minerales, sustancias, etc.). + /// Opcional. + /// + [JsonProperty("TipoMateria")] + public string? TipoMateria { get; set; } = default!; + + /// + /// Descripción de la materia prima. + /// Opcional. + /// + [JsonProperty("DescripcionMateria")] + public string? DescripcionMateria { get; set; } = default!; + + /// + /// Documentos aduaneros asociados a la mercancía. + /// Opcional. + /// + [JsonProperty("DocumentacionAduanera")] + public List? DocumentacionAduanera { get; set; } = default!; + + /// + /// Guías de identificación asociadas. + /// Opcional. + /// + [JsonProperty("GuiasIdentificacion")] + public List? GuiasIdentificacion { get; set; } = default!; + + /// + /// Detalle de cantidades transportadas por origen/destino. + /// Opcional. + /// + [JsonProperty("CantidadTransporta")] + public List? CantidadTransporta { get; set; } = default!; + + /// + /// Detalle de pesos y piezas de la mercancía. + /// Opcional. + /// + [JsonProperty("DetalleMercancia")] + public List? DetalleMercancia { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteMercancias.cs b/Models/CartaPorteMercancias.cs new file mode 100644 index 0000000..74afc24 --- /dev/null +++ b/Models/CartaPorteMercancias.cs @@ -0,0 +1,94 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteMercancias + /// + public class CartaPorteMercancias + { + /// + /// Suma del peso bruto total de las mercancías (aéreo y ferroviario). + /// Requerido. + /// + [JsonProperty("PesoBrutoTotal")] + public decimal PesoBrutoTotal { get; set; } = default!; + + /// + /// Clave de unidad de medida estandarizada del peso (catCartaPorte:c_ClaveUnidadPeso). + /// Requerido. + /// + [JsonProperty("UnidadPeso")] + public string UnidadPeso { get; set; } = default!; + + /// + /// Suma de los valores PesoNeto de cada DetalleMercancia. + /// Opcional. + /// + [JsonProperty("PesoNetoTotal")] + public decimal? PesoNetoTotal { get; set; } = default!; + + /// + /// Número total de mercancías (cantidad de nodos Mercancia). + /// Requerido. + /// + [JsonProperty("NumTotalMercancias")] + public decimal NumTotalMercancias { get; set; } = default!; + + /// + /// Importe pagado por la tasación de las mercancías (vía aérea). + /// Opcional. + /// + [JsonProperty("CargoPorTasacion")] + public decimal? CargoPorTasacion { get; set; } = default!; + + /// + /// Indica si aplica logística inversa, recolección o devolución. + /// Opcional. + /// + [JsonProperty("LogisticaInversaRecoleccionDevolucion")] + public string? LogisticaInversaRecoleccionDevolucion { get; set; } = default!; + + /// + /// Arreglo requerido con las mercancías transportadas. + /// Requerido. + /// + [JsonProperty("Mercancia")] + public List Mercancia { get; set; } = default!; + + /// + /// Datos del autotransporte de carga federal. + /// Opcional. + /// + [JsonProperty("Autotransporte")] + public CartaPorteAutotransporte? Autotransporte { get; set; } = default!; + + /// + /// Datos de la embarcación para transporte marítimo. + /// Opcional. + /// + [JsonProperty("TransporteMaritimo")] + public CartaPorteTransporteMaritimo? TransporteMaritimo { get; set; } = default!; + + /// + /// Datos del transporte aéreo utilizado. + /// Opcional. + /// + [JsonProperty("TransporteAereo")] + public CartaPorteTransporteAereo? TransporteAereo { get; set; } = default!; + + /// + /// Datos del transporte ferroviario utilizado. + /// Opcional. + /// + [JsonProperty("TransporteFerroviario")] + public CartaPorteTransporteFerroviario? TransporteFerroviario { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteRemolque.cs b/Models/CartaPorteRemolque.cs new file mode 100644 index 0000000..174619a --- /dev/null +++ b/Models/CartaPorteRemolque.cs @@ -0,0 +1,31 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteRemolque + /// + public class CartaPorteRemolque + { + /// + /// Subtipo de remolque (catCartaPorte:c_SubTipoRem). + /// Opcional. + /// + [JsonProperty("SubTipoRem")] + public string? SubTipoRem { get; set; } = default!; + + /// + /// Placa del remolque. + /// Opcional. + /// + [JsonProperty("Placa")] + public string? Placa { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteSeguros.cs b/Models/CartaPorteSeguros.cs new file mode 100644 index 0000000..1e0ad3f --- /dev/null +++ b/Models/CartaPorteSeguros.cs @@ -0,0 +1,66 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteSeguros + /// + public class CartaPorteSeguros + { + /// + /// Nombre de la aseguradora de responsabilidad civil. + /// Requerido. + /// + [JsonProperty("AseguraRespCivil")] + public string AseguraRespCivil { get; set; } = default!; + + /// + /// Número de póliza de responsabilidad civil. + /// Requerido. + /// + [JsonProperty("PolizaRespCivil")] + public string PolizaRespCivil { get; set; } = default!; + + /// + /// Aseguradora contra daños al medio ambiente. + /// Opcional. + /// + [JsonProperty("AseguraMedAmbiente")] + public string? AseguraMedAmbiente { get; set; } = default!; + + /// + /// Número de póliza de medio ambiente. + /// Opcional. + /// + [JsonProperty("PolizaMedAmbiente")] + public string? PolizaMedAmbiente { get; set; } = default!; + + /// + /// Aseguradora de la carga. + /// Opcional. + /// + [JsonProperty("AseguraCarga")] + public string? AseguraCarga { get; set; } = default!; + + /// + /// Número de póliza de la carga. + /// Opcional. + /// + [JsonProperty("PolizaCarga")] + public string? PolizaCarga { get; set; } = default!; + + /// + /// Prima total de los seguros contratados. + /// Opcional. + /// + [JsonProperty("PrimaSeguro")] + public decimal? PrimaSeguro { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteTransporteAereo.cs b/Models/CartaPorteTransporteAereo.cs new file mode 100644 index 0000000..dabec06 --- /dev/null +++ b/Models/CartaPorteTransporteAereo.cs @@ -0,0 +1,101 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteTransporteAereo + /// + public class CartaPorteTransporteAereo + { + /// + /// Clave del permiso SCT para transporte aéreo. + /// Opcional. + /// + [JsonProperty("PermSCT")] + public string? PermSCT { get; set; } = default!; + + /// + /// Número de permiso SCT. + /// Opcional. + /// + [JsonProperty("NumPermisoSCT")] + public string? NumPermisoSCT { get; set; } = default!; + + /// + /// Matrícula de la aeronave. + /// Opcional. + /// + [JsonProperty("MatriculaAeronave")] + public string? MatriculaAeronave { get; set; } = default!; + + /// + /// Nombre de la aseguradora aérea. + /// Opcional. + /// + [JsonProperty("NombreAseg")] + public string? NombreAseg { get; set; } = default!; + + /// + /// Número de póliza de seguro de la aeronave. + /// Opcional. + /// + [JsonProperty("NumPolizaSeguro")] + public string? NumPolizaSeguro { get; set; } = default!; + + /// + /// Número de guía aérea (Air Waybill). + /// Opcional. + /// + [JsonProperty("NumeroGuia")] + public string? NumeroGuia { get; set; } = default!; + + /// + /// Lugar donde se celebró el contrato de transporte. + /// Opcional. + /// + [JsonProperty("LugarContrato")] + public string? LugarContrato { get; set; } = default!; + + /// + /// Código del transportista aéreo. + /// Opcional. + /// + [JsonProperty("CodigoTransportista")] + public string? CodigoTransportista { get; set; } = default!; + + /// + /// RFC del embarcador. + /// Opcional. + /// + [JsonProperty("RFCEmbarcador")] + public string? RFCEmbarcador { get; set; } = default!; + + /// + /// Número de registro tributario extranjero del embarcador. + /// Opcional. + /// + [JsonProperty("NumRegIdTribEmbarc")] + public string? NumRegIdTribEmbarc { get; set; } = default!; + + /// + /// País de residencia fiscal del embarcador. + /// Opcional. + /// + [JsonProperty("ResidenciaFiscalEmbarc")] + public string? ResidenciaFiscalEmbarc { get; set; } = default!; + + /// + /// Nombre o razón social del embarcador. + /// Opcional. + /// + [JsonProperty("NombreEmbarcador")] + public string? NombreEmbarcador { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteTransporteFerroviario.cs b/Models/CartaPorteTransporteFerroviario.cs new file mode 100644 index 0000000..46244e0 --- /dev/null +++ b/Models/CartaPorteTransporteFerroviario.cs @@ -0,0 +1,59 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteTransporteFerroviario + /// + public class CartaPorteTransporteFerroviario + { + /// + /// Tipo de servicio ferroviario (regular, intermodal, etc.). + /// Opcional. + /// + [JsonProperty("TipoDeServicio")] + public string? TipoDeServicio { get; set; } = default!; + + /// + /// Tipo de tráfico (nacional, internacional, etc.). + /// Opcional. + /// + [JsonProperty("TipoDeTrafico")] + public string? TipoDeTrafico { get; set; } = default!; + + /// + /// Nombre de la aseguradora ferroviaria. + /// Opcional. + /// + [JsonProperty("NombreAseg")] + public string? NombreAseg { get; set; } = default!; + + /// + /// Número de póliza de seguro ferroviario. + /// Opcional. + /// + [JsonProperty("NumPolizaSeguro")] + public string? NumPolizaSeguro { get; set; } = default!; + + /// + /// Lista de derechos de paso aplicados. + /// Opcional. + /// + [JsonProperty("DerechosDePaso")] + public List? DerechosDePaso { get; set; } = default!; + + /// + /// Lista de carros ferroviarios involucrados. + /// Opcional. + /// + [JsonProperty("Carro")] + public List? Carro { get; set; } = default!; + + } +} diff --git a/Models/CartaPorteTransporteMaritimo.cs b/Models/CartaPorteTransporteMaritimo.cs new file mode 100644 index 0000000..4a1d9f1 --- /dev/null +++ b/Models/CartaPorteTransporteMaritimo.cs @@ -0,0 +1,178 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteTransporteMaritimo + /// + public class CartaPorteTransporteMaritimo + { + /// + /// Clave del permiso SCT de la embarcación. + /// Requerido. + /// + [JsonProperty("PermSCT")] + public string PermSCT { get; set; } = default!; + + /// + /// Número de permiso SCT de la embarcación. + /// Requerido. + /// + [JsonProperty("NumPermisoSCT")] + public string NumPermisoSCT { get; set; } = default!; + + /// + /// Nombre de la aseguradora marítima. + /// Opcional. + /// + [JsonProperty("NombreAseg")] + public string? NombreAseg { get; set; } = default!; + + /// + /// Número de póliza de seguro marítimo. + /// Opcional. + /// + [JsonProperty("NumPolizaSeguro")] + public string? NumPolizaSeguro { get; set; } = default!; + + /// + /// Tipo de embarcación (catCartaPorte:c_TipoEmbarcacion). + /// Opcional. + /// + [JsonProperty("TipoEmbarcacion")] + public string? TipoEmbarcacion { get; set; } = default!; + + /// + /// Matrícula de la embarcación. + /// Opcional. + /// + [JsonProperty("Matricula")] + public string? Matricula { get; set; } = default!; + + /// + /// Número OMI (IMO number) de la embarcación. + /// Opcional. + /// + [JsonProperty("NumeroOMI")] + public string? NumeroOMI { get; set; } = default!; + + /// + /// Año de construcción de la embarcación. + /// Opcional. + /// + [JsonProperty("AnioEmbarcacion")] + public string? AnioEmbarcacion { get; set; } = default!; + + /// + /// Nombre propio de la embarcación. + /// Opcional. + /// + [JsonProperty("NombreEmbarc")] + public string? NombreEmbarc { get; set; } = default!; + + /// + /// Nacionalidad o bandera de la embarcación. + /// Opcional. + /// + [JsonProperty("NacionalidadEmbarc")] + public string? NacionalidadEmbarc { get; set; } = default!; + + /// + /// Toneladas de arqueo bruto. + /// Opcional. + /// + [JsonProperty("UnidadesDeArqBruto")] + public decimal? UnidadesDeArqBruto { get; set; } = default!; + + /// + /// Tipo de carga (granel, contenedores, líquidos, etc.). + /// Opcional. + /// + [JsonProperty("TipoCarga")] + public string? TipoCarga { get; set; } = default!; + + /// + /// Longitud total de la embarcación (eslora). + /// Opcional. + /// + [JsonProperty("Eslora")] + public decimal? Eslora { get; set; } = default!; + + /// + /// Ancho máximo de la embarcación (manga). + /// Opcional. + /// + [JsonProperty("Manga")] + public decimal? Manga { get; set; } = default!; + + /// + /// Calado máximo. + /// Opcional. + /// + [JsonProperty("Calado")] + public decimal? Calado { get; set; } = default!; + + /// + /// Altura del puntal. + /// Opcional. + /// + [JsonProperty("Puntal")] + public decimal? Puntal { get; set; } = default!; + + /// + /// Nombre de la línea naviera. + /// Opcional. + /// + [JsonProperty("LineaNaviera")] + public string? LineaNaviera { get; set; } = default!; + + /// + /// Nombre del agente naviero. + /// Opcional. + /// + [JsonProperty("NombreAgenteNaviero")] + public string? NombreAgenteNaviero { get; set; } = default!; + + /// + /// Número de autorización del agente naviero. + /// Opcional. + /// + [JsonProperty("NumAutorizacionNaviero")] + public string? NumAutorizacionNaviero { get; set; } = default!; + + /// + /// Número de viaje o rotación. + /// Opcional. + /// + [JsonProperty("NumViaje")] + public string? NumViaje { get; set; } = default!; + + /// + /// Número de conocimiento de embarque. + /// Opcional. + /// + [JsonProperty("NumConocEmbarc")] + public string? NumConocEmbarc { get; set; } = default!; + + /// + /// Permiso temporal de navegación. + /// Opcional. + /// + [JsonProperty("PermisoTempNavegacion")] + public string? PermisoTempNavegacion { get; set; } = default!; + + /// + /// Lista de contenedores asociados al embarque. + /// Opcional. + /// + [JsonProperty("Contenedor")] + public List? Contenedor { get; set; } = default!; + + } +} diff --git a/Models/CatalogItem.cs b/Models/CatalogItem.cs index 0e37fc1..df30cf6 100644 --- a/Models/CatalogItem.cs +++ b/Models/CatalogItem.cs @@ -1,9 +1,39 @@ -namespace Facturapi +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi { + /// + /// CatalogItem + /// public class CatalogItem { - public string Key { get; set; } - public string Description { get; set; } - public double Score { get; set; } + /// + /// Clave del catálogo + /// Opcional. + /// + [JsonProperty("key")] + public string? Key { get; set; } = default!; + + /// + /// Descripción de la entrada del catálogo + /// Opcional. + /// + [JsonProperty("description")] + public string? Description { get; set; } = default!; + + /// + /// Número del 0 al 1 que representa el nivel de coincidencia del + /// resultado con respecto a la consulta de búsqueda. + /// Opcional. + /// + [JsonProperty("score")] + public decimal? Score { get; set; } = default!; + } } diff --git a/Models/Certificate.cs b/Models/Certificate.cs index ca3be8e..635c43d 100644 --- a/Models/Certificate.cs +++ b/Models/Certificate.cs @@ -1,11 +1,47 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// Certificate + /// public class Certificate { - public DateTime UpdatedAt { get; set; } - public DateTime ExpiresAt { get; set; } - public bool HasCertificate { get; set; } + /// + /// Indica si la organización ya tiene el Certificado de Sello Digital (CSD) cargado. + /// Opcional. + /// + [JsonProperty("has_certificate")] + public bool? HasCertificate { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de la última actualización del certificado. Se omite cuando no hay un certificado cargado. + /// Opcional. + /// + [JsonProperty("updated_at")] + public DateTime? UpdatedAt { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de expiración del certificado. Se omite cuando no hay un certificado cargado. + /// Opcional. + /// + [JsonProperty("expires_at")] + public DateTime? ExpiresAt { get; set; } = default!; + + /// + /// Número de serie del certificado CSD. + /// Opcional. + /// + [JsonProperty("serial_number")] + public string? SerialNumber { get; set; } = default!; + } -} \ No newline at end of file +} diff --git a/Models/CheckApiHealthResponse.cs b/Models/CheckApiHealthResponse.cs new file mode 100644 index 0000000..c291d57 --- /dev/null +++ b/Models/CheckApiHealthResponse.cs @@ -0,0 +1,24 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CheckApiHealthResponse + /// + public class CheckApiHealthResponse + { + /// + /// ok + /// Opcional. + /// + [JsonProperty("ok")] + public bool? Ok { get; set; } = default!; + + } +} diff --git a/Models/ComercioExteriorDataProperties.cs b/Models/ComercioExteriorDataProperties.cs new file mode 100644 index 0000000..a8fac0f --- /dev/null +++ b/Models/ComercioExteriorDataProperties.cs @@ -0,0 +1,123 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorDataProperties + /// + public class ComercioExteriorDataProperties + { + /// + /// Receptor + /// Opcional. + /// + [JsonProperty("Receptor")] + public ComercioExteriorDataPropertiesReceptor? Receptor { get; set; } = default!; + + /// + /// Version + /// Valores: "2.0". + /// Opcional. + /// + [JsonProperty("Version")] + public string? Version { get; set; } = default!; + + /// + /// Clave del catálogo c_MotivoTraslado. + /// Opcional. + /// + [JsonProperty("MotivoTraslado")] + public string? MotivoTraslado { get; set; } = default!; + + /// + /// Clave del pedimento (catálogo c_ClavePedimento). + /// Requerido. + /// + [JsonProperty("ClaveDePedimento")] + public string ClaveDePedimento { get; set; } = default!; + + /// + /// Indica si existe certificado de origen. + /// Requerido. + /// + [JsonProperty("CertificadoOrigen")] + public int CertificadoOrigen { get; set; } = default!; + + /// + /// Número de certificado de origen. + /// Opcional. + /// + [JsonProperty("NumCertificadoOrigen")] + public string? NumCertificadoOrigen { get; set; } = default!; + + /// + /// Número de exportador confiable. + /// Opcional. + /// + [JsonProperty("NumeroExportadorConfiable")] + public string? NumeroExportadorConfiable { get; set; } = default!; + + /// + /// Clave del INCOTERM (catálogo c_INCOTERM). + /// Opcional. + /// + [JsonProperty("Incoterm")] + public string? Incoterm { get; set; } = default!; + + /// + /// Observaciones + /// Opcional. + /// + [JsonProperty("Observaciones")] + public string? Observaciones { get; set; } = default!; + + /// + /// Tipo de cambio USD. + /// Requerido. + /// + [JsonProperty("TipoCambioUSD")] + public decimal TipoCambioUSD { get; set; } = default!; + + /// + /// Total en USD. + /// Requerido. + /// + [JsonProperty("TotalUSD")] + public decimal TotalUSD { get; set; } = default!; + + /// + /// Objeto con información del emisor del complemento. Requerido cuando el domicilio y CURP del emisor no se toman de la organización que emite el complemento. + /// Opcional. + /// + [JsonProperty("Emisor")] + public OneOf? Emisor { get; set; } = default!; + + /// + /// Propietario + /// Opcional. + /// + [JsonProperty("Propietario")] + public List? Propietario { get; set; } = default!; + + /// + /// Destinatario + /// Opcional. + /// + [JsonProperty("Destinatario")] + public List? Destinatario { get; set; } = default!; + + /// + /// Mercancias + /// Requerido. + /// + [JsonProperty("Mercancias")] + public ComercioExteriorMercancias Mercancias { get; set; } = default!; + + } +} diff --git a/Models/ComercioExteriorDataPropertiesDestinatarioItem.cs b/Models/ComercioExteriorDataPropertiesDestinatarioItem.cs new file mode 100644 index 0000000..9943cac --- /dev/null +++ b/Models/ComercioExteriorDataPropertiesDestinatarioItem.cs @@ -0,0 +1,45 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorDataPropertiesDestinatarioItem + /// + public class ComercioExteriorDataPropertiesDestinatarioItem + { + /// + /// ID del objeto `customer` relacionado a la factura, en caso de no haber sido eliminado + /// Opcional. + /// + [JsonProperty("id")] + public string? Id { get; set; } = default!; + + /// + /// Domicilio + /// Opcional. + /// + [JsonProperty("Domicilio")] + public List? Domicilio { get; set; } = default!; + + /// + /// NumRegIdTrib + /// Opcional. + /// + [JsonProperty("NumRegIdTrib")] + public string? NumRegIdTrib { get; set; } = default!; + + /// + /// Nombre + /// Opcional. + /// + [JsonProperty("Nombre")] + public string? Nombre { get; set; } = default!; + + } +} diff --git a/Models/ComercioExteriorDataPropertiesPropietarioItem.cs b/Models/ComercioExteriorDataPropertiesPropietarioItem.cs new file mode 100644 index 0000000..15791d6 --- /dev/null +++ b/Models/ComercioExteriorDataPropertiesPropietarioItem.cs @@ -0,0 +1,38 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorDataPropertiesPropietarioItem + /// + public class ComercioExteriorDataPropertiesPropietarioItem + { + /// + /// NumRegIdTrib + /// Opcional. + /// + [JsonProperty("NumRegIdTrib")] + public string? NumRegIdTrib { get; set; } = default!; + + /// + /// Clave del catálogo c_Pais. + /// Opcional. + /// + [JsonProperty("ResidenciaFiscal")] + public string? ResidenciaFiscal { get; set; } = default!; + + /// + /// ID del objeto `customer` relacionado a la factura, en caso de no haber sido eliminado + /// Opcional. + /// + [JsonProperty("id")] + public string? Id { get; set; } = default!; + + } +} diff --git a/Models/ComercioExteriorDataPropertiesReceptor.cs b/Models/ComercioExteriorDataPropertiesReceptor.cs new file mode 100644 index 0000000..06e730a --- /dev/null +++ b/Models/ComercioExteriorDataPropertiesReceptor.cs @@ -0,0 +1,38 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorDataPropertiesReceptor + /// + public class ComercioExteriorDataPropertiesReceptor + { + /// + /// ID del objeto `customer` relacionado a la factura, en caso de no haber sido eliminado + /// Opcional. + /// + [JsonProperty("id")] + public string? Id { get; set; } = default!; + + /// + /// Domicilio + /// Opcional. + /// + [JsonProperty("Domicilio")] + public ComercioExteriorDomicilio? Domicilio { get; set; } = default!; + + /// + /// NumRegIdTrib + /// Opcional. + /// + [JsonProperty("NumRegIdTrib")] + public string? NumRegIdTrib { get; set; } = default!; + + } +} diff --git a/Models/ComercioExteriorDescripcionesEspecificas.cs b/Models/ComercioExteriorDescripcionesEspecificas.cs new file mode 100644 index 0000000..903b81e --- /dev/null +++ b/Models/ComercioExteriorDescripcionesEspecificas.cs @@ -0,0 +1,45 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorDescripcionesEspecificas + /// + public class ComercioExteriorDescripcionesEspecificas + { + /// + /// Marca + /// Requerido. + /// + [JsonProperty("Marca")] + public string Marca { get; set; } = default!; + + /// + /// Modelo + /// Opcional. + /// + [JsonProperty("Modelo")] + public string? Modelo { get; set; } = default!; + + /// + /// SubModelo + /// Opcional. + /// + [JsonProperty("SubModelo")] + public string? SubModelo { get; set; } = default!; + + /// + /// NumeroSerie + /// Opcional. + /// + [JsonProperty("NumeroSerie")] + public string? NumeroSerie { get; set; } = default!; + + } +} diff --git a/Models/ComercioExteriorDomicilio.cs b/Models/ComercioExteriorDomicilio.cs new file mode 100644 index 0000000..e0c29fb --- /dev/null +++ b/Models/ComercioExteriorDomicilio.cs @@ -0,0 +1,87 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorDomicilio + /// + public class ComercioExteriorDomicilio + { + /// + /// Calle + /// Requerido. + /// + [JsonProperty("Calle")] + public string Calle { get; set; } = default!; + + /// + /// NumeroExterior + /// Opcional. + /// + [JsonProperty("NumeroExterior")] + public string? NumeroExterior { get; set; } = default!; + + /// + /// NumeroInterior + /// Opcional. + /// + [JsonProperty("NumeroInterior")] + public string? NumeroInterior { get; set; } = default!; + + /// + /// Colonia + /// Opcional. + /// + [JsonProperty("Colonia")] + public string? Colonia { get; set; } = default!; + + /// + /// Localidad + /// Opcional. + /// + [JsonProperty("Localidad")] + public string? Localidad { get; set; } = default!; + + /// + /// Referencia + /// Opcional. + /// + [JsonProperty("Referencia")] + public string? Referencia { get; set; } = default!; + + /// + /// Municipio + /// Opcional. + /// + [JsonProperty("Municipio")] + public string? Municipio { get; set; } = default!; + + /// + /// Estado + /// Requerido. + /// + [JsonProperty("Estado")] + public string Estado { get; set; } = default!; + + /// + /// Clave del catálogo c_Pais. + /// Requerido. + /// + [JsonProperty("Pais")] + public string Pais { get; set; } = default!; + + /// + /// CodigoPostal + /// Requerido. + /// + [JsonProperty("CodigoPostal")] + public string CodigoPostal { get; set; } = default!; + + } +} diff --git a/Models/ComercioExteriorEmisor.cs b/Models/ComercioExteriorEmisor.cs new file mode 100644 index 0000000..1c98782 --- /dev/null +++ b/Models/ComercioExteriorEmisor.cs @@ -0,0 +1,31 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorEmisor + /// + public class ComercioExteriorEmisor + { + /// + /// Domicilio + /// Requerido. + /// + [JsonProperty("Domicilio")] + public ComercioExteriorDomicilio Domicilio { get; set; } = default!; + + /// + /// Curp + /// Opcional. + /// + [JsonProperty("Curp")] + public string? Curp { get; set; } = default!; + + } +} diff --git a/Models/ComercioExteriorMercancia.cs b/Models/ComercioExteriorMercancia.cs new file mode 100644 index 0000000..e720f83 --- /dev/null +++ b/Models/ComercioExteriorMercancia.cs @@ -0,0 +1,66 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorMercancia + /// + public class ComercioExteriorMercancia + { + /// + /// DescripcionesEspecificas + /// Opcional. + /// + [JsonProperty("DescripcionesEspecificas")] + public List? DescripcionesEspecificas { get; set; } = default!; + + /// + /// NoIdentificacion + /// Requerido. + /// + [JsonProperty("NoIdentificacion")] + public string NoIdentificacion { get; set; } = default!; + + /// + /// Clave del catálogo c_FraccionArancelaria. + /// Opcional. + /// + [JsonProperty("FraccionArancelaria")] + public string? FraccionArancelaria { get; set; } = default!; + + /// + /// CantidadAduana + /// Opcional. + /// + [JsonProperty("CantidadAduana")] + public decimal? CantidadAduana { get; set; } = default!; + + /// + /// Clave del catálogo c_UnidadAduana. + /// Opcional. + /// + [JsonProperty("UnidadAduana")] + public string? UnidadAduana { get; set; } = default!; + + /// + /// ValorUnitarioAduana + /// Opcional. + /// + [JsonProperty("ValorUnitarioAduana")] + public decimal? ValorUnitarioAduana { get; set; } = default!; + + /// + /// ValorDolares + /// Requerido. + /// + [JsonProperty("ValorDolares")] + public decimal ValorDolares { get; set; } = default!; + + } +} diff --git a/Models/ComercioExteriorMercancias.cs b/Models/ComercioExteriorMercancias.cs new file mode 100644 index 0000000..5ef52dc --- /dev/null +++ b/Models/ComercioExteriorMercancias.cs @@ -0,0 +1,24 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorMercancias + /// + public class ComercioExteriorMercancias + { + /// + /// Mercancia + /// Requerido. + /// + [JsonProperty("Mercancia")] + public List Mercancia { get; set; } = default!; + + } +} diff --git a/Models/CompletionStep.cs b/Models/CompletionStep.cs index 318031c..75129f3 100644 --- a/Models/CompletionStep.cs +++ b/Models/CompletionStep.cs @@ -1,8 +1,32 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + namespace Facturapi { + /// + /// CompletionStep + /// public class CompletionStep { - public string Type { get; set; } - public string Description { get; set; } + /// + /// Código que representa el tipo de paso que se requiere completar + /// Valores: "legal", "logo", "certificate", "manifiesto". + /// Opcional. + /// + [JsonProperty("type")] + public string? Type { get; set; } = default!; + + /// + /// Texto que describe el paso que se requiere completar y que puedes usar para mostrárselo al usuario. + /// Opcional. + /// + [JsonProperty("description")] + public string? Description { get; set; } = default!; + } } diff --git a/Models/CreateInvoiceResponse.cs b/Models/CreateInvoiceResponse.cs new file mode 100644 index 0000000..9eacaf6 --- /dev/null +++ b/Models/CreateInvoiceResponse.cs @@ -0,0 +1,366 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CreateInvoiceResponse + /// + public class CreateInvoiceResponse + { + /// + /// ID del objeto + /// Requerido. + /// + [JsonProperty("id")] + public string Id { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de registro + /// Requerido. + /// + [JsonProperty("created_at")] + public DateTime CreatedAt { get; set; } = default!; + + /// + /// Si el valor es `true`, indica que el objeto fue creado en ambiente Live; o si es `false`, en ambiente Test. + /// Requerido. + /// + [JsonProperty("livemode")] + public bool Livemode { get; set; } = default!; + + /// + /// Estado actual de la factura. `failed` indica que el timbrado en segundo plano o la recuperación automática del CFDI terminó sin éxito. + /// Valores: "pending". + /// Requerido. + /// + [JsonProperty("status")] + public string Status { get; set; } = default!; + + /// + /// cancellation + /// Opcional. + /// + [JsonProperty("cancellation")] + public InvoiceCancellation? Cancellation { get; set; } = default!; + + /// + /// cancellation_status + /// Valores: "none", "accepted", "pending", "rejected", "expired", "verifying". + /// Requerido. + /// + [JsonProperty("cancellation_status")] + public string CancellationStatus { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha en la que se canceló el CFDI con hora aproximada. + /// Opcional. + /// Admite null. + /// + [JsonProperty("canceled_at")] + public DateTime? CanceledAt { get; set; } = default!; + + /// + /// Format: uri + /// Dirección URL para verificar el estado del CFDI en el portal del SAT. Este link es el mismo que aparece en el código QR, en el PDF de la factura. + /// Opcional. + /// + [JsonProperty("verification_url")] + public string? VerificationUrl { get; set; } = default!; + + /// + /// address + /// Opcional. + /// + [JsonProperty("address")] + public Address? Address { get; set; } = default!; + + /// + /// Tipo de comprobante. Puede tener los valores `"I"`: Ingreso, `"P"`: Pago, `"E"`: Egreso, `"N"`: Nómina, `"T"`: Traslado. + /// Valores: "E", "I", "T", "N", "P". + /// Requerido. + /// + [JsonProperty("type")] + public string Type { get; set; } = default!; + + /// + /// customer + /// Opcional. + /// Admite null. + /// + [JsonProperty("customer")] + public CustomerInfo? Customer { get; set; } = default!; + + /// + /// Monto total facturado. + /// Requerido. + /// + [JsonProperty("total")] + public decimal Total { get; set; } = default!; + + /// + /// Número de folio autoincremental para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonProperty("folio_number")] + public int? FolioNumber { get; set; } = default!; + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. En el PDF se imprime junto al número de folio. + /// Opcional. + /// + [JsonProperty("series")] + public string? Series { get; set; } = default!; + + /// + /// Identificador que puedes usar para relacionar esta factura con tus registros para después buscar por este número. + /// Opcional. + /// + [JsonProperty("external_id")] + public string? ExternalId { get; set; } = default!; + + /// + /// Clave que identifica una operación para evitar recursos duplicados. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonProperty("idempotency_key")] + public string? IdempotencyKey { get; set; } = default!; + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Opcional. + /// Admite null. + /// + [JsonProperty("payment_form")] + public string? PaymentForm { get; set; } = default!; + + /// + /// Total del complemento de Pago cuando la factura es tipo P. + /// Opcional. + /// + [JsonProperty("total_payment_amount")] + public decimal? TotalPaymentAmount { get; set; } = default!; + + /// + /// Total del monto pagado convertido de la moneda de pago a Pesos Mexicanos. + /// Opcional. + /// + [JsonProperty("total_payment_amount_converted")] + public decimal? TotalPaymentAmountConverted { get; set; } = default!; + + /// + /// Este campo es asignado automáticamente por Facturapi. Indica si una factura + /// con status `draft` está completa y lista para intentar timbrarse. Si el valor es `true`, puedes + /// intentar timbrar la factura con el método [Timbrar Factura]('#/operation/stampInvoice'). + /// Si el valor es `false`, debes usar el método [Actualizar Factura]('#/operation/updateDraftInvoice') + /// para completar los campos faltantes. + /// + /// En una factura con status diferente a `draft`, este campo siempre será `false`. + /// Opcional. + /// + [JsonProperty("is_ready_to_stamp")] + public bool? IsReadyToStamp { get; set; } = default!; + + /// + /// Conceptos incluidos en el comprobante + /// Requerido. + /// + [JsonProperty("items")] + public List Items { get; set; } = default!; + + /// + /// Documentos relacionados con la factura. + /// Opcional. + /// + [JsonProperty("related_documents")] + public List? RelatedDocuments { get; set; } = default!; + + /// + /// En facturas con tipo I (Ingreso) y método de pago PPD, este campo lista los + /// IDs de los comprobantes de pago cuyo arreglo de documentos relacionados incluye el UUID + /// de esta factura. Este campo es llenado por Facturapi en el momento en que se crea o importa + /// el comprobante de pago (tipo P), siempre y cuando pertenezca a la misma organización. + /// Opcional. + /// + [JsonProperty("received_payment_ids")] + public List? ReceivedPaymentIds { get; set; } = default!; + + /// + /// En facturas con tipo P (Pago), este arreglo lista los IDs de los comprobantes de ingreso + /// listados en el arreglo de documentos relacionados. Este campo es llenado por Facturapi siempre + /// y cuando el comprobante relacionado también esté registrado en Facturapi y pertenezca a la misma organización. + /// Opcional. + /// + [JsonProperty("target_invoice_ids")] + public List? TargetInvoiceIds { get; set; } = default!; + + /// + /// Al recuperar el detalle de un CFDI de ingreso o egreso, este arreglo contiene los IDs de los + /// CFDI del tipo opuesto relacionados mediante `related_documents`. Para un ingreso incluye los + /// egresos que referencian su UUID; para un egreso incluye los ingresos cuyos UUID están en sus + /// documentos relacionados. Solo incluye CFDI registrados en la misma organización y ambiente. + /// Opcional. + /// + [JsonProperty("related_invoice_ids")] + public List? RelatedInvoiceIds { get; set; } = default!; + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Requerido. + /// + [JsonProperty("currency")] + public string Currency { get; set; } = default!; + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Requerido. + /// + [JsonProperty("exchange")] + public decimal Exchange { get; set; } = default!; + + /// + /// Complementos a incluir en la factura. + /// Opcional. + /// + [JsonProperty("complements")] + public List? Complements { get; set; } = default!; + + /// + /// Format: html + /// En caso de que necesites incluir más información en el PDF, este campo te permite insertar código HTML con tu propio contenido. + /// Opcional. + /// + [JsonProperty("pdf_custom_section")] + public string? PdfCustomSection { get; set; } = default!; + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonProperty("addenda")] + public string? Addenda { get; set; } = default!; + + /// + /// Namespaces a insertar en el nodo raíz de la factura. Requerido en `addenda`. + /// Opcional. + /// + [JsonProperty("namespaces")] + public List? Namespaces { get; set; } = default!; + + /// + /// ID de la organización a la que pertenece este recurso. + /// Opcional. + /// Admite null. + /// + [JsonProperty("organization")] + public string? Organization { get; set; } = default!; + + /// + /// issuer_type + /// Valores: "issuing", "receiving". + /// Opcional. + /// + [JsonProperty("issuer_type")] + public string? IssuerType { get; set; } = default!; + + /// + /// cfdi_version + /// Opcional. + /// + [JsonProperty("cfdi_version")] + public decimal? CfdiVersion { get; set; } = default!; + + /// + /// issuer_info + /// Opcional. + /// + [JsonProperty("issuer_info")] + public CustomerInfo? IssuerInfo { get; set; } = default!; + + /// + /// payment_method + /// Valores: "PUE", "PPD". + /// Opcional. + /// Admite null. + /// + [JsonProperty("payment_method")] + public string? PaymentMethod { get; set; } = default!; + + /// + /// use + /// Opcional. + /// + [JsonProperty("use")] + public string? Use { get; set; } = default!; + + /// + /// amount_due + /// Requerido. + /// + [JsonProperty("amount_due")] + public decimal AmountDue { get; set; } = default!; + + /// + /// Format: uri + /// Opcional. + /// + [JsonProperty("verification_carta_porte")] + public string? VerificationCartaPorte { get; set; } = default!; + + /// + /// conditions + /// Opcional. + /// + [JsonProperty("conditions")] + public string? Conditions { get; set; } = default!; + + /// + /// export + /// Opcional. + /// + [JsonProperty("export")] + public string? Export { get; set; } = default!; + + /// + /// global + /// Opcional. + /// + [JsonProperty("global")] + public Global? Global { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de expedición en formato ISO8601. Puede ser null en borradores. + /// Requerido. + /// Admite null. + /// + [JsonProperty("date")] + public DateTime? Date { get; set; } = default!; + + /// + /// Format: uuid + /// Folio fiscal de la factura, asignado por el SAT. En borradores sin timbrar puede ser null o estar omitido. + /// Opcional. + /// Admite null. + /// + [JsonProperty("uuid")] + public string? Uuid { get; set; } = default!; + + /// + /// stamp + /// Opcional. + /// Admite null. + /// + [JsonProperty("stamp")] + public Stamp? Stamp { get; set; } = default!; + + } +} diff --git a/Models/CreateToInvoiceFromReceiptsResponse.cs b/Models/CreateToInvoiceFromReceiptsResponse.cs new file mode 100644 index 0000000..6e35e2d --- /dev/null +++ b/Models/CreateToInvoiceFromReceiptsResponse.cs @@ -0,0 +1,403 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CreateToInvoiceFromReceiptsResponse + /// + public class CreateToInvoiceFromReceiptsResponse + { + /// + /// ID del objeto + /// Opcional. + /// + [JsonProperty("id")] + public string? Id { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de registro + /// Opcional. + /// + [JsonProperty("created_at")] + public DateTime? CreatedAt { get; set; } = default!; + + /// + /// Si el valor es `true`, indica que el objeto fue creado en ambiente Live; o si es `false`, en ambiente Test. + /// Opcional. + /// + [JsonProperty("livemode")] + public bool? Livemode { get; set; } = default!; + + /// + /// Estado actual de la factura. `failed` indica que el timbrado en segundo plano o la recuperación automática del CFDI terminó sin éxito. + /// Valores: "valid", "canceled", "draft", "pending", "failed". + /// Opcional. + /// + [JsonProperty("status")] + public string? Status { get; set; } = default!; + + /// + /// cancellation + /// Opcional. + /// + [JsonProperty("cancellation")] + public InvoiceCancellation? Cancellation { get; set; } = default!; + + /// + /// cancellation_status + /// Valores: "none", "accepted", "pending", "rejected", "expired", "verifying". + /// Opcional. + /// + [JsonProperty("cancellation_status")] + public string? CancellationStatus { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha en la que se canceló el CFDI con hora aproximada. + /// Opcional. + /// Admite null. + /// + [JsonProperty("canceled_at")] + public DateTime? CanceledAt { get; set; } = default!; + + /// + /// Format: uri + /// Dirección URL para verificar el estado del CFDI en el portal del SAT. Este link es el mismo que aparece en el código QR, en el PDF de la factura. + /// Opcional. + /// + [JsonProperty("verification_url")] + public string? VerificationUrl { get; set; } = default!; + + /// + /// address + /// Opcional. + /// + [JsonProperty("address")] + public Address? Address { get; set; } = default!; + + /// + /// Tipo de comprobante. Puede tener los valores `"I"`: Ingreso, `"P"`: Pago, `"E"`: Egreso, `"N"`: Nómina, `"T"`: Traslado. + /// Valores: "E", "I", "T", "N", "P". + /// Opcional. + /// + [JsonProperty("type")] + public string? Type { get; set; } = default!; + + /// + /// customer + /// Opcional. + /// Admite null. + /// + [JsonProperty("customer")] + public CustomerInfo? Customer { get; set; } = default!; + + /// + /// Monto total facturado. + /// Requerido. + /// + [JsonProperty("total")] + public decimal Total { get; set; } = default!; + + /// + /// Número de folio autoincremental para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonProperty("folio_number")] + public int? FolioNumber { get; set; } = default!; + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. En el PDF se imprime junto al número de folio. + /// Opcional. + /// + [JsonProperty("series")] + public string? Series { get; set; } = default!; + + /// + /// Identificador que puedes usar para relacionar esta factura con tus registros para después buscar por este número. + /// Opcional. + /// + [JsonProperty("external_id")] + public string? ExternalId { get; set; } = default!; + + /// + /// Clave que identifica una operación para evitar recursos duplicados. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonProperty("idempotency_key")] + public string? IdempotencyKey { get; set; } = default!; + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Opcional. + /// Admite null. + /// + [JsonProperty("payment_form")] + public string? PaymentForm { get; set; } = default!; + + /// + /// Total del complemento de Pago cuando la factura es tipo P. + /// Opcional. + /// + [JsonProperty("total_payment_amount")] + public decimal? TotalPaymentAmount { get; set; } = default!; + + /// + /// Total del monto pagado convertido de la moneda de pago a Pesos Mexicanos. + /// Opcional. + /// + [JsonProperty("total_payment_amount_converted")] + public decimal? TotalPaymentAmountConverted { get; set; } = default!; + + /// + /// Este campo es asignado automáticamente por Facturapi. Indica si una factura + /// con status `draft` está completa y lista para intentar timbrarse. Si el valor es `true`, puedes + /// intentar timbrar la factura con el método [Timbrar Factura]('#/operation/stampInvoice'). + /// Si el valor es `false`, debes usar el método [Actualizar Factura]('#/operation/updateDraftInvoice') + /// para completar los campos faltantes. + /// + /// En una factura con status diferente a `draft`, este campo siempre será `false`. + /// Opcional. + /// + [JsonProperty("is_ready_to_stamp")] + public bool? IsReadyToStamp { get; set; } = default!; + + /// + /// Conceptos incluidos en el comprobante + /// Opcional. + /// + [JsonProperty("items")] + public List? Items { get; set; } = default!; + + /// + /// Documentos relacionados con la factura. + /// Opcional. + /// + [JsonProperty("related_documents")] + public List? RelatedDocuments { get; set; } = default!; + + /// + /// En facturas con tipo I (Ingreso) y método de pago PPD, este campo lista los + /// IDs de los comprobantes de pago cuyo arreglo de documentos relacionados incluye el UUID + /// de esta factura. Este campo es llenado por Facturapi en el momento en que se crea o importa + /// el comprobante de pago (tipo P), siempre y cuando pertenezca a la misma organización. + /// Opcional. + /// + [JsonProperty("received_payment_ids")] + public List? ReceivedPaymentIds { get; set; } = default!; + + /// + /// En facturas con tipo P (Pago), este arreglo lista los IDs de los comprobantes de ingreso + /// listados en el arreglo de documentos relacionados. Este campo es llenado por Facturapi siempre + /// y cuando el comprobante relacionado también esté registrado en Facturapi y pertenezca a la misma organización. + /// Opcional. + /// + [JsonProperty("target_invoice_ids")] + public List? TargetInvoiceIds { get; set; } = default!; + + /// + /// Al recuperar el detalle de un CFDI de ingreso o egreso, este arreglo contiene los IDs de los + /// CFDI del tipo opuesto relacionados mediante `related_documents`. Para un ingreso incluye los + /// egresos que referencian su UUID; para un egreso incluye los ingresos cuyos UUID están en sus + /// documentos relacionados. Solo incluye CFDI registrados en la misma organización y ambiente. + /// Opcional. + /// + [JsonProperty("related_invoice_ids")] + public List? RelatedInvoiceIds { get; set; } = default!; + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonProperty("currency")] + public string? Currency { get; set; } = default!; + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Opcional. + /// + [JsonProperty("exchange")] + public decimal? Exchange { get; set; } = default!; + + /// + /// Complementos a incluir en la factura. + /// Opcional. + /// + [JsonProperty("complements")] + public List? Complements { get; set; } = default!; + + /// + /// Format: html + /// En caso de que necesites incluir más información en el PDF, este campo te permite insertar código HTML con tu propio contenido. + /// Opcional. + /// + [JsonProperty("pdf_custom_section")] + public string? PdfCustomSection { get; set; } = default!; + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonProperty("addenda")] + public string? Addenda { get; set; } = default!; + + /// + /// Namespaces a insertar en el nodo raíz de la factura. Requerido en `addenda`. + /// Opcional. + /// + [JsonProperty("namespaces")] + public List? Namespaces { get; set; } = default!; + + /// + /// ID de la organización a la que pertenece este recurso. + /// Opcional. + /// Admite null. + /// + [JsonProperty("organization")] + public string? Organization { get; set; } = default!; + + /// + /// issuer_type + /// Valores: "issuing", "receiving". + /// Opcional. + /// + [JsonProperty("issuer_type")] + public string? IssuerType { get; set; } = default!; + + /// + /// cfdi_version + /// Opcional. + /// + [JsonProperty("cfdi_version")] + public decimal? CfdiVersion { get; set; } = default!; + + /// + /// issuer_info + /// Opcional. + /// + [JsonProperty("issuer_info")] + public CustomerInfo? IssuerInfo { get; set; } = default!; + + /// + /// payment_method + /// Valores: "PUE", "PPD". + /// Opcional. + /// Admite null. + /// + [JsonProperty("payment_method")] + public string? PaymentMethod { get; set; } = default!; + + /// + /// use + /// Opcional. + /// + [JsonProperty("use")] + public string? Use { get; set; } = default!; + + /// + /// amount_due + /// Opcional. + /// + [JsonProperty("amount_due")] + public decimal? AmountDue { get; set; } = default!; + + /// + /// Format: uri + /// Opcional. + /// + [JsonProperty("verification_carta_porte")] + public string? VerificationCartaPorte { get; set; } = default!; + + /// + /// conditions + /// Opcional. + /// + [JsonProperty("conditions")] + public string? Conditions { get; set; } = default!; + + /// + /// export + /// Opcional. + /// + [JsonProperty("export")] + public string? Export { get; set; } = default!; + + /// + /// global + /// Opcional. + /// + [JsonProperty("global")] + public Global? Global { get; set; } = default!; + + /// + /// Format: date-time + /// Format: date-time + /// Fecha de expedición en formato ISO8601. Puede ser null en borradores. + /// Opcional. + /// Admite null. + /// + [JsonProperty("date")] + public DateTime? Date { get; set; } = default!; + + /// + /// Format: uuid + /// Format: uuid + /// Folio fiscal de la factura, asignado por el SAT. En borradores sin timbrar puede ser null o estar omitido. + /// Opcional. + /// Admite null. + /// + [JsonProperty("uuid")] + public string? Uuid { get; set; } = default!; + + /// + /// stamp + /// Opcional. + /// Admite null. + /// + [JsonProperty("stamp")] + public Stamp? Stamp { get; set; } = default!; + + /// + /// subtotal + /// Opcional. + /// + [JsonProperty("subtotal")] + public decimal? Subtotal { get; set; } = default!; + + /// + /// discount + /// Opcional. + /// + [JsonProperty("discount")] + public decimal? Discount { get; set; } = default!; + + /// + /// receipts + /// Opcional. + /// + [JsonProperty("receipts")] + public List? Receipts { get; set; } = default!; + + /// + /// item_count + /// Opcional. + /// + [JsonProperty("item_count")] + public int? ItemCount { get; set; } = default!; + + /// + /// taxes + /// Opcional. + /// + [JsonProperty("taxes")] + public CreateToInvoiceFromReceiptsResponseTaxes? Taxes { get; set; } = default!; + + } +} diff --git a/Models/CreateToInvoiceFromReceiptsResponseTaxes.cs b/Models/CreateToInvoiceFromReceiptsResponseTaxes.cs new file mode 100644 index 0000000..ffa8ecc --- /dev/null +++ b/Models/CreateToInvoiceFromReceiptsResponseTaxes.cs @@ -0,0 +1,73 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CreateToInvoiceFromReceiptsResponseTaxes + /// + public class CreateToInvoiceFromReceiptsResponseTaxes + { + /// + /// totalAdded + /// Requerido. + /// + [JsonProperty("totalAdded")] + public decimal TotalAdded { get; set; } = default!; + + /// + /// totalWithholding + /// Requerido. + /// + [JsonProperty("totalWithholding")] + public decimal TotalWithholding { get; set; } = default!; + + /// + /// localTotalAdded + /// Requerido. + /// + [JsonProperty("localTotalAdded")] + public decimal LocalTotalAdded { get; set; } = default!; + + /// + /// localTotalWithholding + /// Requerido. + /// + [JsonProperty("localTotalWithholding")] + public decimal LocalTotalWithholding { get; set; } = default!; + + /// + /// allAdded + /// Requerido. + /// + [JsonProperty("allAdded")] + public List AllAdded { get; set; } = default!; + + /// + /// allWithholding + /// Requerido. + /// + [JsonProperty("allWithholding")] + public List AllWithholding { get; set; } = default!; + + /// + /// localAllAdded + /// Requerido. + /// + [JsonProperty("localAllAdded")] + public List LocalAllAdded { get; set; } = default!; + + /// + /// localAllWithholding + /// Requerido. + /// + [JsonProperty("localAllWithholding")] + public List LocalAllWithholding { get; set; } = default!; + + } +} diff --git a/Models/Customer.cs b/Models/Customer.cs index 6e0193c..98d1a10 100644 --- a/Models/Customer.cs +++ b/Models/Customer.cs @@ -1,7 +1,10 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { @@ -15,7 +18,7 @@ public class Customer /// Requerido. /// [JsonProperty("id")] - public string Id { get; set; } + public string Id { get; set; } = default!; /// /// Format: date-time @@ -23,14 +26,14 @@ public class Customer /// Requerido. /// [JsonProperty("created_at")] - public DateTime CreatedAt { get; set; } + public DateTime CreatedAt { get; set; } = default!; /// /// Si el valor es `true`, indica que el objeto fue creado en ambiente Live; o si es `false`, en ambiente Test. /// Requerido. /// [JsonProperty("livemode")] - public bool Livemode { get; set; } + public bool Livemode { get; set; } = default!; /// /// Enlace a una página alojada donde el cliente puede editar su información una vez. @@ -39,7 +42,7 @@ public class Customer /// Admite null. /// [JsonProperty("edit_link")] - public string EditLink { get; set; } + public string? EditLink { get; set; } = default!; /// /// Format: date-time @@ -48,7 +51,7 @@ public class Customer /// Admite null. /// [JsonProperty("edit_link_expires_at")] - public DateTime? EditLinkExpiresAt { get; set; } + public DateTime? EditLinkExpiresAt { get; set; } = default!; /// /// Format: date-time @@ -57,7 +60,7 @@ public class Customer /// Admite null. /// [JsonProperty("sat_validated_at")] - public DateTime? SatValidatedAt { get; set; } + public DateTime? SatValidatedAt { get; set; } = default!; /// /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). @@ -65,7 +68,7 @@ public class Customer /// Admite null. /// [JsonProperty("legal_name")] - public string LegalName { get; set; } + public string? LegalName { get; set; } = default!; /// /// En clientes de México contiene el RFC del cliente. Para extranjeros es opcional y representa el número de registro de identificación tributaria, es decir, el equivalente al RFC en el país del cliente. @@ -73,7 +76,7 @@ public class Customer /// Admite null. /// [JsonProperty("tax_id")] - public string TaxId { get; set; } + public string? TaxId { get; set; } = default!; /// /// Requerido para clientes nacionales. Clave del régimen fiscal del cliente, del catálogo de [Regímenes Fiscales](https://docs.facturapi.io/api/#r%C3%A9gimen-fiscal). @@ -81,7 +84,7 @@ public class Customer /// Admite null. /// [JsonProperty("tax_system")] - public string TaxSystem { get; set; } + public string? TaxSystem { get; set; } = default!; /// /// Format: email @@ -90,7 +93,7 @@ public class Customer /// Admite null. /// [JsonProperty("email")] - public string Email { get; set; } + public string? Email { get; set; } = default!; /// /// Teléfono del cliente. @@ -98,14 +101,14 @@ public class Customer /// Admite null. /// [JsonProperty("phone")] - public string Phone { get; set; } + public string? Phone { get; set; } = default!; /// /// Uso de CFDI por defecto. /// Opcional. /// [JsonProperty("default_invoice_use")] - public string DefaultInvoiceUse { get; set; } + public string? DefaultInvoiceUse { get; set; } = default!; /// /// address @@ -113,28 +116,28 @@ public class Customer /// Admite null. /// [JsonProperty("address")] - public Address Address { get; set; } + public Address? Address { get; set; } = default!; /// /// ID de la organización a la que pertenece este recurso. /// Requerido. /// [JsonProperty("organization")] - public string Organization { get; set; } + public string Organization { get; set; } = default!; /// /// curp /// Opcional. /// [JsonProperty("curp")] - public string Curp { get; set; } + public string? Curp { get; set; } = default!; /// /// external_id /// Opcional. /// [JsonProperty("external_id")] - public string ExternalId { get; set; } + public string? ExternalId { get; set; } = default!; } } diff --git a/Models/CustomerEditLinkEmailResult.cs b/Models/CustomerEditLinkEmailResult.cs index 3417d33..75c1a25 100644 --- a/Models/CustomerEditLinkEmailResult.cs +++ b/Models/CustomerEditLinkEmailResult.cs @@ -1,7 +1,10 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { @@ -15,7 +18,7 @@ public class CustomerEditLinkEmailResult /// Opcional. /// [JsonProperty("ok")] - public bool? Ok { get; set; } + public bool? Ok { get; set; } = default!; } } diff --git a/Models/CustomerInfo.cs b/Models/CustomerInfo.cs new file mode 100644 index 0000000..765f3cf --- /dev/null +++ b/Models/CustomerInfo.cs @@ -0,0 +1,63 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Objeto con información parcial del cliente receptor del comprobante. Para obtener el objeto `Customer` completo, deberás consultarlo con el método de [Obtener Cliente]('#/operation/getCustomer'). + /// + public class CustomerInfo + { + /// + /// ID del objeto `customer` relacionado a la factura, en caso de no haber sido eliminado + /// Opcional. + /// + [JsonProperty("id")] + public string? Id { get; set; } = default!; + + /// + /// Nombre fiscal o razón social del cliente, *sin* incluir el régimen societario (ej.: S.A. de C.V.). + /// Opcional. + /// Admite null. + /// + [JsonProperty("legal_name")] + public string? LegalName { get; set; } = default!; + + /// + /// RFC del cliente. + /// Opcional. + /// Admite null. + /// + [JsonProperty("tax_id")] + public string? TaxId { get; set; } = default!; + + /// + /// address + /// Opcional. + /// + [JsonProperty("address")] + public Address? Address { get; set; } = default!; + + /// + /// phone + /// Opcional. + /// Admite null. + /// + [JsonProperty("phone")] + public string? Phone { get; set; } = default!; + + /// + /// tax_system + /// Opcional. + /// Admite null. + /// + [JsonProperty("tax_system")] + public string? TaxSystem { get; set; } = default!; + + } +} diff --git a/Models/Customization.cs b/Models/Customization.cs index c6563a3..9d42135 100644 --- a/Models/Customization.cs +++ b/Models/Customization.cs @@ -1,9 +1,60 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + namespace Facturapi { + /// + /// Customization + /// public class Customization { - public string Color { get; set; } - public bool HasLogo { get; set; } - public PdfExtra PdfExtra { get; set; } + /// + /// default_series + /// Opcional. + /// + [JsonProperty("default_series")] + public CustomizationDefaultSeries? DefaultSeries { get; set; } = default!; + + /// + /// Indica si la organización ya tiene un logotipo cargado. + /// Opcional. + /// + [JsonProperty("has_logo")] + public bool? HasLogo { get; set; } = default!; + + /// + /// Format: hex + /// Color distintivo de la marca en representación Hexadecimal RGB de 6 caracteres. + /// Opcional. + /// + [JsonProperty("color")] + public string? Color { get; set; } = default!; + + /// + /// Número de folio que se asignará a la siguiente factura en ambiente Live (y que se incrementará automáticamente por cada nueva factura). + /// Opcional. + /// + [JsonProperty("next_folio_number")] + public int? NextFolioNumber { get; set; } = default!; + + /// + /// Número de folio que se asignará a la siguiente factura en ambiente Test (y que se incrementará automáticamente por cada nueva factura). + /// Opcional. + /// + [JsonProperty("next_folio_number_test")] + public int? NextFolioNumberTest { get; set; } = default!; + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia de la organización. + /// Opcional. + /// + [JsonProperty("pdf_extra")] + public CustomizationPdfExtra? PdfExtra { get; set; } = default!; + } -} \ No newline at end of file +} diff --git a/Models/CustomizationDefaultSeries.cs b/Models/CustomizationDefaultSeries.cs new file mode 100644 index 0000000..9ed779e --- /dev/null +++ b/Models/CustomizationDefaultSeries.cs @@ -0,0 +1,52 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CustomizationDefaultSeries + /// + public class CustomizationDefaultSeries + { + /// + /// I + /// Opcional. + /// + [JsonProperty("I")] + public string? I { get; set; } = default!; + + /// + /// E + /// Opcional. + /// + [JsonProperty("E")] + public string? E { get; set; } = default!; + + /// + /// P + /// Opcional. + /// + [JsonProperty("P")] + public string? P { get; set; } = default!; + + /// + /// N + /// Opcional. + /// + [JsonProperty("N")] + public string? N { get; set; } = default!; + + /// + /// T + /// Opcional. + /// + [JsonProperty("T")] + public string? T { get; set; } = default!; + + } +} diff --git a/Models/CustomizationPdfExtra.cs b/Models/CustomizationPdfExtra.cs new file mode 100644 index 0000000..348815b --- /dev/null +++ b/Models/CustomizationPdfExtra.cs @@ -0,0 +1,122 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CustomizationPdfExtra + /// + public class CustomizationPdfExtra + { + /// + /// Mostrar códigos de catálogos del SAT junto a sus descripciones. Ejemplo: “KGM Kilogramo”. + /// Opcional. + /// + [JsonProperty("codes")] + public bool? Codes { get; set; } = default!; + + /// + /// Mostrar los códigos estandarizados de estado y de país en el PDF. Ejemplo: "SON" en lugar de "Sonora" y "MEX" en lugar de "México". + /// Opcional. + /// + [JsonProperty("address_codes")] + public bool? AddressCodes { get; set; } = default!; + + /// + /// Mostrar la clave de producto-servicio. + /// Opcional. + /// + [JsonProperty("product_key")] + public bool? ProductKey { get; set; } = default!; + + /// + /// Mostrar la clave de exportación en el PDF. + /// Opcional. + /// + [JsonProperty("export_key")] + public bool? ExportKey { get; set; } = default!; + + /// + /// Redondear el precio unitario en el PDF a 2 decimales, pero conservar los 6 decimales en el XML. + /// Opcional. + /// + [JsonProperty("round_unit_price")] + public bool? RoundUnitPrice { get; set; } = default!; + + /// + /// Mostrar el desglose de impuestos en el PDF. Si se desactiva, sólo se mostratán los impuestos en los totales, pero no en el detalle de cada concepto. + /// Opcional. + /// + [JsonProperty("tax_breakdown")] + public bool? TaxBreakdown { get; set; } = default!; + + /// + /// Mostrar el desglose de IEPS en el PDF. Si se desactiva, solo se mostrarán los impuestos relacionados al IVA en el subtotal. + /// Opcional. + /// + [JsonProperty("ieps_breakdown")] + public bool? IepsBreakdown { get; set; } = default!; + + /// + /// Suma IEPS con subtotal sin desglosarlo en el PDF. + /// Opcional. + /// + [JsonProperty("combine_ieps_with_subtotal")] + public bool? CombineIepsWithSubtotal { get; set; } = default!; + + /// + /// Renderizar el complemento de Carta Porte 3.1 en el PDF sólo si el complemento de carta porte está incluido en la factura. + /// Opcional. + /// + [JsonProperty("render_carta_porte")] + public bool? RenderCartaPorte { get; set; } = default!; + + /// + /// Repetir la firma electrónica en cada página del PDF. Si se desactiva, la firma electrónica sólo se mostrará una vez. + /// Opcional. + /// + [JsonProperty("repeat_signature")] + public bool? RepeatSignature { get; set; } = default!; + + /// + /// Mostrar el domicilio fiscal de la organización en vez del lugar de expedición de la factura. Solo se muestra una dirección. + /// Opcional. + /// + [JsonProperty("render_organization_address")] + public bool? RenderOrganizationAddress { get; set; } = default!; + + /// + /// Renderizar el complemento de Instituciones Educativas Privadas en el PDF. + /// Opcional. + /// + [JsonProperty("render_iedu")] + public bool? RenderIedu { get; set; } = default!; + + /// + /// Renderizar el complemento de hidrocarburos y petrolíferos en el PDF. + /// Opcional. + /// + [JsonProperty("render_hyp_complement")] + public bool? RenderHypComplement { get; set; } = default!; + + /// + /// Renderizar el complemento de comercio exterior en el PDF. + /// Opcional. + /// + [JsonProperty("render_comercio_exterior")] + public bool? RenderComercioExterior { get; set; } = default!; + + /// + /// payroll_options + /// Opcional. + /// + [JsonProperty("payroll_options")] + public CustomizationPdfExtraPayrollOptions? PayrollOptions { get; set; } = default!; + + } +} diff --git a/Models/CustomizationPdfExtraPayrollOptions.cs b/Models/CustomizationPdfExtraPayrollOptions.cs new file mode 100644 index 0000000..c6070a2 --- /dev/null +++ b/Models/CustomizationPdfExtraPayrollOptions.cs @@ -0,0 +1,45 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CustomizationPdfExtraPayrollOptions + /// + public class CustomizationPdfExtraPayrollOptions + { + /// + /// tipo_contrato + /// Opcional. + /// + [JsonProperty("tipo_contrato")] + public bool? TipoContrato { get; set; } = default!; + + /// + /// puesto + /// Opcional. + /// + [JsonProperty("puesto")] + public bool? Puesto { get; set; } = default!; + + /// + /// riesgo_puesto + /// Opcional. + /// + [JsonProperty("riesgo_puesto")] + public bool? RiesgoPuesto { get; set; } = default!; + + /// + /// antiguedad + /// Opcional. + /// + [JsonProperty("antiguedad")] + public bool? Antiguedad { get; set; } = default!; + + } +} diff --git a/Models/DomainAvailability.cs b/Models/DomainAvailability.cs index 13d93cc..d9b12b7 100644 --- a/Models/DomainAvailability.cs +++ b/Models/DomainAvailability.cs @@ -1,7 +1,24 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + namespace Facturapi { + /// + /// DomainAvailability + /// public class DomainAvailability { - public bool Available { get; set; } + /// + /// Indica si el dominio está diponible + /// Requerido. + /// + [JsonProperty("available")] + public bool Available { get; set; } = default!; + } } diff --git a/Models/Efos.cs b/Models/Efos.cs new file mode 100644 index 0000000..1a7b5d3 --- /dev/null +++ b/Models/Efos.cs @@ -0,0 +1,35 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Efos + /// + public class Efos + { + /// + /// Indica si el RFC tiene algún asunto relacionado con esta lista. + /// `true`: El RFC no está en la lista de EFOS o su situación fue + /// apelada y resultó favorable. `false`: El RFC está registrado como + /// “Presunto” o “Definitivo” en la lista de EFOS. + /// Opcional. + /// + [JsonProperty("is_valid")] + public bool? IsValid { get; set; } = default!; + + /// + /// Objeto con el resultado de la búqueda ante el SAT. + /// Toda la información contenida en este objeto proviene del SAT. + /// Opcional. + /// + [JsonProperty("data")] + public EfosData? Data { get; set; } = default!; + + } +} diff --git a/Models/EfosData.cs b/Models/EfosData.cs new file mode 100644 index 0000000..b562726 --- /dev/null +++ b/Models/EfosData.cs @@ -0,0 +1,39 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// EfosData + /// + public class EfosData + { + /// + /// Disponible sólo cuando el RFC no fue encontrado en la lista, + /// lo cual es bueno. + /// Opcional. + /// + [JsonProperty("mensaje")] + public string? Mensaje { get; set; } = default!; + + /// + /// Texto que indica la fecha de actualización de la lista. + /// Opcional. + /// + [JsonProperty("fechaLista")] + public string? FechaLista { get; set; } = default!; + + /// + /// Arreglo con los resultados de la búsqueda en la lista de EFOS. + /// Opcional. + /// + [JsonProperty("detalles")] + public List? Detalles { get; set; } = default!; + + } +} diff --git a/Models/EfosDetalle.cs b/Models/EfosDetalle.cs new file mode 100644 index 0000000..91b4048 --- /dev/null +++ b/Models/EfosDetalle.cs @@ -0,0 +1,100 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// EfosDetalle + /// + public class EfosDetalle + { + /// + /// El RFC consultado, a manera de confirmación. + /// Opcional. + /// + [JsonProperty("rfc")] + public string? Rfc { get; set; } = default!; + + /// + /// Razón social del contribuyente. + /// Opcional. + /// + [JsonProperty("razonSocial")] + public string? RazonSocial { get; set; } = default!; + + /// + /// Texto que indica la situación actual. Consulta + /// [esta tabla](https://docs.facturapi.io/api/#situación-del-contribuyente) para ver + /// el detalle de los distintos valores. + /// Opcional. + /// + [JsonProperty("situacionContribuyente")] + public string? SituacionContribuyente { get; set; } = default!; + + /// + /// Texto con identificador y fecha del reporte de presunción. + /// Opcional. + /// + [JsonProperty("numFechaPresuncion")] + public string? NumFechaPresuncion { get; set; } = default!; + + /// + /// Format: DD/MM/YYYY + /// Fecha de publicación de presunción. + /// Opcional. + /// + [JsonProperty("pubFechaSatPresuntos")] + public string? PubFechaSatPresuntos { get; set; } = default!; + + /// + /// Texto con identificador y fecha de publicación en el listado global de presunción. + /// Opcional. + /// + [JsonProperty("numGlobalPresuncion")] + public string? NumGlobalPresuncion { get; set; } = default!; + + /// + /// Format: DD/MM/YYYY + /// Fecha de publicación en el Diario Oficial de la Federación (DOF). + /// Opcional. + /// + [JsonProperty("pubFechaDofPresuntos")] + public string? PubFechaDofPresuntos { get; set; } = default!; + + /// + /// Identificador de la publicación de estado “Definitivo”. + /// Opcional. + /// + [JsonProperty("pubSatDefinitivos")] + public string? PubSatDefinitivos { get; set; } = default!; + + /// + /// Format: DD/MM/YYYY + /// Fecha de la publicación de estado “Definitivo” en el DOF. + /// Opcional. + /// + [JsonProperty("pubDofDefinitivos")] + public string? PubDofDefinitivos { get; set; } = default!; + + /// + /// Texto con identificador y fecha de sentencia favorable. + /// Opcional. + /// + [JsonProperty("numFechaSentFav")] + public string? NumFechaSentFav { get; set; } = default!; + + /// + /// Format: DD/MM/YYYY + /// Fecha de sentencia favorable + /// Opcional. + /// + [JsonProperty("pubSatSentFav")] + public string? PubSatSentFav { get; set; } = default!; + + } +} diff --git a/Models/ErrorDetail.cs b/Models/ErrorDetail.cs new file mode 100644 index 0000000..2e43d22 --- /dev/null +++ b/Models/ErrorDetail.cs @@ -0,0 +1,54 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ErrorDetail + /// + public class ErrorDetail + { + /// + /// Mensaje legible del detalle. + /// Requerido. + /// + [JsonProperty("message")] + public string Message { get; set; } = default!; + + /// + /// Subcódigo del detalle. En validaciones de Facturapi usa códigos como `required`, `invalid_type` o `tax_id_not_found`; en errores externos puede contener el código original del proveedor. + /// Requerido. + /// + [JsonProperty("code")] + public string Code { get; set; } = default!; + + /// + /// Ubicación opcional del dato relacionado con este detalle. + /// Valores: "body", "query", "params", "headers", "files". + /// Opcional. + /// + [JsonProperty("location")] + public string? Location { get; set; } = default!; + + /// + /// Ruta opcional del campo relacionado con este detalle. + /// Opcional. + /// + [JsonProperty("path")] + public string? Path { get; set; } = default!; + + /// + /// Fuente del detalle. + /// Valores: "facturapi", "sat", "pac". + /// Requerido. + /// + [JsonProperty("source")] + public string Source { get; set; } = default!; + + } +} diff --git a/Models/FielCertificate.cs b/Models/FielCertificate.cs new file mode 100644 index 0000000..2892748 --- /dev/null +++ b/Models/FielCertificate.cs @@ -0,0 +1,47 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// FielCertificate + /// + public class FielCertificate + { + /// + /// Indica si la organización ya tiene el Certificado FIEL cargado. + /// Opcional. + /// + [JsonProperty("has_certificate")] + public bool? HasCertificate { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de la última actualización del certificado FIEL. Se omite cuando no hay un certificado cargado. + /// Opcional. + /// + [JsonProperty("updated_at")] + public DateTime? UpdatedAt { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de expiración del certificado FIEL. Se omite cuando no hay un certificado cargado. + /// Opcional. + /// + [JsonProperty("expires_at")] + public DateTime? ExpiresAt { get; set; } = default!; + + /// + /// Número de serie del certificado FIEL. + /// Opcional. + /// + [JsonProperty("serial_number")] + public string? SerialNumber { get; set; } = default!; + + } +} diff --git a/Models/GenericError.cs b/Models/GenericError.cs new file mode 100644 index 0000000..7df1cee --- /dev/null +++ b/Models/GenericError.cs @@ -0,0 +1,70 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// GenericError + /// + public class GenericError + { + /// + /// Descripción del error + /// Indica qué salió mal y puede incluir una sugerencia sobre cómo solucionar el error. + /// Requerido. + /// + [JsonProperty("message")] + public string Message { get; set; } = default!; + + /// + /// Código de estado HTTP + /// Format: int32 + /// Código de estado HTTP de esta respuesta de error. + /// Requerido. + /// + [JsonProperty("status")] + public int Status { get; set; } = default!; + + /// + /// Indica si la petición fue exitosa. Siempre `false` en respuestas de error. + /// Requerido. + /// + [JsonProperty("ok")] + public bool Ok { get; set; } = default!; + + /// + /// Código de error estable para manejar el error de forma programática. Consulta la guía de manejo de errores para ver la lista de códigos documentados. + /// Requerido. + /// + [JsonProperty("code")] + public string Code { get; set; } = default!; + + /// + /// Ubicación opcional del dato relacionado con el error. + /// Valores: "body", "query", "params", "headers", "files". + /// Opcional. + /// + [JsonProperty("location")] + public string? Location { get; set; } = default!; + + /// + /// Ruta opcional del campo relacionado con el error. + /// Opcional. + /// + [JsonProperty("path")] + public string? Path { get; set; } = default!; + + /// + /// Detalles adicionales del error. Sólo se incluye cuando aporta información útil. + /// Opcional. + /// + [JsonProperty("errors")] + public List? Errors { get; set; } = default!; + + } +} diff --git a/Models/Global.cs b/Models/Global.cs index bbc23f7..2dc267d 100644 --- a/Models/Global.cs +++ b/Models/Global.cs @@ -1,12 +1,39 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// Global + /// public class Global { - public string Periodicity { get; set; } - public string Months { get; set; } - public int Year { get; set; } + /// + /// periodicity + /// Valores: "day", "week", "fortnight", "month", "two_months". + /// Requerido. + /// + [JsonProperty("periodicity")] + public string Periodicity { get; set; } = default!; + + /// + /// months + /// Requerido. + /// + [JsonProperty("months")] + public string Months { get; set; } = default!; + + /// + /// year + /// Requerido. + /// + [JsonProperty("year")] + public int Year { get; set; } = default!; + } } diff --git a/Models/HidroYPetroComplement.cs b/Models/HidroYPetroComplement.cs new file mode 100644 index 0000000..f5095e8 --- /dev/null +++ b/Models/HidroYPetroComplement.cs @@ -0,0 +1,50 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// HidroYPetroComplement + /// + public class HidroYPetroComplement + { + /// + /// Tipo de permiso otorgado por la autoridad competente, conforme al [Catálogo Hidrocarburos Petrolíferos](https://docs.facturapi.io/api/#cat%C3%A1logos-hidrocarburos-petrol%C3%ADferos). + /// Valores: "PER01", "PER02", "PER03", "PER04", "PER05", "PER06", "PER07", "PER08", "PER09", "PER10", "PER11". + /// Opcional. + /// + [JsonProperty("tipo_permiso")] + public string? TipoPermiso { get; set; } = default!; + + /// + /// Número de permiso otorgado por la autoridad competente, conforme a la nomenclatura del catálogo c_TipoPermiso. + /// Opcional. + /// + [JsonProperty("numero_permiso")] + public string? NumeroPermiso { get; set; } = default!; + + /// + /// Subtipo del hidrocarburo o petrolífero, conforme al [Catálogo Hidrocarburos Petrolíferos](https://docs.facturapi.io/api/#cat%C3%A1logos-hidrocarburos-petrol%C3%ADferos). + /// Valores: "SP16", "SP17", "SP18", "SP19", "SP22", "SP23", "SP24", "SP25", "SP48". + /// Opcional. + /// + [JsonProperty("sub_producto_hyp")] + public string? SubProductoHyp { get; set; } = default!; + + /// + /// Clave correspondiente a hidrocarburos y petrolíferos, conforme al [Catálogo Hidrocarburos Petrolíferos](https://docs.facturapi.io/api/#cat%C3%A1logos-hidrocarburos-petrol%C3%ADferos). + /// + /// Puedes enviarla explícitamente o dejar que Facturapi la derive desde el `product_key` del concepto cuando aplique. + /// Valores: "15101514", "15101515", "15101505". + /// Opcional. + /// + [JsonProperty("clave_hyp")] + public string? ClaveHyp { get; set; } = default!; + + } +} diff --git a/Models/IeduComplement.cs b/Models/IeduComplement.cs new file mode 100644 index 0000000..3d8bcdb --- /dev/null +++ b/Models/IeduComplement.cs @@ -0,0 +1,56 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Complemento concepto de Instituciones Educativas Privadas versión 1.0. + /// + /// Se incluye a nivel concepto dentro de `items[].complement`. + /// + /// + public class IeduComplement + { + /// + /// Nombre del alumno. + /// Opcional. + /// + [JsonProperty("nombreAlumno")] + public string? NombreAlumno { get; set; } = default!; + + /// + /// CURP del alumno de la institución educativa. + /// Opcional. + /// + [JsonProperty("CURP")] + public string? CURP { get; set; } = default!; + + /// + /// Nivel educativo que cursa el alumno. + /// Valores: "Preescolar", "Primaria", "Secundaria", "Profesional técnico", "Bachillerato o su equivalente". + /// Opcional. + /// + [JsonProperty("nivelEducativo")] + public string? NivelEducativo { get; set; } = default!; + + /// + /// Clave del centro de trabajo o reconocimiento de validez oficial de estudios de la institución educativa privada donde se realiza el pago. + /// Opcional. + /// + [JsonProperty("autRVOE")] + public string? AutRVOE { get; set; } = default!; + + /// + /// RFC de quien realiza el pago cuando sea diferente a quien recibe el servicio. + /// Opcional. + /// + [JsonProperty("rfcPago")] + public string? RfcPago { get; set; } = default!; + + } +} diff --git a/Models/Inputs/CancellationQueryInput.cs b/Models/Inputs/CancellationQueryInput.cs new file mode 100644 index 0000000..cb6ebfc --- /dev/null +++ b/Models/Inputs/CancellationQueryInput.cs @@ -0,0 +1,42 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Omite los parámetros para eliminar un borrador. Los documentos emitidos requieren motivo; los motivos 01 y 04 también requieren substitution. + /// + public class CancellationQueryInput : Dictionary + { + /// + /// motive + /// Valores: "01", "04", "02", "03". + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Motive + { + get => TryGetValue("motive", out var value) ? (string?)value! : default!; + set => this["motive"] = value; + } + + /// + /// ID de Facturapi o UUID del documento sustituto. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Substitution + { + get => TryGetValue("substitution", out var value) ? (string?)value! : default!; + set => this["substitution"] = value; + } + + } +} diff --git a/Models/Inputs/CancellationWithSubstitutionInput.cs b/Models/Inputs/CancellationWithSubstitutionInput.cs new file mode 100644 index 0000000..e77c298 --- /dev/null +++ b/Models/Inputs/CancellationWithSubstitutionInput.cs @@ -0,0 +1,51 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Omite los parámetros para eliminar un borrador. Los documentos emitidos requieren motivo; los motivos 01 y 04 también requieren substitution. + /// + public class CancellationWithSubstitutionInput : CancellationQueryInput + { + /// + /// Crea CancellationWithSubstitutionInput. + /// + /// motive Valores: "01", "04". Requerido. + /// ID de Facturapi o UUID del documento sustituto. Requerido. + public CancellationWithSubstitutionInput(string @motive, string @substitution) : base() + { + this["motive"] = @motive; + this["substitution"] = @substitution; + } + + /// + /// motive + /// Valores: "01", "04". + /// Requerido. + /// + [JsonIgnore] + public new string Motive + { + get => TryGetValue("motive", out var value) ? (string)value! : default!; + set => this["motive"] = value; + } + + /// + /// ID de Facturapi o UUID del documento sustituto. + /// Requerido. + /// + [JsonIgnore] + public new string Substitution + { + get => TryGetValue("substitution", out var value) ? (string)value! : default!; + set => this["substitution"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteAutotransporteInput.cs b/Models/Inputs/CartaPorteAutotransporteInput.cs new file mode 100644 index 0000000..78172a0 --- /dev/null +++ b/Models/Inputs/CartaPorteAutotransporteInput.cs @@ -0,0 +1,87 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteAutotransporteInput + /// + public class CartaPorteAutotransporteInput : Dictionary + { + /// + /// Crea CartaPorteAutotransporteInput. + /// + /// Clave del permiso SCT del autotransporte. Requerido. + /// Número del permiso SCT. Requerido. + /// Datos de identificación del vehículo principal. Requerido. + /// Información de seguros aplicables. Requerido. + public CartaPorteAutotransporteInput(string @permSCT, string @numPermisoSCT, CartaPorteIdentificacionVehicularInput @identificacionVehicular, CartaPorteSegurosInput @seguros) + { + this["PermSCT"] = @permSCT; + this["NumPermisoSCT"] = @numPermisoSCT; + this["IdentificacionVehicular"] = @identificacionVehicular; + this["Seguros"] = @seguros; + } + + /// + /// Clave del permiso SCT del autotransporte. + /// Requerido. + /// + [JsonIgnore] + public string PermSCT + { + get => TryGetValue("PermSCT", out var value) ? (string)value! : default!; + set => this["PermSCT"] = value; + } + + /// + /// Número del permiso SCT. + /// Requerido. + /// + [JsonIgnore] + public string NumPermisoSCT + { + get => TryGetValue("NumPermisoSCT", out var value) ? (string)value! : default!; + set => this["NumPermisoSCT"] = value; + } + + /// + /// Datos de identificación del vehículo principal. + /// Requerido. + /// + [JsonIgnore] + public CartaPorteIdentificacionVehicularInput IdentificacionVehicular + { + get => TryGetValue("IdentificacionVehicular", out var value) ? (CartaPorteIdentificacionVehicularInput)value! : default!; + set => this["IdentificacionVehicular"] = value; + } + + /// + /// Información de seguros aplicables. + /// Requerido. + /// + [JsonIgnore] + public CartaPorteSegurosInput Seguros + { + get => TryGetValue("Seguros", out var value) ? (CartaPorteSegurosInput)value! : default!; + set => this["Seguros"] = value; + } + + /// + /// Lista de remolques acoplados. + /// Opcional. + /// + [JsonIgnore] + public List? Remolques + { + get => TryGetValue("Remolques", out var value) ? (List?)value! : default!; + set => this["Remolques"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteCantidadTransportaInput.cs b/Models/Inputs/CartaPorteCantidadTransportaInput.cs new file mode 100644 index 0000000..532100c --- /dev/null +++ b/Models/Inputs/CartaPorteCantidadTransportaInput.cs @@ -0,0 +1,74 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteCantidadTransportaInput + /// + public class CartaPorteCantidadTransportaInput : Dictionary + { + /// + /// Crea CartaPorteCantidadTransportaInput. + /// + /// Cantidad Requerido. + /// IDOrigen Requerido. + /// IDDestino Requerido. + public CartaPorteCantidadTransportaInput(decimal @cantidad, string @iDOrigen, string @iDDestino) + { + this["Cantidad"] = @cantidad; + this["IDOrigen"] = @iDOrigen; + this["IDDestino"] = @iDDestino; + } + + /// + /// Cantidad + /// Requerido. + /// + [JsonIgnore] + public decimal Cantidad + { + get => TryGetValue("Cantidad", out var value) ? (decimal)value! : default!; + set => this["Cantidad"] = value; + } + + /// + /// IDOrigen + /// Requerido. + /// + [JsonIgnore] + public string IDOrigen + { + get => TryGetValue("IDOrigen", out var value) ? (string)value! : default!; + set => this["IDOrigen"] = value; + } + + /// + /// IDDestino + /// Requerido. + /// + [JsonIgnore] + public string IDDestino + { + get => TryGetValue("IDDestino", out var value) ? (string)value! : default!; + set => this["IDDestino"] = value; + } + + /// + /// Clave del medio de transporte. + /// Opcional. + /// + [JsonIgnore] + public string? CvesTransporte + { + get => TryGetValue("CvesTransporte", out var value) ? (string?)value! : default!; + set => this["CvesTransporte"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteCarroFerroviarioInput.cs b/Models/Inputs/CartaPorteCarroFerroviarioInput.cs new file mode 100644 index 0000000..8a26e5d --- /dev/null +++ b/Models/Inputs/CartaPorteCarroFerroviarioInput.cs @@ -0,0 +1,72 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteCarroFerroviarioInput + /// + public class CartaPorteCarroFerroviarioInput : Dictionary + { + /// + /// Tipo de carro ferroviario. + /// Opcional. + /// + [JsonIgnore] + public string? TipoCarro + { + get => TryGetValue("TipoCarro", out var value) ? (string?)value! : default!; + set => this["TipoCarro"] = value; + } + + /// + /// Matrícula o número identificador del carro. + /// Opcional. + /// + [JsonIgnore] + public string? MatriculaCarro + { + get => TryGetValue("MatriculaCarro", out var value) ? (string?)value! : default!; + set => this["MatriculaCarro"] = value; + } + + /// + /// Número de guía asociado al carro. + /// Opcional. + /// + [JsonIgnore] + public string? GuiaCarro + { + get => TryGetValue("GuiaCarro", out var value) ? (string?)value! : default!; + set => this["GuiaCarro"] = value; + } + + /// + /// Toneladas netas transportadas en el carro. + /// Opcional. + /// + [JsonIgnore] + public decimal? ToneladasNetasCarro + { + get => TryGetValue("ToneladasNetasCarro", out var value) ? (decimal?)value! : default!; + set => this["ToneladasNetasCarro"] = value; + } + + /// + /// Contenedores asociados al carro. + /// Opcional. + /// + [JsonIgnore] + public List? Contenedor + { + get => TryGetValue("Contenedor", out var value) ? (List?)value! : default!; + set => this["Contenedor"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteContenedorFerroviarioInput.cs b/Models/Inputs/CartaPorteContenedorFerroviarioInput.cs new file mode 100644 index 0000000..9479806 --- /dev/null +++ b/Models/Inputs/CartaPorteContenedorFerroviarioInput.cs @@ -0,0 +1,50 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteContenedorFerroviarioInput + /// + public class CartaPorteContenedorFerroviarioInput : Dictionary + { + /// + /// Tipo de contenedor ferroviario. + /// Opcional. + /// + [JsonIgnore] + public string? TipoContenedor + { + get => TryGetValue("TipoContenedor", out var value) ? (string?)value! : default!; + set => this["TipoContenedor"] = value; + } + + /// + /// Peso del contenedor vacío. + /// Opcional. + /// + [JsonIgnore] + public decimal? PesoContenedorVacio + { + get => TryGetValue("PesoContenedorVacio", out var value) ? (decimal?)value! : default!; + set => this["PesoContenedorVacio"] = value; + } + + /// + /// Peso neto de la mercancía contenida. + /// Opcional. + /// + [JsonIgnore] + public decimal? PesoNetoMercancia + { + get => TryGetValue("PesoNetoMercancia", out var value) ? (decimal?)value! : default!; + set => this["PesoNetoMercancia"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteContenedorMaritimoInput.cs b/Models/Inputs/CartaPorteContenedorMaritimoInput.cs new file mode 100644 index 0000000..5de03af --- /dev/null +++ b/Models/Inputs/CartaPorteContenedorMaritimoInput.cs @@ -0,0 +1,94 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteContenedorMaritimoInput + /// + public class CartaPorteContenedorMaritimoInput : Dictionary + { + /// + /// Tipo de contenedor marítimo (ISO / catálogo SAT). + /// Opcional. + /// + [JsonIgnore] + public string? TipoContenedor + { + get => TryGetValue("TipoContenedor", out var value) ? (string?)value! : default!; + set => this["TipoContenedor"] = value; + } + + /// + /// Matrícula o número identificador del contenedor. + /// Opcional. + /// + [JsonIgnore] + public string? MatriculaContenedor + { + get => TryGetValue("MatriculaContenedor", out var value) ? (string?)value! : default!; + set => this["MatriculaContenedor"] = value; + } + + /// + /// Número de precinto o sello de seguridad. + /// Opcional. + /// + [JsonIgnore] + public string? NumPrecinto + { + get => TryGetValue("NumPrecinto", out var value) ? (string?)value! : default!; + set => this["NumPrecinto"] = value; + } + + /// + /// Identificador CCP relacionado cuando se reutiliza información. + /// Opcional. + /// + [JsonIgnore] + public string? IdCCPRelacionado + { + get => TryGetValue("IdCCPRelacionado", out var value) ? (string?)value! : default!; + set => this["IdCCPRelacionado"] = value; + } + + /// + /// Placa del vehículo motor asociado (si aplica en transbordo). + /// Opcional. + /// + [JsonIgnore] + public string? PlacaVMCCP + { + get => TryGetValue("PlacaVMCCP", out var value) ? (string?)value! : default!; + set => this["PlacaVMCCP"] = value; + } + + /// + /// Fecha de certificación CCP del contenedor. + /// Opcional. + /// + [JsonIgnore] + public string? FechaCertificacionCCP + { + get => TryGetValue("FechaCertificacionCCP", out var value) ? (string?)value! : default!; + set => this["FechaCertificacionCCP"] = value; + } + + /// + /// RemolquesCCP + /// Opcional. + /// + [JsonIgnore] + public List? RemolquesCCP + { + get => TryGetValue("RemolquesCCP", out var value) ? (List?)value! : default!; + set => this["RemolquesCCP"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteContenedorMaritimoInputRemolquesCCPItem.cs b/Models/Inputs/CartaPorteContenedorMaritimoInputRemolquesCCPItem.cs new file mode 100644 index 0000000..94e4c16 --- /dev/null +++ b/Models/Inputs/CartaPorteContenedorMaritimoInputRemolquesCCPItem.cs @@ -0,0 +1,39 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteContenedorMaritimoInputRemolquesCCPItem + /// + public class CartaPorteContenedorMaritimoInputRemolquesCCPItem : Dictionary + { + /// + /// Subtipo de remolque relacionado (CCP). + /// Opcional. + /// + [JsonIgnore] + public string? SubTipoRemCCP + { + get => TryGetValue("SubTipoRemCCP", out var value) ? (string?)value! : default!; + set => this["SubTipoRemCCP"] = value; + } + + /// + /// Placa del remolque relacionado (CCP). + /// Opcional. + /// + [JsonIgnore] + public string? PlacaCCP + { + get => TryGetValue("PlacaCCP", out var value) ? (string?)value! : default!; + set => this["PlacaCCP"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteDataPropertiesInput.cs b/Models/Inputs/CartaPorteDataPropertiesInput.cs new file mode 100644 index 0000000..d69ba0c --- /dev/null +++ b/Models/Inputs/CartaPorteDataPropertiesInput.cs @@ -0,0 +1,175 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Complemento Carta Porte versión 3.1. (Beta) + /// + public class CartaPorteDataPropertiesInput : Dictionary + { + /// + /// Crea CartaPorteDataPropertiesInput. + /// + /// Identificador único de la Carta Porte. Requerido. + /// Indica si el transporte es internacional. Requerido. + /// Arreglo de ubicaciones. Requerido. + /// Mercancias Requerido. + public CartaPorteDataPropertiesInput(string @idCCP, string @transpInternac, List @ubicaciones, CartaPorteMercanciasInput @mercancias) + { + this["IdCCP"] = @idCCP; + this["TranspInternac"] = @transpInternac; + this["Ubicaciones"] = @ubicaciones; + this["Mercancias"] = @mercancias; + } + + /// + /// Identificador único de la Carta Porte. + /// Requerido. + /// + [JsonIgnore] + public string IdCCP + { + get => TryGetValue("IdCCP", out var value) ? (string)value! : default!; + set => this["IdCCP"] = value; + } + + /// + /// Indica si el transporte es internacional. + /// Requerido. + /// + [JsonIgnore] + public string TranspInternac + { + get => TryGetValue("TranspInternac", out var value) ? (string)value! : default!; + set => this["TranspInternac"] = value; + } + + /// + /// Entrada o salida de mercancías. + /// Opcional. + /// + [JsonIgnore] + public string? EntradaSalidaMerc + { + get => TryGetValue("EntradaSalidaMerc", out var value) ? (string?)value! : default!; + set => this["EntradaSalidaMerc"] = value; + } + + /// + /// País de origen o destino. + /// Opcional. + /// + [JsonIgnore] + public string? PaisOrigenDestino + { + get => TryGetValue("PaisOrigenDestino", out var value) ? (string?)value! : default!; + set => this["PaisOrigenDestino"] = value; + } + + /// + /// Vía de entrada o salida. + /// Opcional. + /// + [JsonIgnore] + public string? ViaEntradaSalida + { + get => TryGetValue("ViaEntradaSalida", out var value) ? (string?)value! : default!; + set => this["ViaEntradaSalida"] = value; + } + + /// + /// Distancia total recorrida. + /// Opcional. + /// + [JsonIgnore] + public decimal? TotalDistRec + { + get => TryGetValue("TotalDistRec", out var value) ? (decimal?)value! : default!; + set => this["TotalDistRec"] = value; + } + + /// + /// Registro del programa ISTMO. + /// Opcional. + /// + [JsonIgnore] + public string? RegistroISTMO + { + get => TryGetValue("RegistroISTMO", out var value) ? (string?)value! : default!; + set => this["RegistroISTMO"] = value; + } + + /// + /// Polo origen. + /// Opcional. + /// + [JsonIgnore] + public string? UbicacionPoloOrigen + { + get => TryGetValue("UbicacionPoloOrigen", out var value) ? (string?)value! : default!; + set => this["UbicacionPoloOrigen"] = value; + } + + /// + /// Polo destino. + /// Opcional. + /// + [JsonIgnore] + public string? UbicacionPoloDestino + { + get => TryGetValue("UbicacionPoloDestino", out var value) ? (string?)value! : default!; + set => this["UbicacionPoloDestino"] = value; + } + + /// + /// Objeto con los regímenes aduaneros aplicables. + /// Opcional. + /// + [JsonIgnore] + public Dictionary? RegimenesAduaneros + { + get => TryGetValue("RegimenesAduaneros", out var value) ? (Dictionary?)value! : default!; + set => this["RegimenesAduaneros"] = value; + } + + /// + /// Arreglo de ubicaciones. + /// Requerido. + /// + [JsonIgnore] + public List Ubicaciones + { + get => TryGetValue("Ubicaciones", out var value) ? (List)value! : default!; + set => this["Ubicaciones"] = value; + } + + /// + /// Mercancias + /// Requerido. + /// + [JsonIgnore] + public CartaPorteMercanciasInput Mercancias + { + get => TryGetValue("Mercancias", out var value) ? (CartaPorteMercanciasInput)value! : default!; + set => this["Mercancias"] = value; + } + + /// + /// Figuras de transporte. + /// Opcional. + /// + [JsonIgnore] + public List? FiguraTransporte + { + get => TryGetValue("FiguraTransporte", out var value) ? (List?)value! : default!; + set => this["FiguraTransporte"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteDataPropertiesInputFiguraTransporteItem.cs b/Models/Inputs/CartaPorteDataPropertiesInputFiguraTransporteItem.cs new file mode 100644 index 0000000..64c3059 --- /dev/null +++ b/Models/Inputs/CartaPorteDataPropertiesInputFiguraTransporteItem.cs @@ -0,0 +1,116 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteDataPropertiesInputFiguraTransporteItem + /// + public class CartaPorteDataPropertiesInputFiguraTransporteItem : Dictionary + { + /// + /// Crea CartaPorteDataPropertiesInputFiguraTransporteItem. + /// + /// Atributo requerido. Clave que identifica el tipo de figura de transporte conforme al catálogo correspondiente (operador, propietario, arrendatario, notificado). Debe coincidir con c_TipoFigura. Requerido. + /// Nombre o razón social de la figura de transporte (requerido). Requerido. + public CartaPorteDataPropertiesInputFiguraTransporteItem(string @tipoFigura, string @nombreFigura) + { + this["TipoFigura"] = @tipoFigura; + this["NombreFigura"] = @nombreFigura; + } + + /// + /// Atributo requerido. Clave que identifica el tipo de figura de transporte conforme al catálogo correspondiente (operador, propietario, arrendatario, notificado). Debe coincidir con c_TipoFigura. + /// Requerido. + /// + [JsonIgnore] + public string TipoFigura + { + get => TryGetValue("TipoFigura", out var value) ? (string)value! : default!; + set => this["TipoFigura"] = value; + } + + /// + /// RFC del operador/propietario/arrendatario o figura interveniente. + /// Opcional. + /// + [JsonIgnore] + public string? RFCFigura + { + get => TryGetValue("RFCFigura", out var value) ? (string?)value! : default!; + set => this["RFCFigura"] = value; + } + + /// + /// Número de licencia del operador cuando TipoFigura corresponde a operador. + /// Opcional. + /// + [JsonIgnore] + public string? NumLicencia + { + get => TryGetValue("NumLicencia", out var value) ? (string?)value! : default!; + set => this["NumLicencia"] = value; + } + + /// + /// Nombre o razón social de la figura de transporte (requerido). + /// Requerido. + /// + [JsonIgnore] + public string NombreFigura + { + get => TryGetValue("NombreFigura", out var value) ? (string)value! : default!; + set => this["NombreFigura"] = value; + } + + /// + /// Número de registro fiscal en el extranjero de la figura cuando aplica. + /// Opcional. + /// + [JsonIgnore] + public string? NumRegIdTribFigura + { + get => TryGetValue("NumRegIdTribFigura", out var value) ? (string?)value! : default!; + set => this["NumRegIdTribFigura"] = value; + } + + /// + /// Clave del país de residencia fiscal de la figura (c_Pais) cuando es extranjero. + /// Opcional. + /// + [JsonIgnore] + public string? ResidenciaFiscalFigura + { + get => TryGetValue("ResidenciaFiscalFigura", out var value) ? (string?)value! : default!; + set => this["ResidenciaFiscalFigura"] = value; + } + + /// + /// Arreglo opcional con las partes del transporte que se relacionan a la figura. + /// Opcional. + /// + [JsonIgnore] + public List? PartesTransporte + { + get => TryGetValue("PartesTransporte", out var value) ? (List?)value! : default!; + set => this["PartesTransporte"] = value; + } + + /// + /// Domicilio asociado a la figura del transporte. + /// Opcional. + /// + [JsonIgnore] + public CartaPorteDomicilioInput? Domicilio + { + get => TryGetValue("Domicilio", out var value) ? (CartaPorteDomicilioInput?)value! : default!; + set => this["Domicilio"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteDataPropertiesInputFiguraTransporteItemPartesTransporteItem.cs b/Models/Inputs/CartaPorteDataPropertiesInputFiguraTransporteItemPartesTransporteItem.cs new file mode 100644 index 0000000..5f7f869 --- /dev/null +++ b/Models/Inputs/CartaPorteDataPropertiesInputFiguraTransporteItemPartesTransporteItem.cs @@ -0,0 +1,37 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteDataPropertiesInputFiguraTransporteItemPartesTransporteItem + /// + public class CartaPorteDataPropertiesInputFiguraTransporteItemPartesTransporteItem : Dictionary + { + /// + /// Crea CartaPorteDataPropertiesInputFiguraTransporteItemPartesTransporteItem. + /// + /// Clave de la parte del transporte conforme al catálogo c_ParteTransporte. Requerido. + public CartaPorteDataPropertiesInputFiguraTransporteItemPartesTransporteItem(string @parteTransporte) + { + this["ParteTransporte"] = @parteTransporte; + } + + /// + /// Clave de la parte del transporte conforme al catálogo c_ParteTransporte. + /// Requerido. + /// + [JsonIgnore] + public string ParteTransporte + { + get => TryGetValue("ParteTransporte", out var value) ? (string)value! : default!; + set => this["ParteTransporte"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteDataPropertiesInputUbicacionesItem.cs b/Models/Inputs/CartaPorteDataPropertiesInputUbicacionesItem.cs new file mode 100644 index 0000000..31e194e --- /dev/null +++ b/Models/Inputs/CartaPorteDataPropertiesInputUbicacionesItem.cs @@ -0,0 +1,173 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteDataPropertiesInputUbicacionesItem + /// + public class CartaPorteDataPropertiesInputUbicacionesItem : Dictionary + { + /// + /// Crea CartaPorteDataPropertiesInputUbicacionesItem. + /// + /// Atributo requerido para precisar si el tipo de ubicación corresponde al origen o destino de las ubicaciones para el traslado de los bienes y/o mercancías en los distintos medios de transporte. Valores: "Origen" | "Destino". Requerido. + /// Atributo requerido para registrar el RFC del remitente o destinatario de los bienes y/o mercancías que se trasladan. Requerido. + /// Atributo requerido para registrar la fecha y hora estimada de salida o llegada en formato AAAA-MM-DDThh:mm:ss. Requerido. + public CartaPorteDataPropertiesInputUbicacionesItem(string @tipoUbicacion, string @rFCRemitenteDestinatario, string @fechaHoraSalidaLlegada) + { + this["TipoUbicacion"] = @tipoUbicacion; + this["RFCRemitenteDestinatario"] = @rFCRemitenteDestinatario; + this["FechaHoraSalidaLlegada"] = @fechaHoraSalidaLlegada; + } + + /// + /// Atributo requerido para precisar si el tipo de ubicación corresponde al origen o destino de las ubicaciones para el traslado de los bienes y/o mercancías en los distintos medios de transporte. Valores: "Origen" | "Destino". + /// Requerido. + /// + [JsonIgnore] + public string TipoUbicacion + { + get => TryGetValue("TipoUbicacion", out var value) ? (string)value! : default!; + set => this["TipoUbicacion"] = value; + } + + /// + /// Atributo condicional para registrar una clave que identifique el punto de salida o entrada de los bienes y/o mercancías. Formato: "OR" o "DE" seguido de 6 dígitos numéricos (expresión regular (OR|DE)[0-9]{6}). + /// Opcional. + /// + [JsonIgnore] + public string? IDUbicacion + { + get => TryGetValue("IDUbicacion", out var value) ? (string?)value! : default!; + set => this["IDUbicacion"] = value; + } + + /// + /// Atributo requerido para registrar el RFC del remitente o destinatario de los bienes y/o mercancías que se trasladan. + /// Requerido. + /// + [JsonIgnore] + public string RFCRemitenteDestinatario + { + get => TryGetValue("RFCRemitenteDestinatario", out var value) ? (string)value! : default!; + set => this["RFCRemitenteDestinatario"] = value; + } + + /// + /// Atributo opcional para registrar el nombre del remitente o destinatario de los bienes y/o mercancías (longitud 1 a 254 caracteres). + /// Opcional. + /// + [JsonIgnore] + public string? NombreRemitenteDestinatario + { + get => TryGetValue("NombreRemitenteDestinatario", out var value) ? (string?)value! : default!; + set => this["NombreRemitenteDestinatario"] = value; + } + + /// + /// Atributo condicional para el número de identificación o registro fiscal del país de residencia del remitente o destinatario cuando se trate de residentes en el extranjero (longitud 6 a 40 caracteres). + /// Opcional. + /// + [JsonIgnore] + public string? NumRegIdTrib + { + get => TryGetValue("NumRegIdTrib", out var value) ? (string?)value! : default!; + set => this["NumRegIdTrib"] = value; + } + + /// + /// Atributo condicional para registrar la clave del país de residencia fiscal conforme al catálogo c_Pais (ISO 3166-1). + /// Opcional. + /// + [JsonIgnore] + public string? ResidenciaFiscal + { + get => TryGetValue("ResidenciaFiscal", out var value) ? (string?)value! : default!; + set => this["ResidenciaFiscal"] = value; + } + + /// + /// Atributo condicional para la clave de la estación de origen o destino conforme al catálogo c_Estaciones del complemento Carta Porte y al tipo de transporte. + /// Opcional. + /// + [JsonIgnore] + public string? NumEstacion + { + get => TryGetValue("NumEstacion", out var value) ? (string?)value! : default!; + set => this["NumEstacion"] = value; + } + + /// + /// Atributo condicional para el nombre de la estación de origen o destino conforme al catálogo c_Estaciones (longitud 1 a 50 caracteres). + /// Opcional. + /// + [JsonIgnore] + public string? NombreEstacion + { + get => TryGetValue("NombreEstacion", out var value) ? (string?)value! : default!; + set => this["NombreEstacion"] = value; + } + + /// + /// Atributo condicional para registrar el tipo de puerto de origen o destino en transporte marítimo. Valores: "Altura" | "Cabotaje". + /// Opcional. + /// + [JsonIgnore] + public string? NavegacionTrafico + { + get => TryGetValue("NavegacionTrafico", out var value) ? (string?)value! : default!; + set => this["NavegacionTrafico"] = value; + } + + /// + /// Atributo requerido para registrar la fecha y hora estimada de salida o llegada en formato AAAA-MM-DDThh:mm:ss. + /// Requerido. + /// + [JsonIgnore] + public string FechaHoraSalidaLlegada + { + get => TryGetValue("FechaHoraSalidaLlegada", out var value) ? (string)value! : default!; + set => this["FechaHoraSalidaLlegada"] = value; + } + + /// + /// Atributo condicional para registrar el tipo de estación por la que pasan las mercancías conforme al catálogo c_TipoEstacion. + /// Opcional. + /// + [JsonIgnore] + public string? TipoEstacion + { + get => TryGetValue("TipoEstacion", out var value) ? (string?)value! : default!; + set => this["TipoEstacion"] = value; + } + + /// + /// Atributo condicional para registrar en kilómetros la distancia recorrida entre la ubicación de origen y la de destino parcial o final. + /// Opcional. + /// + [JsonIgnore] + public decimal? DistanciaRecorrida + { + get => TryGetValue("DistanciaRecorrida", out var value) ? (decimal?)value! : default!; + set => this["DistanciaRecorrida"] = value; + } + + /// + /// Domicilio + /// Opcional. + /// + [JsonIgnore] + public CartaPorteDomicilioInput? Domicilio + { + get => TryGetValue("Domicilio", out var value) ? (CartaPorteDomicilioInput?)value! : default!; + set => this["Domicilio"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteDerechosDePasoInput.cs b/Models/Inputs/CartaPorteDerechosDePasoInput.cs new file mode 100644 index 0000000..25b4499 --- /dev/null +++ b/Models/Inputs/CartaPorteDerechosDePasoInput.cs @@ -0,0 +1,39 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteDerechosDePasoInput + /// + public class CartaPorteDerechosDePasoInput : Dictionary + { + /// + /// Tipo de derecho de paso ferroviario. + /// Opcional. + /// + [JsonIgnore] + public string? TipoDerechoDePaso + { + get => TryGetValue("TipoDerechoDePaso", out var value) ? (string?)value! : default!; + set => this["TipoDerechoDePaso"] = value; + } + + /// + /// Kilometraje cubierto/pagado en el derecho de paso. + /// Opcional. + /// + [JsonIgnore] + public decimal? KilometrajePagado + { + get => TryGetValue("KilometrajePagado", out var value) ? (decimal?)value! : default!; + set => this["KilometrajePagado"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteDetalleMercanciaInput.cs b/Models/Inputs/CartaPorteDetalleMercanciaInput.cs new file mode 100644 index 0000000..1f75704 --- /dev/null +++ b/Models/Inputs/CartaPorteDetalleMercanciaInput.cs @@ -0,0 +1,87 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteDetalleMercanciaInput + /// + public class CartaPorteDetalleMercanciaInput : Dictionary + { + /// + /// Crea CartaPorteDetalleMercanciaInput. + /// + /// Clave de la unidad de peso de la mercancía conforme al catálogo correspondiente. Requerido. + /// Peso bruto de la mercancía incluyendo embalajes y tare. Requerido. + /// Peso neto de la mercancía sin incluir embalajes ni tara. Requerido. + /// Peso de la tara (contenedores, embalajes) asociado a la mercancía. Requerido. + public CartaPorteDetalleMercanciaInput(string @unidadPesoMerc, decimal @pesoBruto, decimal @pesoNeto, decimal @pesoTara) + { + this["UnidadPesoMerc"] = @unidadPesoMerc; + this["PesoBruto"] = @pesoBruto; + this["PesoNeto"] = @pesoNeto; + this["PesoTara"] = @pesoTara; + } + + /// + /// Clave de la unidad de peso de la mercancía conforme al catálogo correspondiente. + /// Requerido. + /// + [JsonIgnore] + public string UnidadPesoMerc + { + get => TryGetValue("UnidadPesoMerc", out var value) ? (string)value! : default!; + set => this["UnidadPesoMerc"] = value; + } + + /// + /// Peso bruto de la mercancía incluyendo embalajes y tare. + /// Requerido. + /// + [JsonIgnore] + public decimal PesoBruto + { + get => TryGetValue("PesoBruto", out var value) ? (decimal)value! : default!; + set => this["PesoBruto"] = value; + } + + /// + /// Peso neto de la mercancía sin incluir embalajes ni tara. + /// Requerido. + /// + [JsonIgnore] + public decimal PesoNeto + { + get => TryGetValue("PesoNeto", out var value) ? (decimal)value! : default!; + set => this["PesoNeto"] = value; + } + + /// + /// Peso de la tara (contenedores, embalajes) asociado a la mercancía. + /// Requerido. + /// + [JsonIgnore] + public decimal PesoTara + { + get => TryGetValue("PesoTara", out var value) ? (decimal)value! : default!; + set => this["PesoTara"] = value; + } + + /// + /// Número de piezas que conforman la mercancía detallada. + /// Opcional. + /// + [JsonIgnore] + public decimal? NumPiezas + { + get => TryGetValue("NumPiezas", out var value) ? (decimal?)value! : default!; + set => this["NumPiezas"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteDocumentacionAduaneraInput.cs b/Models/Inputs/CartaPorteDocumentacionAduaneraInput.cs new file mode 100644 index 0000000..253f05b --- /dev/null +++ b/Models/Inputs/CartaPorteDocumentacionAduaneraInput.cs @@ -0,0 +1,61 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// RFC del importador cuando aplica. + /// + public class CartaPorteDocumentacionAduaneraInput : Dictionary + { + /// + /// Tipo de documento aduanero (pedimento, guía, conocimiento) relacionado. + /// Opcional. + /// + [JsonIgnore] + public string? TipoDocumento + { + get => TryGetValue("TipoDocumento", out var value) ? (string?)value! : default!; + set => this["TipoDocumento"] = value; + } + + /// + /// Número de pedimento de importación/exportación. + /// Opcional. + /// + [JsonIgnore] + public string? NumPedimento + { + get => TryGetValue("NumPedimento", out var value) ? (string?)value! : default!; + set => this["NumPedimento"] = value; + } + + /// + /// Identificador alterno del documento aduanero. + /// Opcional. + /// + [JsonIgnore] + public string? IdentDocAduanero + { + get => TryGetValue("IdentDocAduanero", out var value) ? (string?)value! : default!; + set => this["IdentDocAduanero"] = value; + } + + /// + /// RFCImpo + /// Opcional. + /// + [JsonIgnore] + public string? RFCImpo + { + get => TryGetValue("RFCImpo", out var value) ? (string?)value! : default!; + set => this["RFCImpo"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteDomicilioInput.cs b/Models/Inputs/CartaPorteDomicilioInput.cs new file mode 100644 index 0000000..28a1085 --- /dev/null +++ b/Models/Inputs/CartaPorteDomicilioInput.cs @@ -0,0 +1,140 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Domicilio relacionado a la ubicación en el complemento Carta Porte. + /// + public class CartaPorteDomicilioInput : Dictionary + { + /// + /// Crea CartaPorteDomicilioInput. + /// + /// Clave de estado, entidad o región (ISO 3166-2 conforme catálogo SAT). Requerido. + /// Clave del país (catálogo c_Pais, ISO 3166-1). Requerido. + /// Código postal del domicilio. Requerido. + public CartaPorteDomicilioInput(string @estado, string @pais, string @codigoPostal) + { + this["Estado"] = @estado; + this["Pais"] = @pais; + this["CodigoPostal"] = @codigoPostal; + } + + /// + /// Calle del domicilio de origen y/o destino (requerida en XSD). + /// Opcional. + /// + [JsonIgnore] + public string? Calle + { + get => TryGetValue("Calle", out var value) ? (string?)value! : default!; + set => this["Calle"] = value; + } + + /// + /// Número exterior donde se ubica el domicilio. + /// Opcional. + /// + [JsonIgnore] + public string? NumeroExterior + { + get => TryGetValue("NumeroExterior", out var value) ? (string?)value! : default!; + set => this["NumeroExterior"] = value; + } + + /// + /// Número interior del domicilio, si existe. + /// Opcional. + /// + [JsonIgnore] + public string? NumeroInterior + { + get => TryGetValue("NumeroInterior", out var value) ? (string?)value! : default!; + set => this["NumeroInterior"] = value; + } + + /// + /// Colonia o dato análogo del domicilio. + /// Opcional. + /// + [JsonIgnore] + public string? Colonia + { + get => TryGetValue("Colonia", out var value) ? (string?)value! : default!; + set => this["Colonia"] = value; + } + + /// + /// Ciudad, población o distrito del domicilio. + /// Opcional. + /// + [JsonIgnore] + public string? Localidad + { + get => TryGetValue("Localidad", out var value) ? (string?)value! : default!; + set => this["Localidad"] = value; + } + + /// + /// Referencia geográfica adicional (ej. coordenadas GPS). + /// Opcional. + /// + [JsonIgnore] + public string? Referencia + { + get => TryGetValue("Referencia", out var value) ? (string?)value! : default!; + set => this["Referencia"] = value; + } + + /// + /// Municipio, delegación, alcaldía o análogo del domicilio. + /// Opcional. + /// + [JsonIgnore] + public string? Municipio + { + get => TryGetValue("Municipio", out var value) ? (string?)value! : default!; + set => this["Municipio"] = value; + } + + /// + /// Clave de estado, entidad o región (ISO 3166-2 conforme catálogo SAT). + /// Requerido. + /// + [JsonIgnore] + public string Estado + { + get => TryGetValue("Estado", out var value) ? (string)value! : default!; + set => this["Estado"] = value; + } + + /// + /// Clave del país (catálogo c_Pais, ISO 3166-1). + /// Requerido. + /// + [JsonIgnore] + public string Pais + { + get => TryGetValue("Pais", out var value) ? (string)value! : default!; + set => this["Pais"] = value; + } + + /// + /// Código postal del domicilio. + /// Requerido. + /// + [JsonIgnore] + public string CodigoPostal + { + get => TryGetValue("CodigoPostal", out var value) ? (string)value! : default!; + set => this["CodigoPostal"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteGuiaIdentificacionInput.cs b/Models/Inputs/CartaPorteGuiaIdentificacionInput.cs new file mode 100644 index 0000000..921aaae --- /dev/null +++ b/Models/Inputs/CartaPorteGuiaIdentificacionInput.cs @@ -0,0 +1,50 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteGuiaIdentificacionInput + /// + public class CartaPorteGuiaIdentificacionInput : Dictionary + { + /// + /// Número de la guía de identificación asociada a la mercancía. + /// Opcional. + /// + [JsonIgnore] + public string? NumeroGuiaIdentificacion + { + get => TryGetValue("NumeroGuiaIdentificacion", out var value) ? (string?)value! : default!; + set => this["NumeroGuiaIdentificacion"] = value; + } + + /// + /// Descripción detallada de la guía de identificación. + /// Opcional. + /// + [JsonIgnore] + public string? DescripGuiaIdentificacion + { + get => TryGetValue("DescripGuiaIdentificacion", out var value) ? (string?)value! : default!; + set => this["DescripGuiaIdentificacion"] = value; + } + + /// + /// Peso amparado por la guía de identificación. + /// Opcional. + /// + [JsonIgnore] + public decimal? PesoGuiaIdentificacion + { + get => TryGetValue("PesoGuiaIdentificacion", out var value) ? (decimal?)value! : default!; + set => this["PesoGuiaIdentificacion"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteIdentificacionVehicularInput.cs b/Models/Inputs/CartaPorteIdentificacionVehicularInput.cs new file mode 100644 index 0000000..7f2768b --- /dev/null +++ b/Models/Inputs/CartaPorteIdentificacionVehicularInput.cs @@ -0,0 +1,76 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteIdentificacionVehicularInput + /// + public class CartaPorteIdentificacionVehicularInput : Dictionary + { + /// + /// Crea CartaPorteIdentificacionVehicularInput. + /// + /// Configuración vehicular (catCartaPorte:c_ConfigAutotransporte) del vehículo primario. Requerido. + /// Peso bruto vehicular máximo permitido. Requerido. + /// Placa del vehículo motor. Requerido. + /// Año modelo del vehículo motor. Requerido. + public CartaPorteIdentificacionVehicularInput(string @configVehicular, decimal @pesoBrutoVehicular, string @placaVM, string @anioModeloVM) + { + this["ConfigVehicular"] = @configVehicular; + this["PesoBrutoVehicular"] = @pesoBrutoVehicular; + this["PlacaVM"] = @placaVM; + this["AnioModeloVM"] = @anioModeloVM; + } + + /// + /// Configuración vehicular (catCartaPorte:c_ConfigAutotransporte) del vehículo primario. + /// Requerido. + /// + [JsonIgnore] + public string ConfigVehicular + { + get => TryGetValue("ConfigVehicular", out var value) ? (string)value! : default!; + set => this["ConfigVehicular"] = value; + } + + /// + /// Peso bruto vehicular máximo permitido. + /// Requerido. + /// + [JsonIgnore] + public decimal PesoBrutoVehicular + { + get => TryGetValue("PesoBrutoVehicular", out var value) ? (decimal)value! : default!; + set => this["PesoBrutoVehicular"] = value; + } + + /// + /// Placa del vehículo motor. + /// Requerido. + /// + [JsonIgnore] + public string PlacaVM + { + get => TryGetValue("PlacaVM", out var value) ? (string)value! : default!; + set => this["PlacaVM"] = value; + } + + /// + /// Año modelo del vehículo motor. + /// Requerido. + /// + [JsonIgnore] + public string AnioModeloVM + { + get => TryGetValue("AnioModeloVM", out var value) ? (string)value! : default!; + set => this["AnioModeloVM"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteInput.cs b/Models/Inputs/CartaPorteInput.cs new file mode 100644 index 0000000..e31fbcf --- /dev/null +++ b/Models/Inputs/CartaPorteInput.cs @@ -0,0 +1,48 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteInput + /// + public class CartaPorteInput : InvoiceComplementInput + { + /// + /// Crea CartaPorteInput. + /// + public CartaPorteInput() : base("carta_porte") + { + this["type"] = "carta_porte"; + } + + /// + /// type + /// Valores: "carta_porte". + /// Requerido. + /// + [JsonIgnore] + public new string Type + { + get => TryGetValue("type", out var value) ? (string)value! : default!; + set => this["type"] = value; + } + + /// + /// data + /// Opcional. + /// + [JsonIgnore] + public new CartaPorteDataPropertiesInput? Data + { + get => TryGetValue("data", out var value) ? (CartaPorteDataPropertiesInput?)value! : default!; + set => this["data"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteMercanciaInput.cs b/Models/Inputs/CartaPorteMercanciaInput.cs new file mode 100644 index 0000000..7c5842c --- /dev/null +++ b/Models/Inputs/CartaPorteMercanciaInput.cs @@ -0,0 +1,496 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteMercanciaInput + /// + public class CartaPorteMercanciaInput : Dictionary + { + /// + /// Crea CartaPorteMercanciaInput. + /// + /// Clave del bien o producto transportado (catCartaPorte:c_BienesTransp). Requerido. + /// Descripción comercial del bien transportado. Requerido. + /// Cantidad total de unidades del bien. Requerido. + /// Clave de unidad (c_ClaveUnidad) aplicable a la cantidad. Requerido. + /// Peso en kilogramos de la mercancía (puede ser peso neto o bruto según contexto). Requerido. + public CartaPorteMercanciaInput(string @bienesTransp, string @descripcion, decimal @cantidad, string @claveUnidad, decimal @pesoEnKg) + { + this["BienesTransp"] = @bienesTransp; + this["Descripcion"] = @descripcion; + this["Cantidad"] = @cantidad; + this["ClaveUnidad"] = @claveUnidad; + this["PesoEnKg"] = @pesoEnKg; + } + + /// + /// Clave del bien o producto transportado (catCartaPorte:c_BienesTransp). + /// Requerido. + /// + [JsonIgnore] + public string BienesTransp + { + get => TryGetValue("BienesTransp", out var value) ? (string)value! : default!; + set => this["BienesTransp"] = value; + } + + /// + /// Clave STCC para transporte ferroviario cuando corresponda. + /// Opcional. + /// + [JsonIgnore] + public string? ClaveSTCC + { + get => TryGetValue("ClaveSTCC", out var value) ? (string?)value! : default!; + set => this["ClaveSTCC"] = value; + } + + /// + /// Descripción comercial del bien transportado. + /// Requerido. + /// + [JsonIgnore] + public string Descripcion + { + get => TryGetValue("Descripcion", out var value) ? (string)value! : default!; + set => this["Descripcion"] = value; + } + + /// + /// Cantidad total de unidades del bien. + /// Requerido. + /// + [JsonIgnore] + public decimal Cantidad + { + get => TryGetValue("Cantidad", out var value) ? (decimal)value! : default!; + set => this["Cantidad"] = value; + } + + /// + /// Clave de unidad (c_ClaveUnidad) aplicable a la cantidad. + /// Requerido. + /// + [JsonIgnore] + public string ClaveUnidad + { + get => TryGetValue("ClaveUnidad", out var value) ? (string)value! : default!; + set => this["ClaveUnidad"] = value; + } + + /// + /// Texto descriptivo de la unidad de medida. + /// Opcional. + /// + [JsonIgnore] + public string? Unidad + { + get => TryGetValue("Unidad", out var value) ? (string?)value! : default!; + set => this["Unidad"] = value; + } + + /// + /// Dimensiones físicas de la mercancía (largo x ancho x alto) si aplica. + /// Opcional. + /// + [JsonIgnore] + public string? Dimensiones + { + get => TryGetValue("Dimensiones", out var value) ? (string?)value! : default!; + set => this["Dimensiones"] = value; + } + + /// + /// Indicador de si la mercancía es material peligroso ("Sí" / "No"). + /// Opcional. + /// + [JsonIgnore] + public string? MaterialPeligroso + { + get => TryGetValue("MaterialPeligroso", out var value) ? (string?)value! : default!; + set => this["MaterialPeligroso"] = value; + } + + /// + /// Clave del material peligroso (c_MaterialPeligroso) cuando MaterialPeligroso es Sí. + /// Opcional. + /// + [JsonIgnore] + public string? CveMaterialPeligroso + { + get => TryGetValue("CveMaterialPeligroso", out var value) ? (string?)value! : default!; + set => this["CveMaterialPeligroso"] = value; + } + + /// + /// Clave del tipo de embalaje utilizado (c_TipoEmbalaje). + /// Opcional. + /// + [JsonIgnore] + public string? Embalaje + { + get => TryGetValue("Embalaje", out var value) ? (string?)value! : default!; + set => this["Embalaje"] = value; + } + + /// + /// Descripción adicional del embalaje. + /// Opcional. + /// + [JsonIgnore] + public string? DescripEmbalaje + { + get => TryGetValue("DescripEmbalaje", out var value) ? (string?)value! : default!; + set => this["DescripEmbalaje"] = value; + } + + /// + /// Sector regulado por COFEPRIS al que pertenece el producto. + /// Opcional. + /// + [JsonIgnore] + public string? SectorCOFEPRIS + { + get => TryGetValue("SectorCOFEPRIS", out var value) ? (string?)value! : default!; + set => this["SectorCOFEPRIS"] = value; + } + + /// + /// Nombre del ingrediente activo (productos regulados). + /// Opcional. + /// + [JsonIgnore] + public string? NombreIngredienteActivo + { + get => TryGetValue("NombreIngredienteActivo", out var value) ? (string?)value! : default!; + set => this["NombreIngredienteActivo"] = value; + } + + /// + /// Nombre químico del producto cuando aplica. + /// Opcional. + /// + [JsonIgnore] + public string? NomQuimico + { + get => TryGetValue("NomQuimico", out var value) ? (string?)value! : default!; + set => this["NomQuimico"] = value; + } + + /// + /// Denominación genérica del producto farmacéutico. + /// Opcional. + /// + [JsonIgnore] + public string? DenominacionGenericaProd + { + get => TryGetValue("DenominacionGenericaProd", out var value) ? (string?)value! : default!; + set => this["DenominacionGenericaProd"] = value; + } + + /// + /// Denominación distintiva (marca) del producto farmacéutico. + /// Opcional. + /// + [JsonIgnore] + public string? DenominacionDistintivaProd + { + get => TryGetValue("DenominacionDistintivaProd", out var value) ? (string?)value! : default!; + set => this["DenominacionDistintivaProd"] = value; + } + + /// + /// Nombre o razón social del fabricante. + /// Opcional. + /// + [JsonIgnore] + public string? Fabricante + { + get => TryGetValue("Fabricante", out var value) ? (string?)value! : default!; + set => this["Fabricante"] = value; + } + + /// + /// Fecha de caducidad del producto (AAAAMMDD o formato aplicable). + /// Opcional. + /// + [JsonIgnore] + public string? FechaCaducidad + { + get => TryGetValue("FechaCaducidad", out var value) ? (string?)value! : default!; + set => this["FechaCaducidad"] = value; + } + + /// + /// Número de lote del medicamento. + /// Opcional. + /// + [JsonIgnore] + public string? LoteMedicamento + { + get => TryGetValue("LoteMedicamento", out var value) ? (string?)value! : default!; + set => this["LoteMedicamento"] = value; + } + + /// + /// Forma farmacéutica (tableta, cápsula, solución, etc.). + /// Opcional. + /// + [JsonIgnore] + public string? FormaFarmaceutica + { + get => TryGetValue("FormaFarmaceutica", out var value) ? (string?)value! : default!; + set => this["FormaFarmaceutica"] = value; + } + + /// + /// Condiciones especiales de transporte (refrigeración, frágil, etc.). + /// Opcional. + /// + [JsonIgnore] + public string? CondicionesEspTransp + { + get => TryGetValue("CondicionesEspTransp", out var value) ? (string?)value! : default!; + set => this["CondicionesEspTransp"] = value; + } + + /// + /// Registro sanitario o folio de autorización. + /// Opcional. + /// + [JsonIgnore] + public string? RegistroSanitarioFolioAutorizacion + { + get => TryGetValue("RegistroSanitarioFolioAutorizacion", out var value) ? (string?)value! : default!; + set => this["RegistroSanitarioFolioAutorizacion"] = value; + } + + /// + /// Número de permiso de importación. + /// Opcional. + /// + [JsonIgnore] + public string? PermisoImportacion + { + get => TryGetValue("PermisoImportacion", out var value) ? (string?)value! : default!; + set => this["PermisoImportacion"] = value; + } + + /// + /// Folio VUCEM de importación. + /// Opcional. + /// + [JsonIgnore] + public string? FolioImpoVUCEM + { + get => TryGetValue("FolioImpoVUCEM", out var value) ? (string?)value! : default!; + set => this["FolioImpoVUCEM"] = value; + } + + /// + /// Número CAS para sustancias químicas. + /// Opcional. + /// + [JsonIgnore] + public string? NumCAS + { + get => TryGetValue("NumCAS", out var value) ? (string?)value! : default!; + set => this["NumCAS"] = value; + } + + /// + /// Razón social de la empresa importadora. + /// Opcional. + /// + [JsonIgnore] + public string? RazonSocialEmpImp + { + get => TryGetValue("RazonSocialEmpImp", out var value) ? (string?)value! : default!; + set => this["RazonSocialEmpImp"] = value; + } + + /// + /// Número de registro sanitario o plaguicida COFEPRIS. + /// Opcional. + /// + [JsonIgnore] + public string? NumRegSanPlagCOFEPRIS + { + get => TryGetValue("NumRegSanPlagCOFEPRIS", out var value) ? (string?)value! : default!; + set => this["NumRegSanPlagCOFEPRIS"] = value; + } + + /// + /// Información adicional del fabricante. + /// Opcional. + /// + [JsonIgnore] + public string? DatosFabricante + { + get => TryGetValue("DatosFabricante", out var value) ? (string?)value! : default!; + set => this["DatosFabricante"] = value; + } + + /// + /// Información del formulador del producto. + /// Opcional. + /// + [JsonIgnore] + public string? DatosFormulador + { + get => TryGetValue("DatosFormulador", out var value) ? (string?)value! : default!; + set => this["DatosFormulador"] = value; + } + + /// + /// Información del maquilador (si aplica). + /// Opcional. + /// + [JsonIgnore] + public string? DatosMaquilador + { + get => TryGetValue("DatosMaquilador", out var value) ? (string?)value! : default!; + set => this["DatosMaquilador"] = value; + } + + /// + /// Uso autorizado del producto. + /// Opcional. + /// + [JsonIgnore] + public string? UsoAutorizado + { + get => TryGetValue("UsoAutorizado", out var value) ? (string?)value! : default!; + set => this["UsoAutorizado"] = value; + } + + /// + /// Peso en kilogramos de la mercancía (puede ser peso neto o bruto según contexto). + /// Requerido. + /// + [JsonIgnore] + public decimal PesoEnKg + { + get => TryGetValue("PesoEnKg", out var value) ? (decimal)value! : default!; + set => this["PesoEnKg"] = value; + } + + /// + /// Valor monetario de la mercancía. + /// Opcional. + /// + [JsonIgnore] + public decimal? ValorMercancia + { + get => TryGetValue("ValorMercancia", out var value) ? (decimal?)value! : default!; + set => this["ValorMercancia"] = value; + } + + /// + /// Clave de moneda (c_Moneda) del valor de la mercancía. + /// Opcional. + /// + [JsonIgnore] + public string? Moneda + { + get => TryGetValue("Moneda", out var value) ? (string?)value! : default!; + set => this["Moneda"] = value; + } + + /// + /// Fracción arancelaria aplicable (c_FraccionArancelaria). + /// Opcional. + /// + [JsonIgnore] + public string? FraccionArancelaria + { + get => TryGetValue("FraccionArancelaria", out var value) ? (string?)value! : default!; + set => this["FraccionArancelaria"] = value; + } + + /// + /// UUID asociado al complemento de Comercio Exterior relacionado. + /// Opcional. + /// + [JsonIgnore] + public string? UUIDComercioExt + { + get => TryGetValue("UUIDComercioExt", out var value) ? (string?)value! : default!; + set => this["UUIDComercioExt"] = value; + } + + /// + /// Tipo de materia prima (si aplica para minerales, sustancias, etc.). + /// Opcional. + /// + [JsonIgnore] + public string? TipoMateria + { + get => TryGetValue("TipoMateria", out var value) ? (string?)value! : default!; + set => this["TipoMateria"] = value; + } + + /// + /// Descripción de la materia prima. + /// Opcional. + /// + [JsonIgnore] + public string? DescripcionMateria + { + get => TryGetValue("DescripcionMateria", out var value) ? (string?)value! : default!; + set => this["DescripcionMateria"] = value; + } + + /// + /// Documentos aduaneros asociados a la mercancía. + /// Opcional. + /// + [JsonIgnore] + public List? DocumentacionAduanera + { + get => TryGetValue("DocumentacionAduanera", out var value) ? (List?)value! : default!; + set => this["DocumentacionAduanera"] = value; + } + + /// + /// Guías de identificación asociadas. + /// Opcional. + /// + [JsonIgnore] + public List? GuiasIdentificacion + { + get => TryGetValue("GuiasIdentificacion", out var value) ? (List?)value! : default!; + set => this["GuiasIdentificacion"] = value; + } + + /// + /// Detalle de cantidades transportadas por origen/destino. + /// Opcional. + /// + [JsonIgnore] + public List? CantidadTransporta + { + get => TryGetValue("CantidadTransporta", out var value) ? (List?)value! : default!; + set => this["CantidadTransporta"] = value; + } + + /// + /// Detalle de pesos y piezas de la mercancía. + /// Opcional. + /// + [JsonIgnore] + public List? DetalleMercancia + { + get => TryGetValue("DetalleMercancia", out var value) ? (List?)value! : default!; + set => this["DetalleMercancia"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteMercanciasInput.cs b/Models/Inputs/CartaPorteMercanciasInput.cs new file mode 100644 index 0000000..190d57c --- /dev/null +++ b/Models/Inputs/CartaPorteMercanciasInput.cs @@ -0,0 +1,153 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteMercanciasInput + /// + public class CartaPorteMercanciasInput : Dictionary + { + /// + /// Crea CartaPorteMercanciasInput. + /// + /// Suma del peso bruto total de las mercancías (aéreo y ferroviario). Requerido. + /// Clave de unidad de medida estandarizada del peso (catCartaPorte:c_ClaveUnidadPeso). Requerido. + /// Número total de mercancías (cantidad de nodos Mercancia). Requerido. + /// Arreglo requerido con las mercancías transportadas. Requerido. + public CartaPorteMercanciasInput(decimal @pesoBrutoTotal, string @unidadPeso, decimal @numTotalMercancias, List @mercancia) + { + this["PesoBrutoTotal"] = @pesoBrutoTotal; + this["UnidadPeso"] = @unidadPeso; + this["NumTotalMercancias"] = @numTotalMercancias; + this["Mercancia"] = @mercancia; + } + + /// + /// Suma del peso bruto total de las mercancías (aéreo y ferroviario). + /// Requerido. + /// + [JsonIgnore] + public decimal PesoBrutoTotal + { + get => TryGetValue("PesoBrutoTotal", out var value) ? (decimal)value! : default!; + set => this["PesoBrutoTotal"] = value; + } + + /// + /// Clave de unidad de medida estandarizada del peso (catCartaPorte:c_ClaveUnidadPeso). + /// Requerido. + /// + [JsonIgnore] + public string UnidadPeso + { + get => TryGetValue("UnidadPeso", out var value) ? (string)value! : default!; + set => this["UnidadPeso"] = value; + } + + /// + /// Suma de los valores PesoNeto de cada DetalleMercancia. + /// Opcional. + /// + [JsonIgnore] + public decimal? PesoNetoTotal + { + get => TryGetValue("PesoNetoTotal", out var value) ? (decimal?)value! : default!; + set => this["PesoNetoTotal"] = value; + } + + /// + /// Número total de mercancías (cantidad de nodos Mercancia). + /// Requerido. + /// + [JsonIgnore] + public decimal NumTotalMercancias + { + get => TryGetValue("NumTotalMercancias", out var value) ? (decimal)value! : default!; + set => this["NumTotalMercancias"] = value; + } + + /// + /// Importe pagado por la tasación de las mercancías (vía aérea). + /// Opcional. + /// + [JsonIgnore] + public decimal? CargoPorTasacion + { + get => TryGetValue("CargoPorTasacion", out var value) ? (decimal?)value! : default!; + set => this["CargoPorTasacion"] = value; + } + + /// + /// Indica si aplica logística inversa, recolección o devolución. + /// Opcional. + /// + [JsonIgnore] + public string? LogisticaInversaRecoleccionDevolucion + { + get => TryGetValue("LogisticaInversaRecoleccionDevolucion", out var value) ? (string?)value! : default!; + set => this["LogisticaInversaRecoleccionDevolucion"] = value; + } + + /// + /// Arreglo requerido con las mercancías transportadas. + /// Requerido. + /// + [JsonIgnore] + public List Mercancia + { + get => TryGetValue("Mercancia", out var value) ? (List)value! : default!; + set => this["Mercancia"] = value; + } + + /// + /// Datos del autotransporte de carga federal. + /// Opcional. + /// + [JsonIgnore] + public CartaPorteAutotransporteInput? Autotransporte + { + get => TryGetValue("Autotransporte", out var value) ? (CartaPorteAutotransporteInput?)value! : default!; + set => this["Autotransporte"] = value; + } + + /// + /// Datos de la embarcación para transporte marítimo. + /// Opcional. + /// + [JsonIgnore] + public CartaPorteTransporteMaritimoInput? TransporteMaritimo + { + get => TryGetValue("TransporteMaritimo", out var value) ? (CartaPorteTransporteMaritimoInput?)value! : default!; + set => this["TransporteMaritimo"] = value; + } + + /// + /// Datos del transporte aéreo utilizado. + /// Opcional. + /// + [JsonIgnore] + public CartaPorteTransporteAereoInput? TransporteAereo + { + get => TryGetValue("TransporteAereo", out var value) ? (CartaPorteTransporteAereoInput?)value! : default!; + set => this["TransporteAereo"] = value; + } + + /// + /// Datos del transporte ferroviario utilizado. + /// Opcional. + /// + [JsonIgnore] + public CartaPorteTransporteFerroviarioInput? TransporteFerroviario + { + get => TryGetValue("TransporteFerroviario", out var value) ? (CartaPorteTransporteFerroviarioInput?)value! : default!; + set => this["TransporteFerroviario"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteRemolqueInput.cs b/Models/Inputs/CartaPorteRemolqueInput.cs new file mode 100644 index 0000000..9ff1cde --- /dev/null +++ b/Models/Inputs/CartaPorteRemolqueInput.cs @@ -0,0 +1,39 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteRemolqueInput + /// + public class CartaPorteRemolqueInput : Dictionary + { + /// + /// Subtipo de remolque (catCartaPorte:c_SubTipoRem). + /// Opcional. + /// + [JsonIgnore] + public string? SubTipoRem + { + get => TryGetValue("SubTipoRem", out var value) ? (string?)value! : default!; + set => this["SubTipoRem"] = value; + } + + /// + /// Placa del remolque. + /// Opcional. + /// + [JsonIgnore] + public string? Placa + { + get => TryGetValue("Placa", out var value) ? (string?)value! : default!; + set => this["Placa"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteSegurosInput.cs b/Models/Inputs/CartaPorteSegurosInput.cs new file mode 100644 index 0000000..45718c4 --- /dev/null +++ b/Models/Inputs/CartaPorteSegurosInput.cs @@ -0,0 +1,105 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteSegurosInput + /// + public class CartaPorteSegurosInput : Dictionary + { + /// + /// Crea CartaPorteSegurosInput. + /// + /// Nombre de la aseguradora de responsabilidad civil. Requerido. + /// Número de póliza de responsabilidad civil. Requerido. + public CartaPorteSegurosInput(string @aseguraRespCivil, string @polizaRespCivil) + { + this["AseguraRespCivil"] = @aseguraRespCivil; + this["PolizaRespCivil"] = @polizaRespCivil; + } + + /// + /// Nombre de la aseguradora de responsabilidad civil. + /// Requerido. + /// + [JsonIgnore] + public string AseguraRespCivil + { + get => TryGetValue("AseguraRespCivil", out var value) ? (string)value! : default!; + set => this["AseguraRespCivil"] = value; + } + + /// + /// Número de póliza de responsabilidad civil. + /// Requerido. + /// + [JsonIgnore] + public string PolizaRespCivil + { + get => TryGetValue("PolizaRespCivil", out var value) ? (string)value! : default!; + set => this["PolizaRespCivil"] = value; + } + + /// + /// Aseguradora contra daños al medio ambiente. + /// Opcional. + /// + [JsonIgnore] + public string? AseguraMedAmbiente + { + get => TryGetValue("AseguraMedAmbiente", out var value) ? (string?)value! : default!; + set => this["AseguraMedAmbiente"] = value; + } + + /// + /// Número de póliza de medio ambiente. + /// Opcional. + /// + [JsonIgnore] + public string? PolizaMedAmbiente + { + get => TryGetValue("PolizaMedAmbiente", out var value) ? (string?)value! : default!; + set => this["PolizaMedAmbiente"] = value; + } + + /// + /// Aseguradora de la carga. + /// Opcional. + /// + [JsonIgnore] + public string? AseguraCarga + { + get => TryGetValue("AseguraCarga", out var value) ? (string?)value! : default!; + set => this["AseguraCarga"] = value; + } + + /// + /// Número de póliza de la carga. + /// Opcional. + /// + [JsonIgnore] + public string? PolizaCarga + { + get => TryGetValue("PolizaCarga", out var value) ? (string?)value! : default!; + set => this["PolizaCarga"] = value; + } + + /// + /// Prima total de los seguros contratados. + /// Opcional. + /// + [JsonIgnore] + public decimal? PrimaSeguro + { + get => TryGetValue("PrimaSeguro", out var value) ? (decimal?)value! : default!; + set => this["PrimaSeguro"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteTransporteAereoInput.cs b/Models/Inputs/CartaPorteTransporteAereoInput.cs new file mode 100644 index 0000000..6256754 --- /dev/null +++ b/Models/Inputs/CartaPorteTransporteAereoInput.cs @@ -0,0 +1,149 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteTransporteAereoInput + /// + public class CartaPorteTransporteAereoInput : Dictionary + { + /// + /// Clave del permiso SCT para transporte aéreo. + /// Opcional. + /// + [JsonIgnore] + public string? PermSCT + { + get => TryGetValue("PermSCT", out var value) ? (string?)value! : default!; + set => this["PermSCT"] = value; + } + + /// + /// Número de permiso SCT. + /// Opcional. + /// + [JsonIgnore] + public string? NumPermisoSCT + { + get => TryGetValue("NumPermisoSCT", out var value) ? (string?)value! : default!; + set => this["NumPermisoSCT"] = value; + } + + /// + /// Matrícula de la aeronave. + /// Opcional. + /// + [JsonIgnore] + public string? MatriculaAeronave + { + get => TryGetValue("MatriculaAeronave", out var value) ? (string?)value! : default!; + set => this["MatriculaAeronave"] = value; + } + + /// + /// Nombre de la aseguradora aérea. + /// Opcional. + /// + [JsonIgnore] + public string? NombreAseg + { + get => TryGetValue("NombreAseg", out var value) ? (string?)value! : default!; + set => this["NombreAseg"] = value; + } + + /// + /// Número de póliza de seguro de la aeronave. + /// Opcional. + /// + [JsonIgnore] + public string? NumPolizaSeguro + { + get => TryGetValue("NumPolizaSeguro", out var value) ? (string?)value! : default!; + set => this["NumPolizaSeguro"] = value; + } + + /// + /// Número de guía aérea (Air Waybill). + /// Opcional. + /// + [JsonIgnore] + public string? NumeroGuia + { + get => TryGetValue("NumeroGuia", out var value) ? (string?)value! : default!; + set => this["NumeroGuia"] = value; + } + + /// + /// Lugar donde se celebró el contrato de transporte. + /// Opcional. + /// + [JsonIgnore] + public string? LugarContrato + { + get => TryGetValue("LugarContrato", out var value) ? (string?)value! : default!; + set => this["LugarContrato"] = value; + } + + /// + /// Código del transportista aéreo. + /// Opcional. + /// + [JsonIgnore] + public string? CodigoTransportista + { + get => TryGetValue("CodigoTransportista", out var value) ? (string?)value! : default!; + set => this["CodigoTransportista"] = value; + } + + /// + /// RFC del embarcador. + /// Opcional. + /// + [JsonIgnore] + public string? RFCEmbarcador + { + get => TryGetValue("RFCEmbarcador", out var value) ? (string?)value! : default!; + set => this["RFCEmbarcador"] = value; + } + + /// + /// Número de registro tributario extranjero del embarcador. + /// Opcional. + /// + [JsonIgnore] + public string? NumRegIdTribEmbarc + { + get => TryGetValue("NumRegIdTribEmbarc", out var value) ? (string?)value! : default!; + set => this["NumRegIdTribEmbarc"] = value; + } + + /// + /// País de residencia fiscal del embarcador. + /// Opcional. + /// + [JsonIgnore] + public string? ResidenciaFiscalEmbarc + { + get => TryGetValue("ResidenciaFiscalEmbarc", out var value) ? (string?)value! : default!; + set => this["ResidenciaFiscalEmbarc"] = value; + } + + /// + /// Nombre o razón social del embarcador. + /// Opcional. + /// + [JsonIgnore] + public string? NombreEmbarcador + { + get => TryGetValue("NombreEmbarcador", out var value) ? (string?)value! : default!; + set => this["NombreEmbarcador"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteTransporteFerroviarioInput.cs b/Models/Inputs/CartaPorteTransporteFerroviarioInput.cs new file mode 100644 index 0000000..8aa7bc8 --- /dev/null +++ b/Models/Inputs/CartaPorteTransporteFerroviarioInput.cs @@ -0,0 +1,83 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteTransporteFerroviarioInput + /// + public class CartaPorteTransporteFerroviarioInput : Dictionary + { + /// + /// Tipo de servicio ferroviario (regular, intermodal, etc.). + /// Opcional. + /// + [JsonIgnore] + public string? TipoDeServicio + { + get => TryGetValue("TipoDeServicio", out var value) ? (string?)value! : default!; + set => this["TipoDeServicio"] = value; + } + + /// + /// Tipo de tráfico (nacional, internacional, etc.). + /// Opcional. + /// + [JsonIgnore] + public string? TipoDeTrafico + { + get => TryGetValue("TipoDeTrafico", out var value) ? (string?)value! : default!; + set => this["TipoDeTrafico"] = value; + } + + /// + /// Nombre de la aseguradora ferroviaria. + /// Opcional. + /// + [JsonIgnore] + public string? NombreAseg + { + get => TryGetValue("NombreAseg", out var value) ? (string?)value! : default!; + set => this["NombreAseg"] = value; + } + + /// + /// Número de póliza de seguro ferroviario. + /// Opcional. + /// + [JsonIgnore] + public string? NumPolizaSeguro + { + get => TryGetValue("NumPolizaSeguro", out var value) ? (string?)value! : default!; + set => this["NumPolizaSeguro"] = value; + } + + /// + /// Lista de derechos de paso aplicados. + /// Opcional. + /// + [JsonIgnore] + public List? DerechosDePaso + { + get => TryGetValue("DerechosDePaso", out var value) ? (List?)value! : default!; + set => this["DerechosDePaso"] = value; + } + + /// + /// Lista de carros ferroviarios involucrados. + /// Opcional. + /// + [JsonIgnore] + public List? Carro + { + get => TryGetValue("Carro", out var value) ? (List?)value! : default!; + set => this["Carro"] = value; + } + + } +} diff --git a/Models/Inputs/CartaPorteTransporteMaritimoInput.cs b/Models/Inputs/CartaPorteTransporteMaritimoInput.cs new file mode 100644 index 0000000..75b1230 --- /dev/null +++ b/Models/Inputs/CartaPorteTransporteMaritimoInput.cs @@ -0,0 +1,281 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaPorteTransporteMaritimoInput + /// + public class CartaPorteTransporteMaritimoInput : Dictionary + { + /// + /// Crea CartaPorteTransporteMaritimoInput. + /// + /// Clave del permiso SCT de la embarcación. Requerido. + /// Número de permiso SCT de la embarcación. Requerido. + public CartaPorteTransporteMaritimoInput(string @permSCT, string @numPermisoSCT) + { + this["PermSCT"] = @permSCT; + this["NumPermisoSCT"] = @numPermisoSCT; + } + + /// + /// Clave del permiso SCT de la embarcación. + /// Requerido. + /// + [JsonIgnore] + public string PermSCT + { + get => TryGetValue("PermSCT", out var value) ? (string)value! : default!; + set => this["PermSCT"] = value; + } + + /// + /// Número de permiso SCT de la embarcación. + /// Requerido. + /// + [JsonIgnore] + public string NumPermisoSCT + { + get => TryGetValue("NumPermisoSCT", out var value) ? (string)value! : default!; + set => this["NumPermisoSCT"] = value; + } + + /// + /// Nombre de la aseguradora marítima. + /// Opcional. + /// + [JsonIgnore] + public string? NombreAseg + { + get => TryGetValue("NombreAseg", out var value) ? (string?)value! : default!; + set => this["NombreAseg"] = value; + } + + /// + /// Número de póliza de seguro marítimo. + /// Opcional. + /// + [JsonIgnore] + public string? NumPolizaSeguro + { + get => TryGetValue("NumPolizaSeguro", out var value) ? (string?)value! : default!; + set => this["NumPolizaSeguro"] = value; + } + + /// + /// Tipo de embarcación (catCartaPorte:c_TipoEmbarcacion). + /// Opcional. + /// + [JsonIgnore] + public string? TipoEmbarcacion + { + get => TryGetValue("TipoEmbarcacion", out var value) ? (string?)value! : default!; + set => this["TipoEmbarcacion"] = value; + } + + /// + /// Matrícula de la embarcación. + /// Opcional. + /// + [JsonIgnore] + public string? Matricula + { + get => TryGetValue("Matricula", out var value) ? (string?)value! : default!; + set => this["Matricula"] = value; + } + + /// + /// Número OMI (IMO number) de la embarcación. + /// Opcional. + /// + [JsonIgnore] + public string? NumeroOMI + { + get => TryGetValue("NumeroOMI", out var value) ? (string?)value! : default!; + set => this["NumeroOMI"] = value; + } + + /// + /// Año de construcción de la embarcación. + /// Opcional. + /// + [JsonIgnore] + public string? AnioEmbarcacion + { + get => TryGetValue("AnioEmbarcacion", out var value) ? (string?)value! : default!; + set => this["AnioEmbarcacion"] = value; + } + + /// + /// Nombre propio de la embarcación. + /// Opcional. + /// + [JsonIgnore] + public string? NombreEmbarc + { + get => TryGetValue("NombreEmbarc", out var value) ? (string?)value! : default!; + set => this["NombreEmbarc"] = value; + } + + /// + /// Nacionalidad o bandera de la embarcación. + /// Opcional. + /// + [JsonIgnore] + public string? NacionalidadEmbarc + { + get => TryGetValue("NacionalidadEmbarc", out var value) ? (string?)value! : default!; + set => this["NacionalidadEmbarc"] = value; + } + + /// + /// Toneladas de arqueo bruto. + /// Opcional. + /// + [JsonIgnore] + public decimal? UnidadesDeArqBruto + { + get => TryGetValue("UnidadesDeArqBruto", out var value) ? (decimal?)value! : default!; + set => this["UnidadesDeArqBruto"] = value; + } + + /// + /// Tipo de carga (granel, contenedores, líquidos, etc.). + /// Opcional. + /// + [JsonIgnore] + public string? TipoCarga + { + get => TryGetValue("TipoCarga", out var value) ? (string?)value! : default!; + set => this["TipoCarga"] = value; + } + + /// + /// Longitud total de la embarcación (eslora). + /// Opcional. + /// + [JsonIgnore] + public decimal? Eslora + { + get => TryGetValue("Eslora", out var value) ? (decimal?)value! : default!; + set => this["Eslora"] = value; + } + + /// + /// Ancho máximo de la embarcación (manga). + /// Opcional. + /// + [JsonIgnore] + public decimal? Manga + { + get => TryGetValue("Manga", out var value) ? (decimal?)value! : default!; + set => this["Manga"] = value; + } + + /// + /// Calado máximo. + /// Opcional. + /// + [JsonIgnore] + public decimal? Calado + { + get => TryGetValue("Calado", out var value) ? (decimal?)value! : default!; + set => this["Calado"] = value; + } + + /// + /// Altura del puntal. + /// Opcional. + /// + [JsonIgnore] + public decimal? Puntal + { + get => TryGetValue("Puntal", out var value) ? (decimal?)value! : default!; + set => this["Puntal"] = value; + } + + /// + /// Nombre de la línea naviera. + /// Opcional. + /// + [JsonIgnore] + public string? LineaNaviera + { + get => TryGetValue("LineaNaviera", out var value) ? (string?)value! : default!; + set => this["LineaNaviera"] = value; + } + + /// + /// Nombre del agente naviero. + /// Opcional. + /// + [JsonIgnore] + public string? NombreAgenteNaviero + { + get => TryGetValue("NombreAgenteNaviero", out var value) ? (string?)value! : default!; + set => this["NombreAgenteNaviero"] = value; + } + + /// + /// Número de autorización del agente naviero. + /// Opcional. + /// + [JsonIgnore] + public string? NumAutorizacionNaviero + { + get => TryGetValue("NumAutorizacionNaviero", out var value) ? (string?)value! : default!; + set => this["NumAutorizacionNaviero"] = value; + } + + /// + /// Número de viaje o rotación. + /// Opcional. + /// + [JsonIgnore] + public string? NumViaje + { + get => TryGetValue("NumViaje", out var value) ? (string?)value! : default!; + set => this["NumViaje"] = value; + } + + /// + /// Número de conocimiento de embarque. + /// Opcional. + /// + [JsonIgnore] + public string? NumConocEmbarc + { + get => TryGetValue("NumConocEmbarc", out var value) ? (string?)value! : default!; + set => this["NumConocEmbarc"] = value; + } + + /// + /// Permiso temporal de navegación. + /// Opcional. + /// + [JsonIgnore] + public string? PermisoTempNavegacion + { + get => TryGetValue("PermisoTempNavegacion", out var value) ? (string?)value! : default!; + set => this["PermisoTempNavegacion"] = value; + } + + /// + /// Lista de contenedores asociados al embarque. + /// Opcional. + /// + [JsonIgnore] + public List? Contenedor + { + get => TryGetValue("Contenedor", out var value) ? (List?)value! : default!; + set => this["Contenedor"] = value; + } + + } +} diff --git a/Models/Inputs/CartaporteCatalogSearchAirTransportCodesParams.cs b/Models/Inputs/CartaporteCatalogSearchAirTransportCodesParams.cs new file mode 100644 index 0000000..f4b269a --- /dev/null +++ b/Models/Inputs/CartaporteCatalogSearchAirTransportCodesParams.cs @@ -0,0 +1,84 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaporteCatalogSearchAirTransportCodesParams + /// + public class CartaporteCatalogSearchAirTransportCodesParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Prefijo para buscar en `key`, `airline_name` o `icao_designator`. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados. + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CartaporteCatalogSearchCustomsDocumentsParams.cs b/Models/Inputs/CartaporteCatalogSearchCustomsDocumentsParams.cs new file mode 100644 index 0000000..8ee9dd5 --- /dev/null +++ b/Models/Inputs/CartaporteCatalogSearchCustomsDocumentsParams.cs @@ -0,0 +1,84 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaporteCatalogSearchCustomsDocumentsParams + /// + public class CartaporteCatalogSearchCustomsDocumentsParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Prefijo para buscar en `key` o `description`. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados. + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CartaporteCatalogSearchHazardousMaterialsParams.cs b/Models/Inputs/CartaporteCatalogSearchHazardousMaterialsParams.cs new file mode 100644 index 0000000..6a3497e --- /dev/null +++ b/Models/Inputs/CartaporteCatalogSearchHazardousMaterialsParams.cs @@ -0,0 +1,84 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaporteCatalogSearchHazardousMaterialsParams + /// + public class CartaporteCatalogSearchHazardousMaterialsParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Prefijo para buscar en `key`, `description` o `class_division`. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados. + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CartaporteCatalogSearchMarineContainersParams.cs b/Models/Inputs/CartaporteCatalogSearchMarineContainersParams.cs new file mode 100644 index 0000000..9a88c95 --- /dev/null +++ b/Models/Inputs/CartaporteCatalogSearchMarineContainersParams.cs @@ -0,0 +1,84 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaporteCatalogSearchMarineContainersParams + /// + public class CartaporteCatalogSearchMarineContainersParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Prefijo para buscar en `key` o `description`. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados. + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CartaporteCatalogSearchNavalAuthorizationsParams.cs b/Models/Inputs/CartaporteCatalogSearchNavalAuthorizationsParams.cs new file mode 100644 index 0000000..9e022a2 --- /dev/null +++ b/Models/Inputs/CartaporteCatalogSearchNavalAuthorizationsParams.cs @@ -0,0 +1,84 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaporteCatalogSearchNavalAuthorizationsParams + /// + public class CartaporteCatalogSearchNavalAuthorizationsParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Prefijo para buscar en `key`. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados. + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CartaporteCatalogSearchPackagingTypesParams.cs b/Models/Inputs/CartaporteCatalogSearchPackagingTypesParams.cs new file mode 100644 index 0000000..7115b6a --- /dev/null +++ b/Models/Inputs/CartaporteCatalogSearchPackagingTypesParams.cs @@ -0,0 +1,84 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaporteCatalogSearchPackagingTypesParams + /// + public class CartaporteCatalogSearchPackagingTypesParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Prefijo para buscar en `key` o `description`. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados. + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CartaporteCatalogSearchPortStationsParams.cs b/Models/Inputs/CartaporteCatalogSearchPortStationsParams.cs new file mode 100644 index 0000000..c1966dd --- /dev/null +++ b/Models/Inputs/CartaporteCatalogSearchPortStationsParams.cs @@ -0,0 +1,84 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaporteCatalogSearchPortStationsParams + /// + public class CartaporteCatalogSearchPortStationsParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Prefijo para buscar en `key`, `description` o `iata_designator`. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados. + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CartaporteCatalogSearchRightsOfPassageParams.cs b/Models/Inputs/CartaporteCatalogSearchRightsOfPassageParams.cs new file mode 100644 index 0000000..9673b72 --- /dev/null +++ b/Models/Inputs/CartaporteCatalogSearchRightsOfPassageParams.cs @@ -0,0 +1,84 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaporteCatalogSearchRightsOfPassageParams + /// + public class CartaporteCatalogSearchRightsOfPassageParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Prefijo para buscar en `key`, `right_of_passage` o `concessionaire`. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados. + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CartaporteCatalogSearchTrailerTypesParams.cs b/Models/Inputs/CartaporteCatalogSearchTrailerTypesParams.cs new file mode 100644 index 0000000..a4eecb7 --- /dev/null +++ b/Models/Inputs/CartaporteCatalogSearchTrailerTypesParams.cs @@ -0,0 +1,84 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaporteCatalogSearchTrailerTypesParams + /// + public class CartaporteCatalogSearchTrailerTypesParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Prefijo para buscar en `key` o `description`. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados. + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CartaporteCatalogSearchTransportConfigsParams.cs b/Models/Inputs/CartaporteCatalogSearchTransportConfigsParams.cs new file mode 100644 index 0000000..a377890 --- /dev/null +++ b/Models/Inputs/CartaporteCatalogSearchTransportConfigsParams.cs @@ -0,0 +1,84 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CartaporteCatalogSearchTransportConfigsParams + /// + public class CartaporteCatalogSearchTransportConfigsParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Prefijo para buscar en `key` o `description`. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados. + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CatalogGetProductCategoryParams.cs b/Models/Inputs/CatalogGetProductCategoryParams.cs new file mode 100644 index 0000000..40df5a2 --- /dev/null +++ b/Models/Inputs/CatalogGetProductCategoryParams.cs @@ -0,0 +1,73 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CatalogGetProductCategoryParams + /// + public class CatalogGetProductCategoryParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados (con el `limit` por defecto de 100, la página máxima es 30). + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CatalogSearchCountriesParams.cs b/Models/Inputs/CatalogSearchCountriesParams.cs new file mode 100644 index 0000000..fd9bdbd --- /dev/null +++ b/Models/Inputs/CatalogSearchCountriesParams.cs @@ -0,0 +1,50 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CatalogSearchCountriesParams + /// + public class CatalogSearchCountriesParams : Dictionary + { + /// + /// Código o texto a buscar. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// page + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// limit + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CatalogSearchInvoiceUsesParams.cs b/Models/Inputs/CatalogSearchInvoiceUsesParams.cs new file mode 100644 index 0000000..a99b5df --- /dev/null +++ b/Models/Inputs/CatalogSearchInvoiceUsesParams.cs @@ -0,0 +1,50 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CatalogSearchInvoiceUsesParams + /// + public class CatalogSearchInvoiceUsesParams : Dictionary + { + /// + /// Código o texto a buscar. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// page + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// limit + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CatalogSearchProductsParams.cs b/Models/Inputs/CatalogSearchProductsParams.cs new file mode 100644 index 0000000..035612a --- /dev/null +++ b/Models/Inputs/CatalogSearchProductsParams.cs @@ -0,0 +1,95 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CatalogSearchProductsParams + /// + public class CatalogSearchProductsParams : Dictionary + { + /// + /// Prefijo de categoría de 2, 4 o 6 dígitos. Incluye descendientes y se combina con q. Sin q, lista los productos de la categoría. + /// Opcional. + /// + [JsonIgnore] + public string? Category + { + get => TryGetValue("category", out var value) ? (string?)value! : default!; + set => this["category"] = value; + } + + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Busca prefijos de claves, descripciones, palabras similares y nombres de categorías, sin distinguir mayúsculas ni diacríticos. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados (con el `limit` por defecto de 100, la página máxima es 30). + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CatalogSearchTaxSystemsParams.cs b/Models/Inputs/CatalogSearchTaxSystemsParams.cs new file mode 100644 index 0000000..df3cc79 --- /dev/null +++ b/Models/Inputs/CatalogSearchTaxSystemsParams.cs @@ -0,0 +1,50 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CatalogSearchTaxSystemsParams + /// + public class CatalogSearchTaxSystemsParams : Dictionary + { + /// + /// Código o texto a buscar. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// page + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// limit + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CatalogSearchUnitsParams.cs b/Models/Inputs/CatalogSearchUnitsParams.cs new file mode 100644 index 0000000..d4c1f49 --- /dev/null +++ b/Models/Inputs/CatalogSearchUnitsParams.cs @@ -0,0 +1,84 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CatalogSearchUnitsParams + /// + public class CatalogSearchUnitsParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Consulta. Texto a buscar en la descripción de la unidad de medida. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados (con el `limit` por defecto de 100, la página máxima es 30). + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/CatalogSearchZipCodesParams.cs b/Models/Inputs/CatalogSearchZipCodesParams.cs new file mode 100644 index 0000000..dccf03d --- /dev/null +++ b/Models/Inputs/CatalogSearchZipCodesParams.cs @@ -0,0 +1,95 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CatalogSearchZipCodesParams + /// + public class CatalogSearchZipCodesParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Código o prefijo de 1 a 5 dígitos, o nombre de colonia, localidad/ciudad, municipio o estado. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// page + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// limit + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + /// + /// Clave de estado de tres letras (por ejemplo ZAC). + /// Opcional. + /// + [JsonIgnore] + public string? State + { + get => TryGetValue("state", out var value) ? (string?)value! : default!; + set => this["state"] = value; + } + + } +} diff --git a/Models/Inputs/ComercioExteriorCatalogSearchTariffFractionsParams.cs b/Models/Inputs/ComercioExteriorCatalogSearchTariffFractionsParams.cs new file mode 100644 index 0000000..7000e8a --- /dev/null +++ b/Models/Inputs/ComercioExteriorCatalogSearchTariffFractionsParams.cs @@ -0,0 +1,84 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorCatalogSearchTariffFractionsParams + /// + public class ComercioExteriorCatalogSearchTariffFractionsParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Prefijo para buscar en `key` o `description`. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados. + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/ComercioExteriorDataInput.cs b/Models/Inputs/ComercioExteriorDataInput.cs new file mode 100644 index 0000000..a130cf6 --- /dev/null +++ b/Models/Inputs/ComercioExteriorDataInput.cs @@ -0,0 +1,200 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorDataInput + /// + public class ComercioExteriorDataInput : Dictionary + { + /// + /// Crea ComercioExteriorDataInput. + /// + /// Clave del pedimento (catálogo c_ClavePedimento). Requerido. + /// Indica si existe certificado de origen. Requerido. + /// Tipo de cambio USD. Requerido. + /// Total en USD. Requerido. + /// Mercancias Requerido. + public ComercioExteriorDataInput(string @claveDePedimento, int @certificadoOrigen, decimal @tipoCambioUSD, decimal @totalUSD, ComercioExteriorMercanciasInput @mercancias) + { + this["ClaveDePedimento"] = @claveDePedimento; + this["CertificadoOrigen"] = @certificadoOrigen; + this["TipoCambioUSD"] = @tipoCambioUSD; + this["TotalUSD"] = @totalUSD; + this["Mercancias"] = @mercancias; + } + + /// + /// Receptor + /// Opcional. + /// + [JsonIgnore] + public OneOf? Receptor + { + get => TryGetValue("Receptor", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["Receptor"] = value?.Value; + } + + /// + /// Version + /// Valores: "2.0". + /// Opcional. + /// + [JsonIgnore] + public string? Version + { + get => TryGetValue("Version", out var value) ? (string?)value! : default!; + set => this["Version"] = value; + } + + /// + /// Clave del catálogo c_MotivoTraslado. + /// Opcional. + /// + [JsonIgnore] + public string? MotivoTraslado + { + get => TryGetValue("MotivoTraslado", out var value) ? (string?)value! : default!; + set => this["MotivoTraslado"] = value; + } + + /// + /// Clave del pedimento (catálogo c_ClavePedimento). + /// Requerido. + /// + [JsonIgnore] + public string ClaveDePedimento + { + get => TryGetValue("ClaveDePedimento", out var value) ? (string)value! : default!; + set => this["ClaveDePedimento"] = value; + } + + /// + /// Indica si existe certificado de origen. + /// Requerido. + /// + [JsonIgnore] + public int CertificadoOrigen + { + get => TryGetValue("CertificadoOrigen", out var value) ? (int)value! : default!; + set => this["CertificadoOrigen"] = value; + } + + /// + /// Número de certificado de origen. + /// Opcional. + /// + [JsonIgnore] + public string? NumCertificadoOrigen + { + get => TryGetValue("NumCertificadoOrigen", out var value) ? (string?)value! : default!; + set => this["NumCertificadoOrigen"] = value; + } + + /// + /// Número de exportador confiable. + /// Opcional. + /// + [JsonIgnore] + public string? NumeroExportadorConfiable + { + get => TryGetValue("NumeroExportadorConfiable", out var value) ? (string?)value! : default!; + set => this["NumeroExportadorConfiable"] = value; + } + + /// + /// Clave del INCOTERM (catálogo c_INCOTERM). + /// Opcional. + /// + [JsonIgnore] + public string? Incoterm + { + get => TryGetValue("Incoterm", out var value) ? (string?)value! : default!; + set => this["Incoterm"] = value; + } + + /// + /// Observaciones + /// Opcional. + /// + [JsonIgnore] + public string? Observaciones + { + get => TryGetValue("Observaciones", out var value) ? (string?)value! : default!; + set => this["Observaciones"] = value; + } + + /// + /// Tipo de cambio USD. + /// Requerido. + /// + [JsonIgnore] + public decimal TipoCambioUSD + { + get => TryGetValue("TipoCambioUSD", out var value) ? (decimal)value! : default!; + set => this["TipoCambioUSD"] = value; + } + + /// + /// Total en USD. + /// Requerido. + /// + [JsonIgnore] + public decimal TotalUSD + { + get => TryGetValue("TotalUSD", out var value) ? (decimal)value! : default!; + set => this["TotalUSD"] = value; + } + + /// + /// Objeto con información del emisor del complemento. Requerido cuando el domicilio y CURP del emisor no se toman de la organización que emite el complemento. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Emisor + { + get => TryGetValue("Emisor", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["Emisor"] = value?.Value; + } + + /// + /// Propietario + /// Opcional. + /// + [JsonIgnore] + public List? Propietario + { + get => TryGetValue("Propietario", out var value) ? (List?)value! : default!; + set => this["Propietario"] = value; + } + + /// + /// Destinatario + /// Opcional. + /// + [JsonIgnore] + public List? Destinatario + { + get => TryGetValue("Destinatario", out var value) ? (List?)value! : default!; + set => this["Destinatario"] = value; + } + + /// + /// Mercancias + /// Requerido. + /// + [JsonIgnore] + public ComercioExteriorMercanciasInput Mercancias + { + get => TryGetValue("Mercancias", out var value) ? (ComercioExteriorMercanciasInput)value! : default!; + set => this["Mercancias"] = value; + } + + } +} diff --git a/Models/Inputs/ComercioExteriorDataInputDestinatarioItem.cs b/Models/Inputs/ComercioExteriorDataInputDestinatarioItem.cs new file mode 100644 index 0000000..bf99253 --- /dev/null +++ b/Models/Inputs/ComercioExteriorDataInputDestinatarioItem.cs @@ -0,0 +1,61 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorDataInputDestinatarioItem + /// + public class ComercioExteriorDataInputDestinatarioItem : Dictionary + { + /// + /// ID del objeto `customer` relacionado a la factura, en caso de no haber sido eliminado + /// Opcional. + /// + [JsonIgnore] + public string? Id + { + get => TryGetValue("id", out var value) ? (string?)value! : default!; + set => this["id"] = value; + } + + /// + /// Domicilio + /// Opcional. + /// + [JsonIgnore] + public List? Domicilio + { + get => TryGetValue("Domicilio", out var value) ? (List?)value! : default!; + set => this["Domicilio"] = value; + } + + /// + /// NumRegIdTrib + /// Opcional. + /// + [JsonIgnore] + public string? NumRegIdTrib + { + get => TryGetValue("NumRegIdTrib", out var value) ? (string?)value! : default!; + set => this["NumRegIdTrib"] = value; + } + + /// + /// Nombre + /// Opcional. + /// + [JsonIgnore] + public string? Nombre + { + get => TryGetValue("Nombre", out var value) ? (string?)value! : default!; + set => this["Nombre"] = value; + } + + } +} diff --git a/Models/Inputs/ComercioExteriorDataInputPropietarioItem.cs b/Models/Inputs/ComercioExteriorDataInputPropietarioItem.cs new file mode 100644 index 0000000..ecb68dd --- /dev/null +++ b/Models/Inputs/ComercioExteriorDataInputPropietarioItem.cs @@ -0,0 +1,50 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorDataInputPropietarioItem + /// + public class ComercioExteriorDataInputPropietarioItem : Dictionary + { + /// + /// NumRegIdTrib + /// Opcional. + /// + [JsonIgnore] + public string? NumRegIdTrib + { + get => TryGetValue("NumRegIdTrib", out var value) ? (string?)value! : default!; + set => this["NumRegIdTrib"] = value; + } + + /// + /// Clave del catálogo c_Pais. + /// Opcional. + /// + [JsonIgnore] + public string? ResidenciaFiscal + { + get => TryGetValue("ResidenciaFiscal", out var value) ? (string?)value! : default!; + set => this["ResidenciaFiscal"] = value; + } + + /// + /// ID del objeto `customer` relacionado a la factura, en caso de no haber sido eliminado + /// Opcional. + /// + [JsonIgnore] + public string? Id + { + get => TryGetValue("id", out var value) ? (string?)value! : default!; + set => this["id"] = value; + } + + } +} diff --git a/Models/Inputs/ComercioExteriorDescripcionesEspecificasInput.cs b/Models/Inputs/ComercioExteriorDescripcionesEspecificasInput.cs new file mode 100644 index 0000000..8688454 --- /dev/null +++ b/Models/Inputs/ComercioExteriorDescripcionesEspecificasInput.cs @@ -0,0 +1,70 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorDescripcionesEspecificasInput + /// + public class ComercioExteriorDescripcionesEspecificasInput : Dictionary + { + /// + /// Crea ComercioExteriorDescripcionesEspecificasInput. + /// + /// Marca Requerido. + public ComercioExteriorDescripcionesEspecificasInput(string @marca) + { + this["Marca"] = @marca; + } + + /// + /// Marca + /// Requerido. + /// + [JsonIgnore] + public string Marca + { + get => TryGetValue("Marca", out var value) ? (string)value! : default!; + set => this["Marca"] = value; + } + + /// + /// Modelo + /// Opcional. + /// + [JsonIgnore] + public string? Modelo + { + get => TryGetValue("Modelo", out var value) ? (string?)value! : default!; + set => this["Modelo"] = value; + } + + /// + /// SubModelo + /// Opcional. + /// + [JsonIgnore] + public string? SubModelo + { + get => TryGetValue("SubModelo", out var value) ? (string?)value! : default!; + set => this["SubModelo"] = value; + } + + /// + /// NumeroSerie + /// Opcional. + /// + [JsonIgnore] + public string? NumeroSerie + { + get => TryGetValue("NumeroSerie", out var value) ? (string?)value! : default!; + set => this["NumeroSerie"] = value; + } + + } +} diff --git a/Models/Inputs/ComercioExteriorDomicilioInput.cs b/Models/Inputs/ComercioExteriorDomicilioInput.cs new file mode 100644 index 0000000..7587209 --- /dev/null +++ b/Models/Inputs/ComercioExteriorDomicilioInput.cs @@ -0,0 +1,142 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorDomicilioInput + /// + public class ComercioExteriorDomicilioInput : Dictionary + { + /// + /// Crea ComercioExteriorDomicilioInput. + /// + /// Calle Requerido. + /// Estado Requerido. + /// Clave del catálogo c_Pais. Requerido. + /// CodigoPostal Requerido. + public ComercioExteriorDomicilioInput(string @calle, string @estado, string @pais, string @codigoPostal) + { + this["Calle"] = @calle; + this["Estado"] = @estado; + this["Pais"] = @pais; + this["CodigoPostal"] = @codigoPostal; + } + + /// + /// Calle + /// Requerido. + /// + [JsonIgnore] + public string Calle + { + get => TryGetValue("Calle", out var value) ? (string)value! : default!; + set => this["Calle"] = value; + } + + /// + /// NumeroExterior + /// Opcional. + /// + [JsonIgnore] + public string? NumeroExterior + { + get => TryGetValue("NumeroExterior", out var value) ? (string?)value! : default!; + set => this["NumeroExterior"] = value; + } + + /// + /// NumeroInterior + /// Opcional. + /// + [JsonIgnore] + public string? NumeroInterior + { + get => TryGetValue("NumeroInterior", out var value) ? (string?)value! : default!; + set => this["NumeroInterior"] = value; + } + + /// + /// Colonia + /// Opcional. + /// + [JsonIgnore] + public string? Colonia + { + get => TryGetValue("Colonia", out var value) ? (string?)value! : default!; + set => this["Colonia"] = value; + } + + /// + /// Localidad + /// Opcional. + /// + [JsonIgnore] + public string? Localidad + { + get => TryGetValue("Localidad", out var value) ? (string?)value! : default!; + set => this["Localidad"] = value; + } + + /// + /// Referencia + /// Opcional. + /// + [JsonIgnore] + public string? Referencia + { + get => TryGetValue("Referencia", out var value) ? (string?)value! : default!; + set => this["Referencia"] = value; + } + + /// + /// Municipio + /// Opcional. + /// + [JsonIgnore] + public string? Municipio + { + get => TryGetValue("Municipio", out var value) ? (string?)value! : default!; + set => this["Municipio"] = value; + } + + /// + /// Estado + /// Requerido. + /// + [JsonIgnore] + public string Estado + { + get => TryGetValue("Estado", out var value) ? (string)value! : default!; + set => this["Estado"] = value; + } + + /// + /// Clave del catálogo c_Pais. + /// Requerido. + /// + [JsonIgnore] + public string Pais + { + get => TryGetValue("Pais", out var value) ? (string)value! : default!; + set => this["Pais"] = value; + } + + /// + /// CodigoPostal + /// Requerido. + /// + [JsonIgnore] + public string CodigoPostal + { + get => TryGetValue("CodigoPostal", out var value) ? (string)value! : default!; + set => this["CodigoPostal"] = value; + } + + } +} diff --git a/Models/Inputs/ComercioExteriorEmisorInput.cs b/Models/Inputs/ComercioExteriorEmisorInput.cs new file mode 100644 index 0000000..f3b78a8 --- /dev/null +++ b/Models/Inputs/ComercioExteriorEmisorInput.cs @@ -0,0 +1,48 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorEmisorInput + /// + public class ComercioExteriorEmisorInput : Dictionary + { + /// + /// Crea ComercioExteriorEmisorInput. + /// + /// Domicilio Requerido. + public ComercioExteriorEmisorInput(ComercioExteriorDomicilioInput @domicilio) + { + this["Domicilio"] = @domicilio; + } + + /// + /// Domicilio + /// Requerido. + /// + [JsonIgnore] + public ComercioExteriorDomicilioInput Domicilio + { + get => TryGetValue("Domicilio", out var value) ? (ComercioExteriorDomicilioInput)value! : default!; + set => this["Domicilio"] = value; + } + + /// + /// Curp + /// Opcional. + /// + [JsonIgnore] + public string? Curp + { + get => TryGetValue("Curp", out var value) ? (string?)value! : default!; + set => this["Curp"] = value; + } + + } +} diff --git a/Models/Inputs/ComercioExteriorInput.cs b/Models/Inputs/ComercioExteriorInput.cs new file mode 100644 index 0000000..f38c2dc --- /dev/null +++ b/Models/Inputs/ComercioExteriorInput.cs @@ -0,0 +1,48 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorInput + /// + public class ComercioExteriorInput : InvoiceComplementInput + { + /// + /// Crea ComercioExteriorInput. + /// + public ComercioExteriorInput() : base("comercio_exterior") + { + this["type"] = "comercio_exterior"; + } + + /// + /// type + /// Valores: "comercio_exterior". + /// Requerido. + /// + [JsonIgnore] + public new string Type + { + get => TryGetValue("type", out var value) ? (string)value! : default!; + set => this["type"] = value; + } + + /// + /// data + /// Opcional. + /// + [JsonIgnore] + public new ComercioExteriorDataInput? Data + { + get => TryGetValue("data", out var value) ? (ComercioExteriorDataInput?)value! : default!; + set => this["data"] = value; + } + + } +} diff --git a/Models/Inputs/ComercioExteriorMercanciaInput.cs b/Models/Inputs/ComercioExteriorMercanciaInput.cs new file mode 100644 index 0000000..2cccdbe --- /dev/null +++ b/Models/Inputs/ComercioExteriorMercanciaInput.cs @@ -0,0 +1,105 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorMercanciaInput + /// + public class ComercioExteriorMercanciaInput : Dictionary + { + /// + /// Crea ComercioExteriorMercanciaInput. + /// + /// NoIdentificacion Requerido. + /// ValorDolares Requerido. + public ComercioExteriorMercanciaInput(string @noIdentificacion, decimal @valorDolares) + { + this["NoIdentificacion"] = @noIdentificacion; + this["ValorDolares"] = @valorDolares; + } + + /// + /// DescripcionesEspecificas + /// Opcional. + /// + [JsonIgnore] + public List? DescripcionesEspecificas + { + get => TryGetValue("DescripcionesEspecificas", out var value) ? (List?)value! : default!; + set => this["DescripcionesEspecificas"] = value; + } + + /// + /// NoIdentificacion + /// Requerido. + /// + [JsonIgnore] + public string NoIdentificacion + { + get => TryGetValue("NoIdentificacion", out var value) ? (string)value! : default!; + set => this["NoIdentificacion"] = value; + } + + /// + /// Clave del catálogo c_FraccionArancelaria. + /// Opcional. + /// + [JsonIgnore] + public string? FraccionArancelaria + { + get => TryGetValue("FraccionArancelaria", out var value) ? (string?)value! : default!; + set => this["FraccionArancelaria"] = value; + } + + /// + /// CantidadAduana + /// Opcional. + /// + [JsonIgnore] + public decimal? CantidadAduana + { + get => TryGetValue("CantidadAduana", out var value) ? (decimal?)value! : default!; + set => this["CantidadAduana"] = value; + } + + /// + /// Clave del catálogo c_UnidadAduana. + /// Opcional. + /// + [JsonIgnore] + public string? UnidadAduana + { + get => TryGetValue("UnidadAduana", out var value) ? (string?)value! : default!; + set => this["UnidadAduana"] = value; + } + + /// + /// ValorUnitarioAduana + /// Opcional. + /// + [JsonIgnore] + public decimal? ValorUnitarioAduana + { + get => TryGetValue("ValorUnitarioAduana", out var value) ? (decimal?)value! : default!; + set => this["ValorUnitarioAduana"] = value; + } + + /// + /// ValorDolares + /// Requerido. + /// + [JsonIgnore] + public decimal ValorDolares + { + get => TryGetValue("ValorDolares", out var value) ? (decimal)value! : default!; + set => this["ValorDolares"] = value; + } + + } +} diff --git a/Models/Inputs/ComercioExteriorMercanciasInput.cs b/Models/Inputs/ComercioExteriorMercanciasInput.cs new file mode 100644 index 0000000..b495ad5 --- /dev/null +++ b/Models/Inputs/ComercioExteriorMercanciasInput.cs @@ -0,0 +1,37 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorMercanciasInput + /// + public class ComercioExteriorMercanciasInput : Dictionary + { + /// + /// Crea ComercioExteriorMercanciasInput. + /// + /// Mercancia Requerido. + public ComercioExteriorMercanciasInput(List @mercancia) + { + this["Mercancia"] = @mercancia; + } + + /// + /// Mercancia + /// Requerido. + /// + [JsonIgnore] + public List Mercancia + { + get => TryGetValue("Mercancia", out var value) ? (List)value! : default!; + set => this["Mercancia"] = value; + } + + } +} diff --git a/Models/Inputs/ComercioExteriorReceptorInput.cs b/Models/Inputs/ComercioExteriorReceptorInput.cs new file mode 100644 index 0000000..4c736dc --- /dev/null +++ b/Models/Inputs/ComercioExteriorReceptorInput.cs @@ -0,0 +1,39 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ComercioExteriorReceptorInput + /// + public class ComercioExteriorReceptorInput : Dictionary + { + /// + /// Domicilio + /// Opcional. + /// + [JsonIgnore] + public ComercioExteriorDomicilioInput? Domicilio + { + get => TryGetValue("Domicilio", out var value) ? (ComercioExteriorDomicilioInput?)value! : default!; + set => this["Domicilio"] = value; + } + + /// + /// NumRegIdTrib + /// Opcional. + /// + [JsonIgnore] + public string? NumRegIdTrib + { + get => TryGetValue("NumRegIdTrib", out var value) ? (string?)value! : default!; + set => this["NumRegIdTrib"] = value; + } + + } +} diff --git a/Models/Inputs/CustomComplementInput.cs b/Models/Inputs/CustomComplementInput.cs new file mode 100644 index 0000000..ef54d9e --- /dev/null +++ b/Models/Inputs/CustomComplementInput.cs @@ -0,0 +1,50 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CustomComplement + /// + public class CustomComplementInput : InvoiceComplementInput + { + /// + /// Crea CustomComplementInput. + /// + /// data Requerido. + public CustomComplementInput(string @data) : base("custom") + { + this["data"] = @data; + this["type"] = "custom"; + } + + /// + /// Tipo de complemento. + /// Valores: "custom". + /// Requerido. + /// + [JsonIgnore] + public new string Type + { + get => TryGetValue("type", out var value) ? (string)value! : default!; + set => this["type"] = value; + } + + /// + /// data + /// Requerido. + /// + [JsonIgnore] + public new string Data + { + get => TryGetValue("data", out var value) ? (string)value! : default!; + set => this["data"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerComercioExteriorInput.cs b/Models/Inputs/CustomerComercioExteriorInput.cs new file mode 100644 index 0000000..019d88b --- /dev/null +++ b/Models/Inputs/CustomerComercioExteriorInput.cs @@ -0,0 +1,28 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Objeto con información parcial del cliente receptor del comprobante. Para obtener el objeto `Customer` completo, deberás consultarlo con el método de [Obtener Cliente]('#/operation/getCustomer'). + /// + public class CustomerComercioExteriorInput : Dictionary + { + /// + /// ID del objeto `customer` relacionado a la factura, en caso de no haber sido eliminado + /// Opcional. + /// + [JsonIgnore] + public string? Id + { + get => TryGetValue("id", out var value) ? (string?)value! : default!; + set => this["id"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerCreateCommonInput.cs b/Models/Inputs/CustomerCreateCommonInput.cs new file mode 100644 index 0000000..fe24d10 --- /dev/null +++ b/Models/Inputs/CustomerCreateCommonInput.cs @@ -0,0 +1,73 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CustomerCreateCommonInput + /// + public class CustomerCreateCommonInput : Dictionary + { + /// + /// Crea CustomerCreateCommonInput. + /// + /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). Requerido. + public CustomerCreateCommonInput(string @legalName) + { + this["legal_name"] = @legalName; + } + + /// + /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). + /// Requerido. + /// + [JsonIgnore] + public string LegalName + { + get => TryGetValue("legal_name", out var value) ? (string)value! : default!; + set => this["legal_name"] = value; + } + + /// + /// Format: email + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Email + { + get => TryGetValue("email", out var value) ? (string?)value! : default!; + set => this["email"] = value; + } + + /// + /// Teléfono del cliente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Phone + { + get => TryGetValue("phone", out var value) ? (string?)value! : default!; + set => this["phone"] = value; + } + + /// + /// Uso de CFDI que se utiliza en facturas de ingreso cuando se omite use o se envía null. Si el cliente no tiene un uso configurado, se utiliza G03. Para clientes extranjeros o con RFC genérico sólo se admite S01; omitirlo, enviar null o una cadena vacía asigna S01. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? DefaultInvoiceUse + { + get => TryGetValue("default_invoice_use", out var value) ? (string?)value! : default!; + set => this["default_invoice_use"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerCreateInput.cs b/Models/Inputs/CustomerCreateInput.cs new file mode 100644 index 0000000..3f3599e --- /dev/null +++ b/Models/Inputs/CustomerCreateInput.cs @@ -0,0 +1,114 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Los campos requeridos dependen del país y del RFC. Omitir el país equivale a México. Con createEditLink=true se usa CustomerCreateWithEditLinkInput. + /// + public class CustomerCreateInput : Dictionary + { + /// + /// Crea CustomerCreateInput. + /// + /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). Nombre fiscal o razón social del receptor, sin el régimen societario (ej.: S.A. de C.V.). Para una factura individual con RFC genérico, envía el nombre del receptor y omite global. Para una factura global de ingreso, usa PUBLICO EN GENERAL con el RFC XAXX010101000 y envía global con periodicity, months y year. Requerido. + public CustomerCreateInput(string @legalName) + { + this["legal_name"] = @legalName; + } + + /// + /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). + /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). + /// Nombre fiscal o razón social del receptor, sin el régimen societario (ej.: S.A. de C.V.). Para una factura individual con RFC genérico, envía el nombre del receptor y omite global. Para una factura global de ingreso, usa PUBLICO EN GENERAL con el RFC XAXX010101000 y envía global con periodicity, months y year. + /// Requerido. + /// + [JsonIgnore] + public string LegalName + { + get => TryGetValue("legal_name", out var value) ? (string)value! : default!; + set => this["legal_name"] = value; + } + + /// + /// Format: email + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Email + { + get => TryGetValue("email", out var value) ? (string?)value! : default!; + set => this["email"] = value; + } + + /// + /// Teléfono del cliente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Phone + { + get => TryGetValue("phone", out var value) ? (string?)value! : default!; + set => this["phone"] = value; + } + + /// + /// Uso de CFDI que se utiliza en facturas de ingreso cuando se omite use o se envía null. Si el cliente no tiene un uso configurado, se utiliza G03. Para clientes extranjeros o con RFC genérico sólo se admite S01; omitirlo, enviar null o una cadena vacía asigna S01. + /// Uso de CFDI que se utiliza en facturas de ingreso cuando se omite use o se envía null. Si el cliente no tiene un uso configurado, se utiliza G03. Para clientes extranjeros o con RFC genérico sólo se admite S01; omitirlo, enviar null o una cadena vacía asigna S01. + /// Sólo se admite S01. Omitirlo, enviar null o una cadena vacía asigna S01. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? DefaultInvoiceUse + { + get => TryGetValue("default_invoice_use", out var value) ? (string?)value! : default!; + set => this["default_invoice_use"] = value; + } + + /// + /// En clientes de México contiene el RFC del cliente. Para extranjeros es opcional y representa el número de registro de identificación tributaria, es decir, el equivalente al RFC en el país del cliente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? TaxId + { + get => TryGetValue("tax_id", out var value) ? (string?)value! : default!; + set => this["tax_id"] = value; + } + + /// + /// Requerido para clientes nacionales. Clave del régimen fiscal del cliente, del catálogo de [Regímenes Fiscales](https://docs.facturapi.io/api/#r%C3%A9gimen-fiscal). + /// Los clientes extranjeros usan 616. Omitirlo, enviar null o una cadena vacía usa el valor predeterminado. + /// Régimen fiscal del receptor. Con RFC genérico, si se omite se utiliza 616 (Sin obligaciones fiscales); si se envía explícitamente, sólo se admite 616. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? TaxSystem + { + get => TryGetValue("tax_system", out var value) ? (string?)value! : default!; + set => this["tax_system"] = value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public OneOf? Address + { + get => TryGetValue("address", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["address"] = value?.Value; + } + + } +} diff --git a/Models/Inputs/CustomerCreateParams.cs b/Models/Inputs/CustomerCreateParams.cs index 1dd33f9..95ceca9 100644 --- a/Models/Inputs/CustomerCreateParams.cs +++ b/Models/Inputs/CustomerCreateParams.cs @@ -1,14 +1,17 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// /// CustomerCreateParams /// - public class CustomerCreateParams : Dictionary + public class CustomerCreateParams : Dictionary { /// /// Si pasas el valor `true`, se generará un enlace para que el cliente pueda editar @@ -22,7 +25,7 @@ public class CustomerCreateParams : Dictionary [JsonIgnore] public bool? CreateEditLink { - get => TryGetValue("createEditLink", out var value) ? (bool?)value : default; + get => TryGetValue("createEditLink", out var value) ? (bool?)value! : default!; set => this["createEditLink"] = value; } diff --git a/Models/Inputs/CustomerCreateWithEditLinkInput.cs b/Models/Inputs/CustomerCreateWithEditLinkInput.cs index eff1fa0..0ee3799 100644 --- a/Models/Inputs/CustomerCreateWithEditLinkInput.cs +++ b/Models/Inputs/CustomerCreateWithEditLinkInput.cs @@ -1,14 +1,17 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// /// La información del cliente puede estar incompleta cuando createEditLink=true. Los campos opcionales con valor null se tratan como omitidos. Los valores no nulos deben conservar formatos válidos. /// - public class CustomerCreateWithEditLinkInput : Dictionary + public class CustomerCreateWithEditLinkInput : Dictionary { /// /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). @@ -16,9 +19,9 @@ public class CustomerCreateWithEditLinkInput : Dictionary /// Admite null. /// [JsonIgnore] - public string LegalName + public string? LegalName { - get => TryGetValue("legal_name", out var value) ? (string)value : default; + get => TryGetValue("legal_name", out var value) ? (string?)value! : default!; set => this["legal_name"] = value; } @@ -28,9 +31,9 @@ public string LegalName /// Admite null. /// [JsonIgnore] - public string TaxId + public string? TaxId { - get => TryGetValue("tax_id", out var value) ? (string)value : default; + get => TryGetValue("tax_id", out var value) ? (string?)value! : default!; set => this["tax_id"] = value; } @@ -40,9 +43,9 @@ public string TaxId /// Admite null. /// [JsonIgnore] - public string Email + public string? Email { - get => TryGetValue("email", out var value) ? (string)value : default; + get => TryGetValue("email", out var value) ? (string?)value! : default!; set => this["email"] = value; } @@ -52,9 +55,9 @@ public string Email /// Admite null. /// [JsonIgnore] - public string Phone + public string? Phone { - get => TryGetValue("phone", out var value) ? (string)value : default; + get => TryGetValue("phone", out var value) ? (string?)value! : default!; set => this["phone"] = value; } @@ -64,9 +67,9 @@ public string Phone /// Admite null. /// [JsonIgnore] - public string ExternalId + public string? ExternalId { - get => TryGetValue("external_id", out var value) ? (string)value : default; + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; set => this["external_id"] = value; } @@ -76,9 +79,9 @@ public string ExternalId /// Admite null. /// [JsonIgnore] - public string DefaultInvoiceUse + public string? DefaultInvoiceUse { - get => TryGetValue("default_invoice_use", out var value) ? (string)value : default; + get => TryGetValue("default_invoice_use", out var value) ? (string?)value! : default!; set => this["default_invoice_use"] = value; } @@ -88,9 +91,9 @@ public string DefaultInvoiceUse /// Admite null. /// [JsonIgnore] - public string TaxSystem + public string? TaxSystem { - get => TryGetValue("tax_system", out var value) ? (string)value : default; + get => TryGetValue("tax_system", out var value) ? (string?)value! : default!; set => this["tax_system"] = value; } @@ -100,9 +103,9 @@ public string TaxSystem /// Admite null. /// [JsonIgnore] - public CustomerCreateWithEditLinkInputAddress Address + public CustomerCreateWithEditLinkInputAddress? Address { - get => TryGetValue("address", out var value) ? (CustomerCreateWithEditLinkInputAddress)value : default; + get => TryGetValue("address", out var value) ? (CustomerCreateWithEditLinkInputAddress?)value! : default!; set => this["address"] = value; } diff --git a/Models/Inputs/CustomerCreateWithEditLinkInputAddress.cs b/Models/Inputs/CustomerCreateWithEditLinkInputAddress.cs index 63b0931..1e7c619 100644 --- a/Models/Inputs/CustomerCreateWithEditLinkInputAddress.cs +++ b/Models/Inputs/CustomerCreateWithEditLinkInputAddress.cs @@ -1,14 +1,17 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// /// CustomerCreateWithEditLinkInputAddress /// - public class CustomerCreateWithEditLinkInputAddress : Dictionary + public class CustomerCreateWithEditLinkInputAddress : Dictionary { /// /// Nombre de la calle @@ -16,9 +19,9 @@ public class CustomerCreateWithEditLinkInputAddress : Dictionary /// Admite null. /// [JsonIgnore] - public string Street + public string? Street { - get => TryGetValue("street", out var value) ? (string)value : default; + get => TryGetValue("street", out var value) ? (string?)value! : default!; set => this["street"] = value; } @@ -28,9 +31,9 @@ public string Street /// Admite null. /// [JsonIgnore] - public string Exterior + public string? Exterior { - get => TryGetValue("exterior", out var value) ? (string)value : default; + get => TryGetValue("exterior", out var value) ? (string?)value! : default!; set => this["exterior"] = value; } @@ -40,9 +43,9 @@ public string Exterior /// Admite null. /// [JsonIgnore] - public string Interior + public string? Interior { - get => TryGetValue("interior", out var value) ? (string)value : default; + get => TryGetValue("interior", out var value) ? (string?)value! : default!; set => this["interior"] = value; } @@ -52,9 +55,9 @@ public string Interior /// Admite null. /// [JsonIgnore] - public string Neighborhood + public string? Neighborhood { - get => TryGetValue("neighborhood", out var value) ? (string)value : default; + get => TryGetValue("neighborhood", out var value) ? (string?)value! : default!; set => this["neighborhood"] = value; } @@ -64,9 +67,9 @@ public string Neighborhood /// Admite null. /// [JsonIgnore] - public string City + public string? City { - get => TryGetValue("city", out var value) ? (string)value : default; + get => TryGetValue("city", out var value) ? (string?)value! : default!; set => this["city"] = value; } @@ -76,9 +79,9 @@ public string City /// Admite null. /// [JsonIgnore] - public string Municipality + public string? Municipality { - get => TryGetValue("municipality", out var value) ? (string)value : default; + get => TryGetValue("municipality", out var value) ? (string?)value! : default!; set => this["municipality"] = value; } @@ -88,9 +91,9 @@ public string Municipality /// Admite null. /// [JsonIgnore] - public string State + public string? State { - get => TryGetValue("state", out var value) ? (string)value : default; + get => TryGetValue("state", out var value) ? (string?)value! : default!; set => this["state"] = value; } @@ -100,9 +103,9 @@ public string State /// Admite null. /// [JsonIgnore] - public string Country + public string? Country { - get => TryGetValue("country", out var value) ? (string)value : default; + get => TryGetValue("country", out var value) ? (string?)value! : default!; set => this["country"] = value; } @@ -112,9 +115,9 @@ public string Country /// Admite null. /// [JsonIgnore] - public string Zip + public string? Zip { - get => TryGetValue("zip", out var value) ? (string)value : default; + get => TryGetValue("zip", out var value) ? (string?)value! : default!; set => this["zip"] = value; } diff --git a/Models/Inputs/CustomerEditableInput.cs b/Models/Inputs/CustomerEditableInput.cs new file mode 100644 index 0000000..cd9e71e --- /dev/null +++ b/Models/Inputs/CustomerEditableInput.cs @@ -0,0 +1,101 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CustomerEditableInput + /// + public class CustomerEditableInput : Dictionary + { + /// + /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? LegalName + { + get => TryGetValue("legal_name", out var value) ? (string?)value! : default!; + set => this["legal_name"] = value; + } + + /// + /// En clientes de México contiene el RFC del cliente. Para extranjeros es opcional y representa el número de registro de identificación tributaria, es decir, el equivalente al RFC en el país del cliente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? TaxId + { + get => TryGetValue("tax_id", out var value) ? (string?)value! : default!; + set => this["tax_id"] = value; + } + + /// + /// email + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Email + { + get => TryGetValue("email", out var value) ? (string?)value! : default!; + set => this["email"] = value; + } + + /// + /// Teléfono del cliente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Phone + { + get => TryGetValue("phone", out var value) ? (string?)value! : default!; + set => this["phone"] = value; + } + + /// + /// external_id + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Uso de CFDI que se utiliza en facturas de ingreso cuando se omite use o se envía null. Si el cliente no tiene un uso configurado, se utiliza G03. Para clientes extranjeros o con RFC genérico sólo se admite S01; omitirlo, enviar null o una cadena vacía asigna S01. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? DefaultInvoiceUse + { + get => TryGetValue("default_invoice_use", out var value) ? (string?)value! : default!; + set => this["default_invoice_use"] = value; + } + + /// + /// address + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public CustomerEditableInputAddress? Address + { + get => TryGetValue("address", out var value) ? (CustomerEditableInputAddress?)value! : default!; + set => this["address"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerEditableInputAddress.cs b/Models/Inputs/CustomerEditableInputAddress.cs new file mode 100644 index 0000000..de61f6a --- /dev/null +++ b/Models/Inputs/CustomerEditableInputAddress.cs @@ -0,0 +1,124 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// CustomerEditableInputAddress + /// + public class CustomerEditableInputAddress : Dictionary + { + /// + /// Nombre de la calle + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Street + { + get => TryGetValue("street", out var value) ? (string?)value! : default!; + set => this["street"] = value; + } + + /// + /// Número exterior. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Exterior + { + get => TryGetValue("exterior", out var value) ? (string?)value! : default!; + set => this["exterior"] = value; + } + + /// + /// Número interior. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Interior + { + get => TryGetValue("interior", out var value) ? (string?)value! : default!; + set => this["interior"] = value; + } + + /// + /// Colonia + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Neighborhood + { + get => TryGetValue("neighborhood", out var value) ? (string?)value! : default!; + set => this["neighborhood"] = value; + } + + /// + /// Ciudad + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? City + { + get => TryGetValue("city", out var value) ? (string?)value! : default!; + set => this["city"] = value; + } + + /// + /// Municipio o delegación + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Municipality + { + get => TryGetValue("municipality", out var value) ? (string?)value! : default!; + set => this["municipality"] = value; + } + + /// + /// Código postal + /// Opcional. + /// + [JsonIgnore] + public string? Zip + { + get => TryGetValue("zip", out var value) ? (string?)value! : default!; + set => this["zip"] = value; + } + + /// + /// state + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? State + { + get => TryGetValue("state", out var value) ? (string?)value! : default!; + set => this["state"] = value; + } + + /// + /// ISO 3166-1 alpha-3. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Country + { + get => TryGetValue("country", out var value) ? (string?)value! : default!; + set => this["country"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerForeignAddressInput.cs b/Models/Inputs/CustomerForeignAddressInput.cs index f8df57c..9b3ba3a 100644 --- a/Models/Inputs/CustomerForeignAddressInput.cs +++ b/Models/Inputs/CustomerForeignAddressInput.cs @@ -1,22 +1,25 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// /// CustomerForeignAddressInput /// - public class CustomerForeignAddressInput : Dictionary + public class CustomerForeignAddressInput : Dictionary { /// /// Crea CustomerForeignAddressInput. /// /// Código ISO 3166-1 alpha-3 distinto de MEX. Es necesario para aplicar las reglas de cliente extranjero. Requerido. - public CustomerForeignAddressInput(string country) + public CustomerForeignAddressInput(string @country) { - this["country"] = country; + this["country"] = @country; } /// @@ -24,9 +27,9 @@ public CustomerForeignAddressInput(string country) /// Opcional. /// [JsonIgnore] - public string Street + public string? Street { - get => TryGetValue("street", out var value) ? (string)value : default; + get => TryGetValue("street", out var value) ? (string?)value! : default!; set => this["street"] = value; } @@ -35,9 +38,9 @@ public string Street /// Opcional. /// [JsonIgnore] - public string Exterior + public string? Exterior { - get => TryGetValue("exterior", out var value) ? (string)value : default; + get => TryGetValue("exterior", out var value) ? (string?)value! : default!; set => this["exterior"] = value; } @@ -46,9 +49,9 @@ public string Exterior /// Opcional. /// [JsonIgnore] - public string Interior + public string? Interior { - get => TryGetValue("interior", out var value) ? (string)value : default; + get => TryGetValue("interior", out var value) ? (string?)value! : default!; set => this["interior"] = value; } @@ -57,9 +60,9 @@ public string Interior /// Opcional. /// [JsonIgnore] - public string Neighborhood + public string? Neighborhood { - get => TryGetValue("neighborhood", out var value) ? (string)value : default; + get => TryGetValue("neighborhood", out var value) ? (string?)value! : default!; set => this["neighborhood"] = value; } @@ -68,9 +71,9 @@ public string Neighborhood /// Opcional. /// [JsonIgnore] - public string City + public string? City { - get => TryGetValue("city", out var value) ? (string)value : default; + get => TryGetValue("city", out var value) ? (string?)value! : default!; set => this["city"] = value; } @@ -79,9 +82,9 @@ public string City /// Opcional. /// [JsonIgnore] - public string Municipality + public string? Municipality { - get => TryGetValue("municipality", out var value) ? (string)value : default; + get => TryGetValue("municipality", out var value) ? (string?)value! : default!; set => this["municipality"] = value; } @@ -90,9 +93,9 @@ public string Municipality /// Opcional. /// [JsonIgnore] - public string Zip + public string? Zip { - get => TryGetValue("zip", out var value) ? (string)value : default; + get => TryGetValue("zip", out var value) ? (string?)value! : default!; set => this["zip"] = value; } @@ -103,7 +106,7 @@ public string Zip [JsonIgnore] public string Country { - get => TryGetValue("country", out var value) ? (string)value : default; + get => TryGetValue("country", out var value) ? (string)value! : default!; set => this["country"] = value; } @@ -112,9 +115,9 @@ public string Country /// Opcional. /// [JsonIgnore] - public string State + public string? State { - get => TryGetValue("state", out var value) ? (string)value : default; + get => TryGetValue("state", out var value) ? (string?)value! : default!; set => this["state"] = value; } diff --git a/Models/Inputs/CustomerForeignCreateInput.cs b/Models/Inputs/CustomerForeignCreateInput.cs index 6f56f0a..239443d 100644 --- a/Models/Inputs/CustomerForeignCreateInput.cs +++ b/Models/Inputs/CustomerForeignCreateInput.cs @@ -1,24 +1,27 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// /// Requiere razón social y domicilio con un país explícito distinto de MEX. El identificador fiscal y el código postal son opcionales; el régimen fiscal predeterminado es 616. /// - public class CustomerForeignCreateInput : Dictionary + public class CustomerForeignCreateInput : CustomerCreateInput { /// /// Crea CustomerForeignCreateInput. /// /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). Requerido. /// address Requerido. - public CustomerForeignCreateInput(string legalName, CustomerForeignAddressInput address) + public CustomerForeignCreateInput(string @legalName, CustomerForeignAddressInput @address) : base(@legalName) { - this["legal_name"] = legalName; - this["address"] = address; + this["legal_name"] = @legalName; + this["address"] = @address; } /// @@ -26,9 +29,9 @@ public CustomerForeignCreateInput(string legalName, CustomerForeignAddressInput /// Requerido. /// [JsonIgnore] - public string LegalName + public new string LegalName { - get => TryGetValue("legal_name", out var value) ? (string)value : default; + get => TryGetValue("legal_name", out var value) ? (string)value! : default!; set => this["legal_name"] = value; } @@ -38,9 +41,9 @@ public string LegalName /// Admite null. /// [JsonIgnore] - public string Email + public new string? Email { - get => TryGetValue("email", out var value) ? (string)value : default; + get => TryGetValue("email", out var value) ? (string?)value! : default!; set => this["email"] = value; } @@ -50,9 +53,9 @@ public string Email /// Admite null. /// [JsonIgnore] - public string Phone + public new string? Phone { - get => TryGetValue("phone", out var value) ? (string)value : default; + get => TryGetValue("phone", out var value) ? (string?)value! : default!; set => this["phone"] = value; } @@ -64,9 +67,9 @@ public string Phone /// Admite null. /// [JsonIgnore] - public string DefaultInvoiceUse + public new string? DefaultInvoiceUse { - get => TryGetValue("default_invoice_use", out var value) ? (string)value : default; + get => TryGetValue("default_invoice_use", out var value) ? (string?)value! : default!; set => this["default_invoice_use"] = value; } @@ -76,9 +79,9 @@ public string DefaultInvoiceUse /// Admite null. /// [JsonIgnore] - public string TaxId + public new string? TaxId { - get => TryGetValue("tax_id", out var value) ? (string)value : default; + get => TryGetValue("tax_id", out var value) ? (string?)value! : default!; set => this["tax_id"] = value; } @@ -89,9 +92,9 @@ public string TaxId /// Admite null. /// [JsonIgnore] - public string TaxSystem + public new string? TaxSystem { - get => TryGetValue("tax_system", out var value) ? (string)value : default; + get => TryGetValue("tax_system", out var value) ? (string?)value! : default!; set => this["tax_system"] = value; } @@ -100,9 +103,9 @@ public string TaxSystem /// Requerido. /// [JsonIgnore] - public CustomerForeignAddressInput Address + public new CustomerForeignAddressInput Address { - get => TryGetValue("address", out var value) ? (CustomerForeignAddressInput)value : default; + get => TryGetValue("address", out var value) ? (CustomerForeignAddressInput)value! : default!; set => this["address"] = value; } diff --git a/Models/Inputs/CustomerGenericCreateInput.cs b/Models/Inputs/CustomerGenericCreateInput.cs index 4e1bab6..bb7a37a 100644 --- a/Models/Inputs/CustomerGenericCreateInput.cs +++ b/Models/Inputs/CustomerGenericCreateInput.cs @@ -1,24 +1,27 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// /// RFC de público en general XAXX010101000 o RFC genérico extranjero XEXX010101000. Requiere razón social y RFC. El régimen fiscal predeterminado es 616. El código postal es opcional; null o una cadena vacía se tratan como omitidos. /// - public class CustomerGenericCreateInput : Dictionary + public class CustomerGenericCreateInput : CustomerCreateInput { /// /// Crea CustomerGenericCreateInput. /// /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). Nombre fiscal o razón social del receptor, sin el régimen societario (ej.: S.A. de C.V.). Para una factura individual con RFC genérico, envía el nombre del receptor y omite global. Para una factura global de ingreso, usa PUBLICO EN GENERAL con el RFC XAXX010101000 y envía global con periodicity, months y year. Requerido. /// tax_id Valores: "XAXX010101000", "XEXX010101000". Requerido. - public CustomerGenericCreateInput(string legalName, string taxId) + public CustomerGenericCreateInput(string @legalName, string @taxId) : base(@legalName) { - this["legal_name"] = legalName; - this["tax_id"] = taxId; + this["legal_name"] = @legalName; + this["tax_id"] = @taxId; } /// @@ -27,9 +30,9 @@ public CustomerGenericCreateInput(string legalName, string taxId) /// Requerido. /// [JsonIgnore] - public string LegalName + public new string LegalName { - get => TryGetValue("legal_name", out var value) ? (string)value : default; + get => TryGetValue("legal_name", out var value) ? (string)value! : default!; set => this["legal_name"] = value; } @@ -39,9 +42,9 @@ public string LegalName /// Admite null. /// [JsonIgnore] - public string Email + public new string? Email { - get => TryGetValue("email", out var value) ? (string)value : default; + get => TryGetValue("email", out var value) ? (string?)value! : default!; set => this["email"] = value; } @@ -51,9 +54,9 @@ public string Email /// Admite null. /// [JsonIgnore] - public string Phone + public new string? Phone { - get => TryGetValue("phone", out var value) ? (string)value : default; + get => TryGetValue("phone", out var value) ? (string?)value! : default!; set => this["phone"] = value; } @@ -65,9 +68,9 @@ public string Phone /// Admite null. /// [JsonIgnore] - public string DefaultInvoiceUse + public new string? DefaultInvoiceUse { - get => TryGetValue("default_invoice_use", out var value) ? (string)value : default; + get => TryGetValue("default_invoice_use", out var value) ? (string?)value! : default!; set => this["default_invoice_use"] = value; } @@ -77,9 +80,9 @@ public string DefaultInvoiceUse /// Requerido. /// [JsonIgnore] - public string TaxId + public new string TaxId { - get => TryGetValue("tax_id", out var value) ? (string)value : default; + get => TryGetValue("tax_id", out var value) ? (string)value! : default!; set => this["tax_id"] = value; } @@ -89,9 +92,9 @@ public string TaxId /// Opcional. /// [JsonIgnore] - public string TaxSystem + public new string? TaxSystem { - get => TryGetValue("tax_system", out var value) ? (string)value : default; + get => TryGetValue("tax_system", out var value) ? (string?)value! : default!; set => this["tax_system"] = value; } @@ -100,9 +103,9 @@ public string TaxSystem /// Opcional. /// [JsonIgnore] - public CustomerGenericCreateInputAddress Address + public new CustomerGenericCreateInputAddress? Address { - get => TryGetValue("address", out var value) ? (CustomerGenericCreateInputAddress)value : default; + get => TryGetValue("address", out var value) ? (CustomerGenericCreateInputAddress?)value! : default!; set => this["address"] = value; } diff --git a/Models/Inputs/CustomerGenericCreateInputAddress.cs b/Models/Inputs/CustomerGenericCreateInputAddress.cs index 63269f6..2524d3b 100644 --- a/Models/Inputs/CustomerGenericCreateInputAddress.cs +++ b/Models/Inputs/CustomerGenericCreateInputAddress.cs @@ -1,14 +1,17 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// /// CustomerGenericCreateInputAddress /// - public class CustomerGenericCreateInputAddress : Dictionary + public class CustomerGenericCreateInputAddress : Dictionary { /// /// Nombre de la calle @@ -16,9 +19,9 @@ public class CustomerGenericCreateInputAddress : Dictionary /// Admite null. /// [JsonIgnore] - public string Street + public string? Street { - get => TryGetValue("street", out var value) ? (string)value : default; + get => TryGetValue("street", out var value) ? (string?)value! : default!; set => this["street"] = value; } @@ -28,9 +31,9 @@ public string Street /// Admite null. /// [JsonIgnore] - public string Exterior + public string? Exterior { - get => TryGetValue("exterior", out var value) ? (string)value : default; + get => TryGetValue("exterior", out var value) ? (string?)value! : default!; set => this["exterior"] = value; } @@ -40,9 +43,9 @@ public string Exterior /// Admite null. /// [JsonIgnore] - public string Interior + public string? Interior { - get => TryGetValue("interior", out var value) ? (string)value : default; + get => TryGetValue("interior", out var value) ? (string?)value! : default!; set => this["interior"] = value; } @@ -52,9 +55,9 @@ public string Interior /// Admite null. /// [JsonIgnore] - public string Neighborhood + public string? Neighborhood { - get => TryGetValue("neighborhood", out var value) ? (string)value : default; + get => TryGetValue("neighborhood", out var value) ? (string?)value! : default!; set => this["neighborhood"] = value; } @@ -64,9 +67,9 @@ public string Neighborhood /// Admite null. /// [JsonIgnore] - public string City + public string? City { - get => TryGetValue("city", out var value) ? (string)value : default; + get => TryGetValue("city", out var value) ? (string?)value! : default!; set => this["city"] = value; } @@ -76,9 +79,9 @@ public string City /// Admite null. /// [JsonIgnore] - public string Municipality + public string? Municipality { - get => TryGetValue("municipality", out var value) ? (string)value : default; + get => TryGetValue("municipality", out var value) ? (string?)value! : default!; set => this["municipality"] = value; } @@ -88,9 +91,9 @@ public string Municipality /// Admite null. /// [JsonIgnore] - public string State + public string? State { - get => TryGetValue("state", out var value) ? (string)value : default; + get => TryGetValue("state", out var value) ? (string?)value! : default!; set => this["state"] = value; } @@ -100,9 +103,9 @@ public string State /// Admite null. /// [JsonIgnore] - public string Country + public string? Country { - get => TryGetValue("country", out var value) ? (string)value : default; + get => TryGetValue("country", out var value) ? (string?)value! : default!; set => this["country"] = value; } @@ -112,9 +115,9 @@ public string Country /// Admite null. /// [JsonIgnore] - public string Zip + public string? Zip { - get => TryGetValue("zip", out var value) ? (string)value : default; + get => TryGetValue("zip", out var value) ? (string?)value! : default!; set => this["zip"] = value; } diff --git a/Models/Inputs/CustomerListParams.cs b/Models/Inputs/CustomerListParams.cs index 6d05367..beeaf84 100644 --- a/Models/Inputs/CustomerListParams.cs +++ b/Models/Inputs/CustomerListParams.cs @@ -1,14 +1,17 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// /// CustomerListParams /// - public class CustomerListParams : Dictionary + public class CustomerListParams : Dictionary { /// /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). @@ -16,9 +19,9 @@ public class CustomerListParams : Dictionary /// Opcional. /// [JsonIgnore] - public string Pagination + public string? Pagination { - get => TryGetValue("pagination", out var value) ? (string)value : default; + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; set => this["pagination"] = value; } @@ -27,9 +30,9 @@ public string Pagination /// Opcional. /// [JsonIgnore] - public string After + public string? After { - get => TryGetValue("after", out var value) ? (string)value : default; + get => TryGetValue("after", out var value) ? (string?)value! : default!; set => this["after"] = value; } @@ -38,9 +41,9 @@ public string After /// Opcional. /// [JsonIgnore] - public string Before + public string? Before { - get => TryGetValue("before", out var value) ? (string)value : default; + get => TryGetValue("before", out var value) ? (string?)value! : default!; set => this["before"] = value; } @@ -49,9 +52,9 @@ public string Before /// Opcional. /// [JsonIgnore] - public string Q + public string? Q { - get => TryGetValue("q", out var value) ? (string)value : default; + get => TryGetValue("q", out var value) ? (string?)value! : default!; set => this["q"] = value; } @@ -60,9 +63,9 @@ public string Q /// Opcional. /// [JsonIgnore] - public DateRangeInput Date + public DateRangeInput? Date { - get => TryGetValue("date", out var value) ? (DateRangeInput)value : default; + get => TryGetValue("date", out var value) ? (DateRangeInput?)value! : default!; set => this["date"] = value; } @@ -73,7 +76,7 @@ public DateRangeInput Date [JsonIgnore] public int? Page { - get => TryGetValue("page", out var value) ? (int?)value : default; + get => TryGetValue("page", out var value) ? (int?)value! : default!; set => this["page"] = value; } @@ -84,7 +87,7 @@ public int? Page [JsonIgnore] public int? Limit { - get => TryGetValue("limit", out var value) ? (int?)value : default; + get => TryGetValue("limit", out var value) ? (int?)value! : default!; set => this["limit"] = value; } diff --git a/Models/Inputs/CustomerNationalAddressInput.cs b/Models/Inputs/CustomerNationalAddressInput.cs index 559b637..21d75c5 100644 --- a/Models/Inputs/CustomerNationalAddressInput.cs +++ b/Models/Inputs/CustomerNationalAddressInput.cs @@ -1,22 +1,25 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// /// CustomerNationalAddressInput /// - public class CustomerNationalAddressInput : Dictionary + public class CustomerNationalAddressInput : Dictionary { /// /// Crea CustomerNationalAddressInput. /// /// Código postal Requerido. - public CustomerNationalAddressInput(string zip) + public CustomerNationalAddressInput(string @zip) { - this["zip"] = zip; + this["zip"] = @zip; } /// @@ -24,9 +27,9 @@ public CustomerNationalAddressInput(string zip) /// Opcional. /// [JsonIgnore] - public string Street + public string? Street { - get => TryGetValue("street", out var value) ? (string)value : default; + get => TryGetValue("street", out var value) ? (string?)value! : default!; set => this["street"] = value; } @@ -35,9 +38,9 @@ public string Street /// Opcional. /// [JsonIgnore] - public string Exterior + public string? Exterior { - get => TryGetValue("exterior", out var value) ? (string)value : default; + get => TryGetValue("exterior", out var value) ? (string?)value! : default!; set => this["exterior"] = value; } @@ -46,9 +49,9 @@ public string Exterior /// Opcional. /// [JsonIgnore] - public string Interior + public string? Interior { - get => TryGetValue("interior", out var value) ? (string)value : default; + get => TryGetValue("interior", out var value) ? (string?)value! : default!; set => this["interior"] = value; } @@ -57,9 +60,9 @@ public string Interior /// Opcional. /// [JsonIgnore] - public string Neighborhood + public string? Neighborhood { - get => TryGetValue("neighborhood", out var value) ? (string)value : default; + get => TryGetValue("neighborhood", out var value) ? (string?)value! : default!; set => this["neighborhood"] = value; } @@ -68,9 +71,9 @@ public string Neighborhood /// Opcional. /// [JsonIgnore] - public string City + public string? City { - get => TryGetValue("city", out var value) ? (string)value : default; + get => TryGetValue("city", out var value) ? (string?)value! : default!; set => this["city"] = value; } @@ -79,9 +82,9 @@ public string City /// Opcional. /// [JsonIgnore] - public string Municipality + public string? Municipality { - get => TryGetValue("municipality", out var value) ? (string)value : default; + get => TryGetValue("municipality", out var value) ? (string?)value! : default!; set => this["municipality"] = value; } @@ -92,7 +95,7 @@ public string Municipality [JsonIgnore] public string Zip { - get => TryGetValue("zip", out var value) ? (string)value : default; + get => TryGetValue("zip", out var value) ? (string)value! : default!; set => this["zip"] = value; } @@ -101,9 +104,9 @@ public string Zip /// Opcional. /// [JsonIgnore] - public string State + public string? State { - get => TryGetValue("state", out var value) ? (string)value : default; + get => TryGetValue("state", out var value) ? (string?)value! : default!; set => this["state"] = value; } @@ -114,9 +117,9 @@ public string State /// Admite null. /// [JsonIgnore] - public string Country + public string? Country { - get => TryGetValue("country", out var value) ? (string)value : default; + get => TryGetValue("country", out var value) ? (string?)value! : default!; set => this["country"] = value; } diff --git a/Models/Inputs/CustomerNationalCreateInput.cs b/Models/Inputs/CustomerNationalCreateInput.cs index 6dcdcb5..6e314bc 100644 --- a/Models/Inputs/CustomerNationalCreateInput.cs +++ b/Models/Inputs/CustomerNationalCreateInput.cs @@ -1,14 +1,17 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// /// País MEX, u omitido. Requiere razón social, RFC, régimen fiscal y código postal. Los RFC genéricos usan CustomerGenericCreateInput. /// - public class CustomerNationalCreateInput : Dictionary + public class CustomerNationalCreateInput : CustomerCreateInput { /// /// Crea CustomerNationalCreateInput. @@ -17,12 +20,12 @@ public class CustomerNationalCreateInput : Dictionary /// En clientes de México contiene el RFC del cliente. Para extranjeros es opcional y representa el número de registro de identificación tributaria, es decir, el equivalente al RFC en el país del cliente. Requerido. /// Requerido para clientes nacionales. Clave del régimen fiscal del cliente, del catálogo de [Regímenes Fiscales](https://docs.facturapi.io/api/#r%C3%A9gimen-fiscal). Requerido. /// address Requerido. - public CustomerNationalCreateInput(string legalName, string taxId, string taxSystem, CustomerNationalAddressInput address) + public CustomerNationalCreateInput(string @legalName, string @taxId, string @taxSystem, CustomerNationalAddressInput @address) : base(@legalName) { - this["legal_name"] = legalName; - this["tax_id"] = taxId; - this["tax_system"] = taxSystem; - this["address"] = address; + this["legal_name"] = @legalName; + this["tax_id"] = @taxId; + this["tax_system"] = @taxSystem; + this["address"] = @address; } /// @@ -30,9 +33,9 @@ public CustomerNationalCreateInput(string legalName, string taxId, string taxSys /// Requerido. /// [JsonIgnore] - public string LegalName + public new string LegalName { - get => TryGetValue("legal_name", out var value) ? (string)value : default; + get => TryGetValue("legal_name", out var value) ? (string)value! : default!; set => this["legal_name"] = value; } @@ -42,9 +45,9 @@ public string LegalName /// Admite null. /// [JsonIgnore] - public string Email + public new string? Email { - get => TryGetValue("email", out var value) ? (string)value : default; + get => TryGetValue("email", out var value) ? (string?)value! : default!; set => this["email"] = value; } @@ -54,9 +57,9 @@ public string Email /// Admite null. /// [JsonIgnore] - public string Phone + public new string? Phone { - get => TryGetValue("phone", out var value) ? (string)value : default; + get => TryGetValue("phone", out var value) ? (string?)value! : default!; set => this["phone"] = value; } @@ -66,9 +69,9 @@ public string Phone /// Admite null. /// [JsonIgnore] - public string DefaultInvoiceUse + public new string? DefaultInvoiceUse { - get => TryGetValue("default_invoice_use", out var value) ? (string)value : default; + get => TryGetValue("default_invoice_use", out var value) ? (string?)value! : default!; set => this["default_invoice_use"] = value; } @@ -77,9 +80,9 @@ public string DefaultInvoiceUse /// Requerido. /// [JsonIgnore] - public string TaxId + public new string TaxId { - get => TryGetValue("tax_id", out var value) ? (string)value : default; + get => TryGetValue("tax_id", out var value) ? (string)value! : default!; set => this["tax_id"] = value; } @@ -88,9 +91,9 @@ public string TaxId /// Requerido. /// [JsonIgnore] - public string TaxSystem + public new string TaxSystem { - get => TryGetValue("tax_system", out var value) ? (string)value : default; + get => TryGetValue("tax_system", out var value) ? (string)value! : default!; set => this["tax_system"] = value; } @@ -99,9 +102,9 @@ public string TaxSystem /// Requerido. /// [JsonIgnore] - public CustomerNationalAddressInput Address + public new CustomerNationalAddressInput Address { - get => TryGetValue("address", out var value) ? (CustomerNationalAddressInput)value : default; + get => TryGetValue("address", out var value) ? (CustomerNationalAddressInput)value! : default!; set => this["address"] = value; } diff --git a/Models/Inputs/CustomerUpdateInput.cs b/Models/Inputs/CustomerUpdateInput.cs index ad80411..b464d6d 100644 --- a/Models/Inputs/CustomerUpdateInput.cs +++ b/Models/Inputs/CustomerUpdateInput.cs @@ -1,23 +1,26 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// /// En una actualización sin createEditLink=true, los campos omitidos conservan su valor. Un valor null borra los campos que admiten null; un campo opcional puede omitirse sin que necesariamente admita null. No se permite null en legal_name, tax_id, tax_system ni address. En email, phone y los campos opcionales street, exterior, interior, neighborhood, city, municipality y state del domicilio, una cadena vacía o sólo espacios se normaliza a null. El código postal vacío no se acepta. /// - public class CustomerUpdateInput : Dictionary + public class CustomerUpdateInput : Dictionary { /// /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). /// Opcional. /// [JsonIgnore] - public string LegalName + public string? LegalName { - get => TryGetValue("legal_name", out var value) ? (string)value : default; + get => TryGetValue("legal_name", out var value) ? (string?)value! : default!; set => this["legal_name"] = value; } @@ -26,9 +29,9 @@ public string LegalName /// Opcional. /// [JsonIgnore] - public string TaxId + public string? TaxId { - get => TryGetValue("tax_id", out var value) ? (string)value : default; + get => TryGetValue("tax_id", out var value) ? (string?)value! : default!; set => this["tax_id"] = value; } @@ -38,9 +41,9 @@ public string TaxId /// Admite null. /// [JsonIgnore] - public string Email + public string? Email { - get => TryGetValue("email", out var value) ? (string)value : default; + get => TryGetValue("email", out var value) ? (string?)value! : default!; set => this["email"] = value; } @@ -50,9 +53,9 @@ public string Email /// Admite null. /// [JsonIgnore] - public string Phone + public string? Phone { - get => TryGetValue("phone", out var value) ? (string)value : default; + get => TryGetValue("phone", out var value) ? (string?)value! : default!; set => this["phone"] = value; } @@ -62,9 +65,9 @@ public string Phone /// Admite null. /// [JsonIgnore] - public string ExternalId + public string? ExternalId { - get => TryGetValue("external_id", out var value) ? (string)value : default; + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; set => this["external_id"] = value; } @@ -74,9 +77,9 @@ public string ExternalId /// Admite null. /// [JsonIgnore] - public string DefaultInvoiceUse + public string? DefaultInvoiceUse { - get => TryGetValue("default_invoice_use", out var value) ? (string)value : default; + get => TryGetValue("default_invoice_use", out var value) ? (string?)value! : default!; set => this["default_invoice_use"] = value; } @@ -85,9 +88,9 @@ public string DefaultInvoiceUse /// Opcional. /// [JsonIgnore] - public string TaxSystem + public string? TaxSystem { - get => TryGetValue("tax_system", out var value) ? (string)value : default; + get => TryGetValue("tax_system", out var value) ? (string?)value! : default!; set => this["tax_system"] = value; } @@ -96,9 +99,9 @@ public string TaxSystem /// Opcional. /// [JsonIgnore] - public CustomerUpdateInputAddress Address + public CustomerUpdateInputAddress? Address { - get => TryGetValue("address", out var value) ? (CustomerUpdateInputAddress)value : default; + get => TryGetValue("address", out var value) ? (CustomerUpdateInputAddress?)value! : default!; set => this["address"] = value; } diff --git a/Models/Inputs/CustomerUpdateInputAddress.cs b/Models/Inputs/CustomerUpdateInputAddress.cs index 70875d5..ec55987 100644 --- a/Models/Inputs/CustomerUpdateInputAddress.cs +++ b/Models/Inputs/CustomerUpdateInputAddress.cs @@ -1,14 +1,17 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// /// CustomerUpdateInputAddress /// - public class CustomerUpdateInputAddress : Dictionary + public class CustomerUpdateInputAddress : Dictionary { /// /// Nombre de la calle @@ -16,9 +19,9 @@ public class CustomerUpdateInputAddress : Dictionary /// Admite null. /// [JsonIgnore] - public string Street + public string? Street { - get => TryGetValue("street", out var value) ? (string)value : default; + get => TryGetValue("street", out var value) ? (string?)value! : default!; set => this["street"] = value; } @@ -28,9 +31,9 @@ public string Street /// Admite null. /// [JsonIgnore] - public string Exterior + public string? Exterior { - get => TryGetValue("exterior", out var value) ? (string)value : default; + get => TryGetValue("exterior", out var value) ? (string?)value! : default!; set => this["exterior"] = value; } @@ -40,9 +43,9 @@ public string Exterior /// Admite null. /// [JsonIgnore] - public string Interior + public string? Interior { - get => TryGetValue("interior", out var value) ? (string)value : default; + get => TryGetValue("interior", out var value) ? (string?)value! : default!; set => this["interior"] = value; } @@ -52,9 +55,9 @@ public string Interior /// Admite null. /// [JsonIgnore] - public string Neighborhood + public string? Neighborhood { - get => TryGetValue("neighborhood", out var value) ? (string)value : default; + get => TryGetValue("neighborhood", out var value) ? (string?)value! : default!; set => this["neighborhood"] = value; } @@ -64,9 +67,9 @@ public string Neighborhood /// Admite null. /// [JsonIgnore] - public string City + public string? City { - get => TryGetValue("city", out var value) ? (string)value : default; + get => TryGetValue("city", out var value) ? (string?)value! : default!; set => this["city"] = value; } @@ -76,9 +79,9 @@ public string City /// Admite null. /// [JsonIgnore] - public string Municipality + public string? Municipality { - get => TryGetValue("municipality", out var value) ? (string)value : default; + get => TryGetValue("municipality", out var value) ? (string?)value! : default!; set => this["municipality"] = value; } @@ -87,9 +90,9 @@ public string Municipality /// Opcional. /// [JsonIgnore] - public string Zip + public string? Zip { - get => TryGetValue("zip", out var value) ? (string)value : default; + get => TryGetValue("zip", out var value) ? (string?)value! : default!; set => this["zip"] = value; } @@ -99,9 +102,9 @@ public string Zip /// Admite null. /// [JsonIgnore] - public string State + public string? State { - get => TryGetValue("state", out var value) ? (string)value : default; + get => TryGetValue("state", out var value) ? (string?)value! : default!; set => this["state"] = value; } @@ -110,9 +113,9 @@ public string State /// Opcional. /// [JsonIgnore] - public string Country + public string? Country { - get => TryGetValue("country", out var value) ? (string)value : default; + get => TryGetValue("country", out var value) ? (string?)value! : default!; set => this["country"] = value; } diff --git a/Models/Inputs/CustomerUpdateParams.cs b/Models/Inputs/CustomerUpdateParams.cs index 90b1491..d72ebcb 100644 --- a/Models/Inputs/CustomerUpdateParams.cs +++ b/Models/Inputs/CustomerUpdateParams.cs @@ -1,14 +1,17 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// /// CustomerUpdateParams /// - public class CustomerUpdateParams : Dictionary + public class CustomerUpdateParams : Dictionary { /// /// Si pasas el valor `true`, se generará un enlace para que el cliente pueda editar @@ -20,7 +23,7 @@ public class CustomerUpdateParams : Dictionary [JsonIgnore] public bool? CreateEditLink { - get => TryGetValue("createEditLink", out var value) ? (bool?)value : default; + get => TryGetValue("createEditLink", out var value) ? (bool?)value! : default!; set => this["createEditLink"] = value; } diff --git a/Models/Inputs/CustomerUpdateWithEditLinkInput.cs b/Models/Inputs/CustomerUpdateWithEditLinkInput.cs index d28fd3b..1150275 100644 --- a/Models/Inputs/CustomerUpdateWithEditLinkInput.cs +++ b/Models/Inputs/CustomerUpdateWithEditLinkInput.cs @@ -1,14 +1,17 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// /// Con createEditLink=true, los campos omitidos conservan su valor y null borra el valor existente, incluidos los datos fiscales. Los valores no nulos deben ser válidos. En email, phone y los campos opcionales street, exterior, interior, neighborhood, city, municipality y state del domicilio, una cadena vacía o sólo espacios se normaliza a null. El código postal vacío no se acepta. /// - public class CustomerUpdateWithEditLinkInput : Dictionary + public class CustomerUpdateWithEditLinkInput : Dictionary { /// /// Nombre fiscal o razón social del cliente, *sin* el régimen societario (ej.: S.A. de C.V.). @@ -16,9 +19,9 @@ public class CustomerUpdateWithEditLinkInput : Dictionary /// Admite null. /// [JsonIgnore] - public string LegalName + public string? LegalName { - get => TryGetValue("legal_name", out var value) ? (string)value : default; + get => TryGetValue("legal_name", out var value) ? (string?)value! : default!; set => this["legal_name"] = value; } @@ -28,9 +31,9 @@ public string LegalName /// Admite null. /// [JsonIgnore] - public string TaxId + public string? TaxId { - get => TryGetValue("tax_id", out var value) ? (string)value : default; + get => TryGetValue("tax_id", out var value) ? (string?)value! : default!; set => this["tax_id"] = value; } @@ -40,9 +43,9 @@ public string TaxId /// Admite null. /// [JsonIgnore] - public string Email + public string? Email { - get => TryGetValue("email", out var value) ? (string)value : default; + get => TryGetValue("email", out var value) ? (string?)value! : default!; set => this["email"] = value; } @@ -52,9 +55,9 @@ public string Email /// Admite null. /// [JsonIgnore] - public string Phone + public string? Phone { - get => TryGetValue("phone", out var value) ? (string)value : default; + get => TryGetValue("phone", out var value) ? (string?)value! : default!; set => this["phone"] = value; } @@ -64,9 +67,9 @@ public string Phone /// Admite null. /// [JsonIgnore] - public string ExternalId + public string? ExternalId { - get => TryGetValue("external_id", out var value) ? (string)value : default; + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; set => this["external_id"] = value; } @@ -76,9 +79,9 @@ public string ExternalId /// Admite null. /// [JsonIgnore] - public string DefaultInvoiceUse + public string? DefaultInvoiceUse { - get => TryGetValue("default_invoice_use", out var value) ? (string)value : default; + get => TryGetValue("default_invoice_use", out var value) ? (string?)value! : default!; set => this["default_invoice_use"] = value; } @@ -88,9 +91,9 @@ public string DefaultInvoiceUse /// Admite null. /// [JsonIgnore] - public string TaxSystem + public string? TaxSystem { - get => TryGetValue("tax_system", out var value) ? (string)value : default; + get => TryGetValue("tax_system", out var value) ? (string?)value! : default!; set => this["tax_system"] = value; } @@ -100,9 +103,9 @@ public string TaxSystem /// Admite null. /// [JsonIgnore] - public CustomerUpdateWithEditLinkInputAddress Address + public CustomerUpdateWithEditLinkInputAddress? Address { - get => TryGetValue("address", out var value) ? (CustomerUpdateWithEditLinkInputAddress)value : default; + get => TryGetValue("address", out var value) ? (CustomerUpdateWithEditLinkInputAddress?)value! : default!; set => this["address"] = value; } diff --git a/Models/Inputs/CustomerUpdateWithEditLinkInputAddress.cs b/Models/Inputs/CustomerUpdateWithEditLinkInputAddress.cs index 1cbb0cc..9138561 100644 --- a/Models/Inputs/CustomerUpdateWithEditLinkInputAddress.cs +++ b/Models/Inputs/CustomerUpdateWithEditLinkInputAddress.cs @@ -1,14 +1,17 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// /// CustomerUpdateWithEditLinkInputAddress /// - public class CustomerUpdateWithEditLinkInputAddress : Dictionary + public class CustomerUpdateWithEditLinkInputAddress : Dictionary { /// /// Nombre de la calle @@ -16,9 +19,9 @@ public class CustomerUpdateWithEditLinkInputAddress : Dictionary /// Admite null. /// [JsonIgnore] - public string Street + public string? Street { - get => TryGetValue("street", out var value) ? (string)value : default; + get => TryGetValue("street", out var value) ? (string?)value! : default!; set => this["street"] = value; } @@ -28,9 +31,9 @@ public string Street /// Admite null. /// [JsonIgnore] - public string Exterior + public string? Exterior { - get => TryGetValue("exterior", out var value) ? (string)value : default; + get => TryGetValue("exterior", out var value) ? (string?)value! : default!; set => this["exterior"] = value; } @@ -40,9 +43,9 @@ public string Exterior /// Admite null. /// [JsonIgnore] - public string Interior + public string? Interior { - get => TryGetValue("interior", out var value) ? (string)value : default; + get => TryGetValue("interior", out var value) ? (string?)value! : default!; set => this["interior"] = value; } @@ -52,9 +55,9 @@ public string Interior /// Admite null. /// [JsonIgnore] - public string Neighborhood + public string? Neighborhood { - get => TryGetValue("neighborhood", out var value) ? (string)value : default; + get => TryGetValue("neighborhood", out var value) ? (string?)value! : default!; set => this["neighborhood"] = value; } @@ -64,9 +67,9 @@ public string Neighborhood /// Admite null. /// [JsonIgnore] - public string City + public string? City { - get => TryGetValue("city", out var value) ? (string)value : default; + get => TryGetValue("city", out var value) ? (string?)value! : default!; set => this["city"] = value; } @@ -76,9 +79,9 @@ public string City /// Admite null. /// [JsonIgnore] - public string Municipality + public string? Municipality { - get => TryGetValue("municipality", out var value) ? (string)value : default; + get => TryGetValue("municipality", out var value) ? (string?)value! : default!; set => this["municipality"] = value; } @@ -88,9 +91,9 @@ public string Municipality /// Admite null. /// [JsonIgnore] - public string State + public string? State { - get => TryGetValue("state", out var value) ? (string)value : default; + get => TryGetValue("state", out var value) ? (string?)value! : default!; set => this["state"] = value; } @@ -100,9 +103,9 @@ public string State /// Admite null. /// [JsonIgnore] - public string Country + public string? Country { - get => TryGetValue("country", out var value) ? (string)value : default; + get => TryGetValue("country", out var value) ? (string?)value! : default!; set => this["country"] = value; } @@ -112,9 +115,9 @@ public string Country /// Admite null. /// [JsonIgnore] - public string Zip + public string? Zip { - get => TryGetValue("zip", out var value) ? (string)value : default; + get => TryGetValue("zip", out var value) ? (string?)value! : default!; set => this["zip"] = value; } diff --git a/Models/Inputs/DateRangeInput.cs b/Models/Inputs/DateRangeInput.cs index 8da46de..2c3a98b 100644 --- a/Models/Inputs/DateRangeInput.cs +++ b/Models/Inputs/DateRangeInput.cs @@ -1,14 +1,17 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// /// DateRangeInput /// - public class DateRangeInput : Dictionary + public class DateRangeInput : Dictionary { /// /// Greater than @@ -17,10 +20,10 @@ public class DateRangeInput : Dictionary /// Opcional. /// [JsonIgnore] - public string Gt + public OneOf? Gt { - get => TryGetValue("gt", out var value) ? (string)value : default; - set => this["gt"] = value; + get => TryGetValue("gt", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["gt"] = value?.Value; } /// @@ -30,10 +33,10 @@ public string Gt /// Opcional. /// [JsonIgnore] - public string Gte + public OneOf? Gte { - get => TryGetValue("gte", out var value) ? (string)value : default; - set => this["gte"] = value; + get => TryGetValue("gte", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["gte"] = value?.Value; } /// @@ -43,10 +46,10 @@ public string Gte /// Opcional. /// [JsonIgnore] - public string Lt + public OneOf? Lt { - get => TryGetValue("lt", out var value) ? (string)value : default; - set => this["lt"] = value; + get => TryGetValue("lt", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["lt"] = value?.Value; } /// @@ -56,10 +59,10 @@ public string Lt /// Opcional. /// [JsonIgnore] - public string Lte + public OneOf? Lte { - get => TryGetValue("lte", out var value) ? (string)value : default; - set => this["lte"] = value; + get => TryGetValue("lte", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["lte"] = value?.Value; } } diff --git a/Models/Inputs/GlobalInvoiceCommonInput.cs b/Models/Inputs/GlobalInvoiceCommonInput.cs new file mode 100644 index 0000000..0329104 --- /dev/null +++ b/Models/Inputs/GlobalInvoiceCommonInput.cs @@ -0,0 +1,148 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// GlobalInvoiceCommonInput + /// + public class GlobalInvoiceCommonInput : Dictionary + { + /// + /// Fecha inicial de los recibos que se incluirán en la factura global. + /// Por default, este valor es el inicio del último periodo (día, semana, + /// quincena o mes), según el valor de "Periodicidad" (`periodicity`) + /// en la configuración de recibos de tu organización. Este valor es requerido cuando se envíe el campo `receipts`. + /// Opcional. + /// + [JsonIgnore] + public OneOf? From + { + get => TryGetValue("from", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["from"] = value?.Value; + } + + /// + /// Fecha final de los recibos que se incluirán en la factura global. + /// Por default, este valor es el fin del último periodo (día, semana, + /// quincena o mes), según el valor de "Periodicidad" (`periodicity`) + /// en la configuración de recibos de tu organización. Este valor es requerido cuando se envíe el campo `receipts`. + /// Opcional. + /// + [JsonIgnore] + public OneOf? To + { + get => TryGetValue("to", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["to"] = value?.Value; + } + + /// + /// Periodicidad que corresponde al rango de fechas utilizado. + /// Si omites los campos `from` y `to`, las fechas que se asignarán por + /// default dependerán del valor de `periodicity`. + /// + /// Si se omite, se utiliza la periodicidad configurada en los recibos de la organización. + /// Valores: "day", "week", "fortnight", "month", "two_months". + /// Opcional. + /// + [JsonIgnore] + public string? Periodicity + { + get => TryGetValue("periodicity", out var value) ? (string?)value! : default!; + set => this["periodicity"] = value; + } + + /// + /// Clave que representa el mes o bimestre de la factura. Consulta + /// los posibles valores en el [catálogo de Meses y Bimestres](https://docs.facturapi.io/api/#meses-y-bimestres). + /// + /// Si se omite, el mes o bimestre se determina a partir de la fecha inicial y la periodicidad. + /// Opcional. + /// + [JsonIgnore] + public string? Months + { + get => TryGetValue("months", out var value) ? (string?)value! : default!; + set => this["months"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. + /// Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Fecha de emisión de la factura. Si se omite, se utiliza la fecha final (`to`), limitada a la fecha y hora actuales. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). Si se incluye, los recibos se agruparán y se crearán la factura global por la forma de pago. + /// Opcional. + /// + [JsonIgnore] + public string? PaymentForm + { + get => TryGetValue("payment_form", out var value) ? (string?)value! : default!; + set => this["payment_form"] = value; + } + + /// + /// Recibos a incluir en la factura global. Si se incluye este parámetro, los parámetros `from` y `to` serán requeridos y tendrán que cumplir con el campo `periodicity`. + /// Opcional. + /// + [JsonIgnore] + public List? Receipts + { + get => TryGetValue("receipts", out var value) ? (List?)value! : default!; + set => this["receipts"] = value; + } + + /// + /// Permite procesar periodos con más de 5,000 recibos abiertos. Cuando es + /// `true`, la factura incluye como máximo 5,000 recibos y los restantes + /// conservan el status `"open"`. Repite la solicitud con el mismo periodo + /// hasta recibir `null`, que indica que ya no quedan recibos por facturar. + /// + /// Cuando es `false`, un periodo con más de 5,000 recibos abiertos devuelve + /// el error `global_invoice_too_many_items`. + /// Opcional. + /// + [JsonIgnore] + public bool? LimitToMaxReceipts + { + get => TryGetValue("limit_to_max_receipts", out var value) ? (bool?)value! : default!; + set => this["limit_to_max_receipts"] = value; + } + + } +} diff --git a/Models/Inputs/GlobalInvoiceInput.cs b/Models/Inputs/GlobalInvoiceInput.cs new file mode 100644 index 0000000..1670dfd --- /dev/null +++ b/Models/Inputs/GlobalInvoiceInput.cs @@ -0,0 +1,149 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Las fechas son opcionales al seleccionar por periodo. Al enviar receipts se requieren from y to. La periodicidad predeterminada viene de la configuración de la organización. + /// + public class GlobalInvoiceInput : Dictionary + { + /// + /// Fecha inicial de los recibos que se incluirán en la factura global. + /// Por default, este valor es el inicio del último periodo (día, semana, + /// quincena o mes), según el valor de "Periodicidad" (`periodicity`) + /// en la configuración de recibos de tu organización. Este valor es requerido cuando se envíe el campo `receipts`. + /// Opcional. + /// + [JsonIgnore] + public OneOf? From + { + get => TryGetValue("from", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["from"] = value?.Value; + } + + /// + /// Fecha final de los recibos que se incluirán en la factura global. + /// Por default, este valor es el fin del último periodo (día, semana, + /// quincena o mes), según el valor de "Periodicidad" (`periodicity`) + /// en la configuración de recibos de tu organización. Este valor es requerido cuando se envíe el campo `receipts`. + /// Opcional. + /// + [JsonIgnore] + public OneOf? To + { + get => TryGetValue("to", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["to"] = value?.Value; + } + + /// + /// Periodicidad que corresponde al rango de fechas utilizado. + /// Si omites los campos `from` y `to`, las fechas que se asignarán por + /// default dependerán del valor de `periodicity`. + /// + /// Si se omite, se utiliza la periodicidad configurada en los recibos de la organización. + /// Valores: "day", "week", "fortnight", "month", "two_months". + /// Opcional. + /// + [JsonIgnore] + public string? Periodicity + { + get => TryGetValue("periodicity", out var value) ? (string?)value! : default!; + set => this["periodicity"] = value; + } + + /// + /// Clave que representa el mes o bimestre de la factura. Consulta + /// los posibles valores en el [catálogo de Meses y Bimestres](https://docs.facturapi.io/api/#meses-y-bimestres). + /// + /// Si se omite, el mes o bimestre se determina a partir de la fecha inicial y la periodicidad. + /// Opcional. + /// + [JsonIgnore] + public string? Months + { + get => TryGetValue("months", out var value) ? (string?)value! : default!; + set => this["months"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. + /// Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Fecha de emisión de la factura. Si se omite, se utiliza la fecha final (`to`), limitada a la fecha y hora actuales. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). Si se incluye, los recibos se agruparán y se crearán la factura global por la forma de pago. + /// Opcional. + /// + [JsonIgnore] + public string? PaymentForm + { + get => TryGetValue("payment_form", out var value) ? (string?)value! : default!; + set => this["payment_form"] = value; + } + + /// + /// Recibos a incluir en la factura global. Si se incluye este parámetro, los parámetros `from` y `to` serán requeridos y tendrán que cumplir con el campo `periodicity`. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public List? Receipts + { + get => TryGetValue("receipts", out var value) ? (List?)value! : default!; + set => this["receipts"] = value; + } + + /// + /// Permite procesar periodos con más de 5,000 recibos abiertos. Cuando es + /// `true`, la factura incluye como máximo 5,000 recibos y los restantes + /// conservan el status `"open"`. Repite la solicitud con el mismo periodo + /// hasta recibir `null`, que indica que ya no quedan recibos por facturar. + /// + /// Cuando es `false`, un periodo con más de 5,000 recibos abiertos devuelve + /// el error `global_invoice_too_many_items`. + /// Opcional. + /// + [JsonIgnore] + public bool? LimitToMaxReceipts + { + get => TryGetValue("limit_to_max_receipts", out var value) ? (bool?)value! : default!; + set => this["limit_to_max_receipts"] = value; + } + + } +} diff --git a/Models/Inputs/HidroYPetroComplementInput.cs b/Models/Inputs/HidroYPetroComplementInput.cs new file mode 100644 index 0000000..660cd0f --- /dev/null +++ b/Models/Inputs/HidroYPetroComplementInput.cs @@ -0,0 +1,79 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// HidroYPetroComplementInput + /// + public class HidroYPetroComplementInput : Dictionary + { + /// + /// Crea HidroYPetroComplementInput. + /// + /// Tipo de permiso otorgado por la autoridad competente, conforme al [Catálogo Hidrocarburos Petrolíferos](https://docs.facturapi.io/api/#cat%C3%A1logos-hidrocarburos-petrol%C3%ADferos). Valores: "PER01", "PER02", "PER03", "PER04", "PER05", "PER06", "PER07", "PER08", "PER09", "PER10", "PER11". Requerido. + /// Número de permiso otorgado por la autoridad competente, conforme a la nomenclatura del catálogo c_TipoPermiso. Requerido. + /// Subtipo del hidrocarburo o petrolífero, conforme al [Catálogo Hidrocarburos Petrolíferos](https://docs.facturapi.io/api/#cat%C3%A1logos-hidrocarburos-petrol%C3%ADferos). Valores: "SP16", "SP17", "SP18", "SP19", "SP22", "SP23", "SP24", "SP25", "SP48". Requerido. + public HidroYPetroComplementInput(string @tipoPermiso, string @numeroPermiso, string @subProductoHyp) + { + this["tipo_permiso"] = @tipoPermiso; + this["numero_permiso"] = @numeroPermiso; + this["sub_producto_hyp"] = @subProductoHyp; + } + + /// + /// Tipo de permiso otorgado por la autoridad competente, conforme al [Catálogo Hidrocarburos Petrolíferos](https://docs.facturapi.io/api/#cat%C3%A1logos-hidrocarburos-petrol%C3%ADferos). + /// Valores: "PER01", "PER02", "PER03", "PER04", "PER05", "PER06", "PER07", "PER08", "PER09", "PER10", "PER11". + /// Requerido. + /// + [JsonIgnore] + public string TipoPermiso + { + get => TryGetValue("tipo_permiso", out var value) ? (string)value! : default!; + set => this["tipo_permiso"] = value; + } + + /// + /// Número de permiso otorgado por la autoridad competente, conforme a la nomenclatura del catálogo c_TipoPermiso. + /// Requerido. + /// + [JsonIgnore] + public string NumeroPermiso + { + get => TryGetValue("numero_permiso", out var value) ? (string)value! : default!; + set => this["numero_permiso"] = value; + } + + /// + /// Subtipo del hidrocarburo o petrolífero, conforme al [Catálogo Hidrocarburos Petrolíferos](https://docs.facturapi.io/api/#cat%C3%A1logos-hidrocarburos-petrol%C3%ADferos). + /// Valores: "SP16", "SP17", "SP18", "SP19", "SP22", "SP23", "SP24", "SP25", "SP48". + /// Requerido. + /// + [JsonIgnore] + public string SubProductoHyp + { + get => TryGetValue("sub_producto_hyp", out var value) ? (string)value! : default!; + set => this["sub_producto_hyp"] = value; + } + + /// + /// Clave correspondiente a hidrocarburos y petrolíferos, conforme al [Catálogo Hidrocarburos Petrolíferos](https://docs.facturapi.io/api/#cat%C3%A1logos-hidrocarburos-petrol%C3%ADferos). + /// + /// Puedes enviarla explícitamente o dejar que Facturapi la derive desde el `product_key` del concepto cuando aplique. + /// Valores: "15101514", "15101515", "15101505". + /// Opcional. + /// + [JsonIgnore] + public string? ClaveHyp + { + get => TryGetValue("clave_hyp", out var value) ? (string?)value! : default!; + set => this["clave_hyp"] = value; + } + + } +} diff --git a/Models/Inputs/IeduComplementInput.cs b/Models/Inputs/IeduComplementInput.cs new file mode 100644 index 0000000..0e905ca --- /dev/null +++ b/Models/Inputs/IeduComplementInput.cs @@ -0,0 +1,88 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// IeduComplementInput + /// + public class IeduComplementInput : Dictionary + { + /// + /// Crea IeduComplementInput. + /// + /// Nombre del alumno. Requerido. + /// CURP del alumno de la institución educativa. Requerido. + /// Nivel educativo que cursa el alumno. Valores: "Preescolar", "Primaria", "Secundaria", "Profesional técnico", "Bachillerato o su equivalente". Requerido. + /// Clave del centro de trabajo o reconocimiento de validez oficial de estudios de la institución educativa privada donde se realiza el pago. Requerido. + public IeduComplementInput(string @nombreAlumno, string @cURP, string @nivelEducativo, string @autRVOE) + { + this["nombreAlumno"] = @nombreAlumno; + this["CURP"] = @cURP; + this["nivelEducativo"] = @nivelEducativo; + this["autRVOE"] = @autRVOE; + } + + /// + /// Nombre del alumno. + /// Requerido. + /// + [JsonIgnore] + public string NombreAlumno + { + get => TryGetValue("nombreAlumno", out var value) ? (string)value! : default!; + set => this["nombreAlumno"] = value; + } + + /// + /// CURP del alumno de la institución educativa. + /// Requerido. + /// + [JsonIgnore] + public string CURP + { + get => TryGetValue("CURP", out var value) ? (string)value! : default!; + set => this["CURP"] = value; + } + + /// + /// Nivel educativo que cursa el alumno. + /// Valores: "Preescolar", "Primaria", "Secundaria", "Profesional técnico", "Bachillerato o su equivalente". + /// Requerido. + /// + [JsonIgnore] + public string NivelEducativo + { + get => TryGetValue("nivelEducativo", out var value) ? (string)value! : default!; + set => this["nivelEducativo"] = value; + } + + /// + /// Clave del centro de trabajo o reconocimiento de validez oficial de estudios de la institución educativa privada donde se realiza el pago. + /// Requerido. + /// + [JsonIgnore] + public string AutRVOE + { + get => TryGetValue("autRVOE", out var value) ? (string)value! : default!; + set => this["autRVOE"] = value; + } + + /// + /// RFC de quien realiza el pago cuando sea diferente a quien recibe el servicio. + /// Opcional. + /// + [JsonIgnore] + public string? RfcPago + { + get => TryGetValue("rfcPago", out var value) ? (string?)value! : default!; + set => this["rfcPago"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceCommonEditInput.cs b/Models/Inputs/InvoiceCommonEditInput.cs new file mode 100644 index 0000000..29bab47 --- /dev/null +++ b/Models/Inputs/InvoiceCommonEditInput.cs @@ -0,0 +1,155 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceCommonEditInput + /// + public class InvoiceCommonEditInput : Dictionary + { + /// + /// Crea InvoiceCommonEditInput. + /// + public InvoiceCommonEditInput() + { + this["status"] = "draft"; + } + + /// + /// Estado de la factura. El valor `draft` identifica un borrador que no se ha timbrado ni enviado al SAT. + /// Sólo es posible editar facturas con este estado; al editarlas, no se puede cambiar `status`. + /// Valores: "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). No puede ser anterior a 72 horas en el pasado, ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonEditInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonEditInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonEditInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonEditInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceCommonEditInputAddress.cs b/Models/Inputs/InvoiceCommonEditInputAddress.cs new file mode 100644 index 0000000..bfb3baa --- /dev/null +++ b/Models/Inputs/InvoiceCommonEditInputAddress.cs @@ -0,0 +1,105 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceCommonEditInputAddress + /// + public class InvoiceCommonEditInputAddress : Dictionary + { + /// + /// Nombre de la calle + /// Opcional. + /// + [JsonIgnore] + public string? Street + { + get => TryGetValue("street", out var value) ? (string?)value! : default!; + set => this["street"] = value; + } + + /// + /// Número exterior. + /// Opcional. + /// + [JsonIgnore] + public string? Exterior + { + get => TryGetValue("exterior", out var value) ? (string?)value! : default!; + set => this["exterior"] = value; + } + + /// + /// Número interior. + /// Opcional. + /// + [JsonIgnore] + public string? Interior + { + get => TryGetValue("interior", out var value) ? (string?)value! : default!; + set => this["interior"] = value; + } + + /// + /// Colonia + /// Opcional. + /// + [JsonIgnore] + public string? Neighborhood + { + get => TryGetValue("neighborhood", out var value) ? (string?)value! : default!; + set => this["neighborhood"] = value; + } + + /// + /// Ciudad + /// Opcional. + /// + [JsonIgnore] + public string? City + { + get => TryGetValue("city", out var value) ? (string?)value! : default!; + set => this["city"] = value; + } + + /// + /// Municipio o delegación + /// Opcional. + /// + [JsonIgnore] + public string? Municipality + { + get => TryGetValue("municipality", out var value) ? (string?)value! : default!; + set => this["municipality"] = value; + } + + /// + /// Código postal + /// Opcional. + /// + [JsonIgnore] + public string? Zip + { + get => TryGetValue("zip", out var value) ? (string?)value! : default!; + set => this["zip"] = value; + } + + /// + /// Nombre del Estado o Entidad Federativa. + /// Opcional. + /// + [JsonIgnore] + public string? State + { + get => TryGetValue("state", out var value) ? (string?)value! : default!; + set => this["state"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceCommonInput.cs b/Models/Inputs/InvoiceCommonInput.cs new file mode 100644 index 0000000..e44610a --- /dev/null +++ b/Models/Inputs/InvoiceCommonInput.cs @@ -0,0 +1,161 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceCommonInput + /// + public class InvoiceCommonInput : Dictionary + { + /// + /// customer + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// Estado inicial de la factura. Si se envía `draft`, la factura se guardará como borrador y no se timbrará ni se + /// enviará al SAT. También al enviar `draft`, todos los campos requeridos se vuelven + /// opcionales. Si se omite, el estado por default es `pending` y una vez timbrada (en la respuesta) este + /// campo se actualizará a `valid`. Para facturas asíncronas, este campo se quedará en `pending` hasta que + /// se timbre la factura. + /// Valores: "pending", "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601. Si se omite, se utiliza la fecha y hora actuales. No puede ser anterior a 72 horas en el pasado ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceCommonInputAddress.cs b/Models/Inputs/InvoiceCommonInputAddress.cs new file mode 100644 index 0000000..f49be6b --- /dev/null +++ b/Models/Inputs/InvoiceCommonInputAddress.cs @@ -0,0 +1,105 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceCommonInputAddress + /// + public class InvoiceCommonInputAddress : Dictionary + { + /// + /// Nombre de la calle + /// Opcional. + /// + [JsonIgnore] + public string? Street + { + get => TryGetValue("street", out var value) ? (string?)value! : default!; + set => this["street"] = value; + } + + /// + /// Número exterior. + /// Opcional. + /// + [JsonIgnore] + public string? Exterior + { + get => TryGetValue("exterior", out var value) ? (string?)value! : default!; + set => this["exterior"] = value; + } + + /// + /// Número interior. + /// Opcional. + /// + [JsonIgnore] + public string? Interior + { + get => TryGetValue("interior", out var value) ? (string?)value! : default!; + set => this["interior"] = value; + } + + /// + /// Colonia + /// Opcional. + /// + [JsonIgnore] + public string? Neighborhood + { + get => TryGetValue("neighborhood", out var value) ? (string?)value! : default!; + set => this["neighborhood"] = value; + } + + /// + /// Ciudad + /// Opcional. + /// + [JsonIgnore] + public string? City + { + get => TryGetValue("city", out var value) ? (string?)value! : default!; + set => this["city"] = value; + } + + /// + /// Municipio o delegación + /// Opcional. + /// + [JsonIgnore] + public string? Municipality + { + get => TryGetValue("municipality", out var value) ? (string?)value! : default!; + set => this["municipality"] = value; + } + + /// + /// Código postal + /// Opcional. + /// + [JsonIgnore] + public string? Zip + { + get => TryGetValue("zip", out var value) ? (string?)value! : default!; + set => this["zip"] = value; + } + + /// + /// Nombre del Estado o Entidad Federativa. + /// Opcional. + /// + [JsonIgnore] + public string? State + { + get => TryGetValue("state", out var value) ? (string?)value! : default!; + set => this["state"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceComplementInput.cs b/Models/Inputs/InvoiceComplementInput.cs new file mode 100644 index 0000000..92d4484 --- /dev/null +++ b/Models/Inputs/InvoiceComplementInput.cs @@ -0,0 +1,49 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceComplementInput + /// + public class InvoiceComplementInput : Dictionary + { + /// + /// Crea InvoiceComplementInput. + /// + /// Tipo de complemento. Valores: "custom", "pago", "nomina", "carta_porte", "comercio_exterior", "leyendas_fiscales". Requerido. + public InvoiceComplementInput(string @type) + { + this["type"] = @type; + } + + /// + /// Tipo de complemento. + /// Valores: "custom", "pago", "nomina", "carta_porte", "comercio_exterior", "leyendas_fiscales". + /// Requerido. + /// + [JsonIgnore] + public string Type + { + get => TryGetValue("type", out var value) ? (string)value! : default!; + set => this["type"] = value; + } + + /// + /// data + /// Opcional. + /// + [JsonIgnore] + public OneOf, NominaComplementDataInput, CartaPorteDataPropertiesInput, ComercioExteriorDataInput, LeyendasFiscalesDataInput>? Data + { + get => TryGetValue("data", out var value) && value != null ? OneOf, NominaComplementDataInput, CartaPorteDataPropertiesInput, ComercioExteriorDataInput, LeyendasFiscalesDataInput>.FromValue(value) : default(OneOf, NominaComplementDataInput, CartaPorteDataPropertiesInput, ComercioExteriorDataInput, LeyendasFiscalesDataInput>?); + set => this["data"] = value?.Value; + } + + } +} diff --git a/Models/Inputs/InvoiceCreateInput.cs b/Models/Inputs/InvoiceCreateInput.cs new file mode 100644 index 0000000..55d1f1d --- /dev/null +++ b/Models/Inputs/InvoiceCreateInput.cs @@ -0,0 +1,367 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Datos de la factura según su tipo y estado inicial. Omite status para timbrar; usa draft para guardar un borrador. + /// + public class InvoiceCreateInput : Dictionary + { + /// + /// Tipo de comprobante. El valor default es `“I”` (Ingreso). + /// Tipo de comprobante de esta variante de entrada. + /// Valores: "I", "E", "P", "N", "T". + /// Opcional. + /// + [JsonIgnore] + public string? Type + { + get => TryGetValue("type", out var value) ? (string?)value! : default!; + set => this["type"] = value; + } + + /// + /// Conceptos a incluir en la factura. + /// + /// El número máximo de elementos que puedes incluir en una factura es de 5,000. Si necesitas + /// emitir una factura con más de 5,000 conceptos, puedes dividir la transacción en varias facturas. + /// Conceptos a incluir en la nota de crédito. + /// + /// El número máximo de elementos que puedes incluir en el comprobante es de 5,000. Si necesitas + /// emitir un comprobante con más de 5,000 conceptos, puedes dividir la transacción en varios comprobantes. + /// Conceptos a incluir en el comprobante de Traslado. + /// + /// El número máximo de elementos que puedes incluir en un comprobante es de 5,000. Si necesitas + /// emitir un comprobante con más de 5,000 conceptos, puedes dividir la transacción en varios comprobantes. + /// Opcional. + /// + [JsonIgnore] + public List>? Items + { + get => TryGetValue("items", out var value) ? (List>?)value! : default!; + set => this["items"] = value; + } + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? PaymentForm + { + get => TryGetValue("payment_form", out var value) ? (string?)value! : default!; + set => this["payment_form"] = value; + } + + /// + /// Código del método de pago según el catálogo del SAT. + /// + /// - `PUE`: Pago en Una sola Exhibición + /// - `PPD`: Pago en Parcialidades o Diferido + /// Código del método de pago según el catálogo del SAT. Para facturas de Egreso, + /// este campo es opcional y el único valor permitido es `PUE` (Pago en Una sola Exhibición). + /// Valores: "PUE", "PPD". + /// Opcional. + /// + [JsonIgnore] + public string? PaymentMethod + { + get => TryGetValue("payment_method", out var value) ? (string?)value! : default!; + set => this["payment_method"] = value; + } + + /// + /// Si se omite o es null, se utiliza el uso configurado en el cliente; si no tiene uno, se utiliza G03. Para clientes extranjeros o con RFC genérico se utiliza S01, incluso si se envía otro uso válido del catálogo. + /// + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos + /// en [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en + /// nuestras librerías. + /// + /// En una factura global, el uso es `S01`. + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos + /// en [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en + /// nuestras librerías. + /// + /// Para factura global debe ingresarse la clave `S01`. + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos en [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en nuestras librerías. + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos en + /// [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en nuestras librerías. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Use + { + get => TryGetValue("use", out var value) ? (string?)value! : default!; + set => this["use"] = value; + } + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonIgnore] + public string? Currency + { + get => TryGetValue("currency", out var value) ? (string?)value! : default!; + set => this["currency"] = value; + } + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos + /// mexicanos (MXN) que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos (MXN) que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos + /// (MXN) que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Opcional. + /// + [JsonIgnore] + public decimal? Exchange + { + get => TryGetValue("exchange", out var value) ? (decimal?)value! : default!; + set => this["exchange"] = value; + } + + /// + /// Condiciones de pago + /// Opcional. + /// + [JsonIgnore] + public string? Conditions + { + get => TryGetValue("conditions", out var value) ? (string?)value! : default!; + set => this["conditions"] = value; + } + + /// + /// Documentos relacionados con la factura. + /// Documentos relacionados con la nota de crédito. + /// Documentos relacionados con el comprobante. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// Información del periodo que abarca una factura global. En una factura de ingreso, este objeto es obligatorio cuando el receptor tiene `tax_id=XAXX010101000` y `legal_name=PUBLICO EN GENERAL`. Incluye periodicity, months y year. + /// Opcional. + /// + [JsonIgnore] + public InvoiceCreateInputGlobal? Global + { + get => TryGetValue("global", out var value) ? (InvoiceCreateInputGlobal?)value! : default!; + set => this["global"] = value; + } + + /// + /// Indica si el comprobante ampara una operación de exportación. + /// + /// - `01`: No aplica + /// - `02`: Definitiva con clave A1 + /// - `03`: Temporal + /// - `04`: Definitiva con clave distinta a A1 o cuando no existe enajenación en términos del CFF + /// Valores: "01", "04", "02", "03". + /// Opcional. + /// + [JsonIgnore] + public string? Export + { + get => TryGetValue("export", out var value) ? (string?)value! : default!; + set => this["export"] = value; + } + + /// + /// Complementos a incluir en la factura. Puedes incluir cualquier complemento en la + /// factura si tú mismo construyes el nodo XML del complemento y usas el tipo `custom`. + /// Es necesario agregar la información del complemento al PDF por separado usando el + /// parámetro `pdf_custom_section`. + /// Complementos a incluir en el comprobante. Puedes incluir cualquier + /// complemento en el comprobante si tú mismo construyes el nodo XML del + /// complemento y usas el tipo `custom`. Es necesario agregar la información + /// del complemento al PDF por separado usando el parámetro `pdf_custom_section`. + /// Complementos a incluir en la factura. + /// Complementos a incluir en el comprobante. Puedes incluir cualquier complemento en + /// el comprobante si tú mismo construyes el nodo XML del complemento y usas el tipo + /// `custom`. Es necesario agregar la información del complemento al PDF por separado + /// usando el parámetro `pdf_custom_section`. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// Cliente receptor de la factura. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// Estado inicial de la factura. Si se envía `draft`, la factura se guardará como borrador y no se timbrará ni se + /// enviará al SAT. También al enviar `draft`, todos los campos requeridos se vuelven + /// opcionales. Si se omite, el estado por default es `pending` y una vez timbrada (en la respuesta) este + /// campo se actualizará a `valid`. Para facturas asíncronas, este campo se quedará en `pending` hasta que + /// se timbre la factura. + /// Estado de la factura. El valor `draft` identifica un borrador que no se ha timbrado ni enviado al SAT. + /// Sólo es posible editar facturas con este estado; al editarlas, no se puede cambiar `status`. + /// Valores: "pending", "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601. Si se omite, se utiliza la fecha y hora actuales. No puede ser anterior a 72 horas en el pasado ni posterior al presente. + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). No puede ser anterior a 72 horas en el pasado, ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public OneOf? Address + { + get => TryGetValue("address", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["address"] = value?.Value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public OneOf? PdfOptions + { + get => TryGetValue("pdf_options", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["pdf_options"] = value?.Value; + } + + /// + /// third_party + /// Opcional. + /// + [JsonIgnore] + public InvoiceItemInputThirdParty? ThirdParty + { + get => TryGetValue("third_party", out var value) ? (InvoiceItemInputThirdParty?)value! : default!; + set => this["third_party"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceCreateInputGlobal.cs b/Models/Inputs/InvoiceCreateInputGlobal.cs new file mode 100644 index 0000000..e9074fa --- /dev/null +++ b/Models/Inputs/InvoiceCreateInputGlobal.cs @@ -0,0 +1,71 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceCreateInputGlobal + /// + public class InvoiceCreateInputGlobal : Dictionary + { + /// + /// Crea InvoiceCreateInputGlobal. + /// + /// Periodicidad que abarca la factura global. - `day`: Diario - `week`: Semanal - `fortnight`: Quincenal - `month`: Mensual - `two_months`: Bimestral Valores: "day", "week", "fortnight", "month", "two_months". Requerido. + /// Clave que representa el mes o bimestre de la factura. Consulta los posibles valores en el [catálogo de Meses y Bimestres](https://docs.facturapi.io/api/#meses-y-bimestres). Requerido. + /// Año de la factura. Requerido. + public InvoiceCreateInputGlobal(string @periodicity, string @months, int @year) + { + this["periodicity"] = @periodicity; + this["months"] = @months; + this["year"] = @year; + } + + /// + /// Periodicidad que abarca la factura global. + /// + /// - `day`: Diario + /// - `week`: Semanal + /// - `fortnight`: Quincenal + /// - `month`: Mensual + /// - `two_months`: Bimestral + /// Valores: "day", "week", "fortnight", "month", "two_months". + /// Requerido. + /// + [JsonIgnore] + public string Periodicity + { + get => TryGetValue("periodicity", out var value) ? (string)value! : default!; + set => this["periodicity"] = value; + } + + /// + /// Clave que representa el mes o bimestre de la factura. Consulta + /// los posibles valores en el [catálogo de Meses y Bimestres](https://docs.facturapi.io/api/#meses-y-bimestres). + /// Requerido. + /// + [JsonIgnore] + public string Months + { + get => TryGetValue("months", out var value) ? (string)value! : default!; + set => this["months"] = value; + } + + /// + /// Año de la factura. + /// Requerido. + /// + [JsonIgnore] + public int Year + { + get => TryGetValue("year", out var value) ? (int)value! : default!; + set => this["year"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceCreateParams.cs b/Models/Inputs/InvoiceCreateParams.cs new file mode 100644 index 0000000..0795032 --- /dev/null +++ b/Models/Inputs/InvoiceCreateParams.cs @@ -0,0 +1,30 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceCreateParams + /// + public class InvoiceCreateParams : Dictionary + { + /// + /// Útil para facturas de gran tamaño. Si se envía `false` o no se envía, la llamada esperará a que el SAT responda timbrando la factura. + /// Si se envía `true`, la llamada regresará inmediatamente con el objeto `invoice` en status `pending`, y podrá consultarse su cambio de status + /// a `valid` en un momento posterior. + /// Opcional. + /// + [JsonIgnore] + public bool? Async + { + get => TryGetValue("async", out var value) ? (bool?)value! : default!; + set => this["async"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceDraftCommonInput.cs b/Models/Inputs/InvoiceDraftCommonInput.cs new file mode 100644 index 0000000..de93dcc --- /dev/null +++ b/Models/Inputs/InvoiceDraftCommonInput.cs @@ -0,0 +1,166 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceDraftCommonInput + /// + public class InvoiceDraftCommonInput : Dictionary + { + /// + /// Crea InvoiceDraftCommonInput. + /// + public InvoiceDraftCommonInput() + { + this["status"] = "draft"; + } + + /// + /// Estado de la factura. El valor `draft` identifica un borrador que no se ha timbrado ni enviado al SAT. + /// Sólo es posible editar facturas con este estado; al editarlas, no se puede cambiar `status`. + /// Valores: "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). No puede ser anterior a 72 horas en el pasado, ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonEditInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonEditInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonEditInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonEditInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + /// + /// Cliente receptor de la factura. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + } +} diff --git a/Models/Inputs/InvoiceEgresoDraftInput.cs b/Models/Inputs/InvoiceEgresoDraftInput.cs new file mode 100644 index 0000000..8b2580e --- /dev/null +++ b/Models/Inputs/InvoiceEgresoDraftInput.cs @@ -0,0 +1,275 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Datos de la factura según su tipo y estado inicial. Omite status para timbrar; usa draft para guardar un borrador. + /// + public class InvoiceEgresoDraftInput : Dictionary + { + /// + /// Crea InvoiceEgresoDraftInput. + /// + public InvoiceEgresoDraftInput() + { + this["type"] = "E"; + this["status"] = "draft"; + } + + /// + /// Tipo de comprobante de esta variante de entrada. + /// Valores: "E". + /// Opcional. + /// + [JsonIgnore] + public string? Type + { + get => TryGetValue("type", out var value) ? (string?)value! : default!; + set => this["type"] = value; + } + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Opcional. + /// + [JsonIgnore] + public string? PaymentForm + { + get => TryGetValue("payment_form", out var value) ? (string?)value! : default!; + set => this["payment_form"] = value; + } + + /// + /// Código del método de pago según el catálogo del SAT. Para facturas de Egreso, + /// este campo es opcional y el único valor permitido es `PUE` (Pago en Una sola Exhibición). + /// Valores: "PUE". + /// Opcional. + /// + [JsonIgnore] + public string? PaymentMethod + { + get => TryGetValue("payment_method", out var value) ? (string?)value! : default!; + set => this["payment_method"] = value; + } + + /// + /// Documentos relacionados con la nota de crédito. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// Conceptos a incluir en la nota de crédito. + /// + /// El número máximo de elementos que puedes incluir en el comprobante es de 5,000. Si necesitas + /// emitir un comprobante con más de 5,000 conceptos, puedes dividir la transacción en varios comprobantes. + /// Opcional. + /// + [JsonIgnore] + public List? Items + { + get => TryGetValue("items", out var value) ? (List?)value! : default!; + set => this["items"] = value; + } + + /// + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos en [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en nuestras librerías. + /// Opcional. + /// + [JsonIgnore] + public string? Use + { + get => TryGetValue("use", out var value) ? (string?)value! : default!; + set => this["use"] = value; + } + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonIgnore] + public string? Currency + { + get => TryGetValue("currency", out var value) ? (string?)value! : default!; + set => this["currency"] = value; + } + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos (MXN) que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Opcional. + /// + [JsonIgnore] + public decimal? Exchange + { + get => TryGetValue("exchange", out var value) ? (decimal?)value! : default!; + set => this["exchange"] = value; + } + + /// + /// Complementos a incluir en el comprobante. Puedes incluir cualquier + /// complemento en el comprobante si tú mismo construyes el nodo XML del + /// complemento y usas el tipo `custom`. Es necesario agregar la información + /// del complemento al PDF por separado usando el parámetro `pdf_custom_section`. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// Estado de la factura. El valor `draft` identifica un borrador que no se ha timbrado ni enviado al SAT. + /// Sólo es posible editar facturas con este estado; al editarlas, no se puede cambiar `status`. + /// Valores: "draft". + /// Requerido. + /// + [JsonIgnore] + public string Status + { + get => TryGetValue("status", out var value) ? (string)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). No puede ser anterior a 72 horas en el pasado, ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonEditInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonEditInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonEditInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonEditInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + /// + /// Cliente receptor de la factura. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + } +} diff --git a/Models/Inputs/InvoiceEgresoEditInput.cs b/Models/Inputs/InvoiceEgresoEditInput.cs new file mode 100644 index 0000000..c886047 --- /dev/null +++ b/Models/Inputs/InvoiceEgresoEditInput.cs @@ -0,0 +1,275 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Egreso + /// + public class InvoiceEgresoEditInput : Dictionary + { + /// + /// Crea InvoiceEgresoEditInput. + /// + public InvoiceEgresoEditInput() + { + this["type"] = "E"; + this["status"] = "draft"; + } + + /// + /// Tipo de comprobante de esta variante de entrada. + /// Valores: "E". + /// Opcional. + /// + [JsonIgnore] + public string? Type + { + get => TryGetValue("type", out var value) ? (string?)value! : default!; + set => this["type"] = value; + } + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Opcional. + /// + [JsonIgnore] + public string? PaymentForm + { + get => TryGetValue("payment_form", out var value) ? (string?)value! : default!; + set => this["payment_form"] = value; + } + + /// + /// Código del método de pago según el catálogo del SAT. Para facturas de Egreso, + /// este campo es opcional y el único valor permitido es `PUE` (Pago en Una sola Exhibición). + /// Valores: "PUE". + /// Opcional. + /// + [JsonIgnore] + public string? PaymentMethod + { + get => TryGetValue("payment_method", out var value) ? (string?)value! : default!; + set => this["payment_method"] = value; + } + + /// + /// Documentos relacionados con la nota de crédito. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// Conceptos a incluir en la nota de crédito. + /// + /// El número máximo de elementos que puedes incluir en el comprobante es de 5,000. Si necesitas + /// emitir un comprobante con más de 5,000 conceptos, puedes dividir la transacción en varios comprobantes. + /// Opcional. + /// + [JsonIgnore] + public List? Items + { + get => TryGetValue("items", out var value) ? (List?)value! : default!; + set => this["items"] = value; + } + + /// + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos en [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en nuestras librerías. + /// Opcional. + /// + [JsonIgnore] + public string? Use + { + get => TryGetValue("use", out var value) ? (string?)value! : default!; + set => this["use"] = value; + } + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonIgnore] + public string? Currency + { + get => TryGetValue("currency", out var value) ? (string?)value! : default!; + set => this["currency"] = value; + } + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos (MXN) que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Opcional. + /// + [JsonIgnore] + public decimal? Exchange + { + get => TryGetValue("exchange", out var value) ? (decimal?)value! : default!; + set => this["exchange"] = value; + } + + /// + /// Complementos a incluir en el comprobante. Puedes incluir cualquier + /// complemento en el comprobante si tú mismo construyes el nodo XML del + /// complemento y usas el tipo `custom`. Es necesario agregar la información + /// del complemento al PDF por separado usando el parámetro `pdf_custom_section`. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// Estado de la factura. El valor `draft` identifica un borrador que no se ha timbrado ni enviado al SAT. + /// Sólo es posible editar facturas con este estado; al editarlas, no se puede cambiar `status`. + /// Valores: "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). No puede ser anterior a 72 horas en el pasado, ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonEditInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonEditInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonEditInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonEditInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + /// + /// Cliente receptor de la factura. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + } +} diff --git a/Models/Inputs/InvoiceEgresoInput.cs b/Models/Inputs/InvoiceEgresoInput.cs new file mode 100644 index 0000000..b9b322d --- /dev/null +++ b/Models/Inputs/InvoiceEgresoInput.cs @@ -0,0 +1,281 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Egreso + /// + public class InvoiceEgresoInput : Dictionary + { + /// + /// Crea InvoiceEgresoInput. + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). Requerido. + /// Conceptos a incluir en la nota de crédito. El número máximo de elementos que puedes incluir en el comprobante es de 5,000. Si necesitas emitir un comprobante con más de 5,000 conceptos, puedes dividir la transacción en varios comprobantes. Requerido. + public InvoiceEgresoInput(string @paymentForm, List @items) + { + this["payment_form"] = @paymentForm; + this["items"] = @items; + this["type"] = "E"; + } + + /// + /// type + /// Valores: "E". + /// Requerido. + /// + [JsonIgnore] + public string Type + { + get => TryGetValue("type", out var value) ? (string)value! : default!; + set => this["type"] = value; + } + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Requerido. + /// + [JsonIgnore] + public string PaymentForm + { + get => TryGetValue("payment_form", out var value) ? (string)value! : default!; + set => this["payment_form"] = value; + } + + /// + /// Código del método de pago según el catálogo del SAT. Para facturas de Egreso, + /// este campo es opcional y el único valor permitido es `PUE` (Pago en Una sola Exhibición). + /// Valores: "PUE". + /// Opcional. + /// + [JsonIgnore] + public string? PaymentMethod + { + get => TryGetValue("payment_method", out var value) ? (string?)value! : default!; + set => this["payment_method"] = value; + } + + /// + /// Documentos relacionados con la nota de crédito. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// Conceptos a incluir en la nota de crédito. + /// + /// El número máximo de elementos que puedes incluir en el comprobante es de 5,000. Si necesitas + /// emitir un comprobante con más de 5,000 conceptos, puedes dividir la transacción en varios comprobantes. + /// Requerido. + /// + [JsonIgnore] + public List Items + { + get => TryGetValue("items", out var value) ? (List)value! : default!; + set => this["items"] = value; + } + + /// + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos en [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en nuestras librerías. + /// Opcional. + /// + [JsonIgnore] + public string? Use + { + get => TryGetValue("use", out var value) ? (string?)value! : default!; + set => this["use"] = value; + } + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonIgnore] + public string? Currency + { + get => TryGetValue("currency", out var value) ? (string?)value! : default!; + set => this["currency"] = value; + } + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos (MXN) que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Opcional. + /// + [JsonIgnore] + public decimal? Exchange + { + get => TryGetValue("exchange", out var value) ? (decimal?)value! : default!; + set => this["exchange"] = value; + } + + /// + /// Complementos a incluir en el comprobante. Puedes incluir cualquier + /// complemento en el comprobante si tú mismo construyes el nodo XML del + /// complemento y usas el tipo `custom`. Es necesario agregar la información + /// del complemento al PDF por separado usando el parámetro `pdf_custom_section`. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// customer + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// Estado inicial de la factura. Si se envía `draft`, la factura se guardará como borrador y no se timbrará ni se + /// enviará al SAT. También al enviar `draft`, todos los campos requeridos se vuelven + /// opcionales. Si se omite, el estado por default es `pending` y una vez timbrada (en la respuesta) este + /// campo se actualizará a `valid`. Para facturas asíncronas, este campo se quedará en `pending` hasta que + /// se timbre la factura. + /// Valores: "pending", "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601. Si se omite, se utiliza la fecha y hora actuales. No puede ser anterior a 72 horas en el pasado ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceGetPaymentSummaryParams.cs b/Models/Inputs/InvoiceGetPaymentSummaryParams.cs new file mode 100644 index 0000000..8e0dc2e --- /dev/null +++ b/Models/Inputs/InvoiceGetPaymentSummaryParams.cs @@ -0,0 +1,37 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceGetPaymentSummaryParams + /// + public class InvoiceGetPaymentSummaryParams : Dictionary + { + /// + /// Crea InvoiceGetPaymentSummaryParams. + /// + /// Monto que se paga de esta factura, expresado en la divisa de la factura. No puede exceder el saldo pendiente. Requerido. + public InvoiceGetPaymentSummaryParams(decimal @amount) + { + this["amount"] = @amount; + } + + /// + /// Monto que se paga de esta factura, expresado en la divisa de la factura. No puede exceder el saldo pendiente. + /// Requerido. + /// + [JsonIgnore] + public decimal Amount + { + get => TryGetValue("amount", out var value) ? (decimal)value! : default!; + set => this["amount"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceIngresoDraftInput.cs b/Models/Inputs/InvoiceIngresoDraftInput.cs new file mode 100644 index 0000000..2d3293a --- /dev/null +++ b/Models/Inputs/InvoiceIngresoDraftInput.cs @@ -0,0 +1,323 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Datos de la factura según su tipo y estado inicial. Omite status para timbrar; usa draft para guardar un borrador. + /// + public class InvoiceIngresoDraftInput : Dictionary + { + /// + /// Crea InvoiceIngresoDraftInput. + /// + public InvoiceIngresoDraftInput() + { + this["type"] = "I"; + this["status"] = "draft"; + } + + /// + /// Tipo de comprobante de esta variante de entrada. + /// Valores: "I". + /// Opcional. + /// + [JsonIgnore] + public string? Type + { + get => TryGetValue("type", out var value) ? (string?)value! : default!; + set => this["type"] = value; + } + + /// + /// Conceptos a incluir en la factura. + /// + /// El número máximo de elementos que puedes incluir en una factura es de 5,000. Si necesitas + /// emitir una factura con más de 5,000 conceptos, puedes dividir la transacción en varias facturas. + /// Opcional. + /// + [JsonIgnore] + public List? Items + { + get => TryGetValue("items", out var value) ? (List?)value! : default!; + set => this["items"] = value; + } + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? PaymentForm + { + get => TryGetValue("payment_form", out var value) ? (string?)value! : default!; + set => this["payment_form"] = value; + } + + /// + /// Código del método de pago según el catálogo del SAT. + /// + /// - `PUE`: Pago en Una sola Exhibición + /// - `PPD`: Pago en Parcialidades o Diferido + /// Valores: "PUE", "PPD". + /// Opcional. + /// + [JsonIgnore] + public string? PaymentMethod + { + get => TryGetValue("payment_method", out var value) ? (string?)value! : default!; + set => this["payment_method"] = value; + } + + /// + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos + /// en [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en + /// nuestras librerías. + /// + /// Para factura global debe ingresarse la clave `S01`. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Use + { + get => TryGetValue("use", out var value) ? (string?)value! : default!; + set => this["use"] = value; + } + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonIgnore] + public string? Currency + { + get => TryGetValue("currency", out var value) ? (string?)value! : default!; + set => this["currency"] = value; + } + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos + /// mexicanos (MXN) que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Opcional. + /// + [JsonIgnore] + public decimal? Exchange + { + get => TryGetValue("exchange", out var value) ? (decimal?)value! : default!; + set => this["exchange"] = value; + } + + /// + /// Condiciones de pago + /// Opcional. + /// + [JsonIgnore] + public string? Conditions + { + get => TryGetValue("conditions", out var value) ? (string?)value! : default!; + set => this["conditions"] = value; + } + + /// + /// Documentos relacionados con la factura. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// Información del periodo que abarca una factura global. En una factura de ingreso, este objeto es obligatorio cuando el receptor tiene `tax_id=XAXX010101000` y `legal_name=PUBLICO EN GENERAL`. Incluye periodicity, months y year. + /// Opcional. + /// + [JsonIgnore] + public InvoiceCreateInputGlobal? Global + { + get => TryGetValue("global", out var value) ? (InvoiceCreateInputGlobal?)value! : default!; + set => this["global"] = value; + } + + /// + /// Indica si el comprobante ampara una operación de exportación. + /// + /// - `01`: No aplica + /// - `02`: Definitiva con clave A1 + /// - `03`: Temporal + /// - `04`: Definitiva con clave distinta a A1 o cuando no existe enajenación en términos del CFF + /// Valores: "01", "04", "02", "03". + /// Opcional. + /// + [JsonIgnore] + public string? Export + { + get => TryGetValue("export", out var value) ? (string?)value! : default!; + set => this["export"] = value; + } + + /// + /// Complementos a incluir en la factura. Puedes incluir cualquier complemento en la + /// factura si tú mismo construyes el nodo XML del complemento y usas el tipo `custom`. + /// Es necesario agregar la información del complemento al PDF por separado usando el + /// parámetro `pdf_custom_section`. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// Estado de la factura. El valor `draft` identifica un borrador que no se ha timbrado ni enviado al SAT. + /// Sólo es posible editar facturas con este estado; al editarlas, no se puede cambiar `status`. + /// Valores: "draft". + /// Requerido. + /// + [JsonIgnore] + public string Status + { + get => TryGetValue("status", out var value) ? (string)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). No puede ser anterior a 72 horas en el pasado, ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonEditInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonEditInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonEditInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonEditInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + /// + /// Cliente receptor de la factura. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + } +} diff --git a/Models/Inputs/InvoiceIngresoEditInput.cs b/Models/Inputs/InvoiceIngresoEditInput.cs new file mode 100644 index 0000000..7c98984 --- /dev/null +++ b/Models/Inputs/InvoiceIngresoEditInput.cs @@ -0,0 +1,323 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Ingreso + /// + public class InvoiceIngresoEditInput : Dictionary + { + /// + /// Crea InvoiceIngresoEditInput. + /// + public InvoiceIngresoEditInput() + { + this["type"] = "I"; + this["status"] = "draft"; + } + + /// + /// Tipo de comprobante de esta variante de entrada. + /// Valores: "I". + /// Opcional. + /// + [JsonIgnore] + public string? Type + { + get => TryGetValue("type", out var value) ? (string?)value! : default!; + set => this["type"] = value; + } + + /// + /// Conceptos a incluir en la factura. + /// + /// El número máximo de elementos que puedes incluir en una factura es de 5,000. Si necesitas + /// emitir una factura con más de 5,000 conceptos, puedes dividir la transacción en varias facturas. + /// Opcional. + /// + [JsonIgnore] + public List? Items + { + get => TryGetValue("items", out var value) ? (List?)value! : default!; + set => this["items"] = value; + } + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? PaymentForm + { + get => TryGetValue("payment_form", out var value) ? (string?)value! : default!; + set => this["payment_form"] = value; + } + + /// + /// Código del método de pago según el catálogo del SAT. + /// + /// - `PUE`: Pago en Una sola Exhibición + /// - `PPD`: Pago en Parcialidades o Diferido + /// Valores: "PUE", "PPD". + /// Opcional. + /// + [JsonIgnore] + public string? PaymentMethod + { + get => TryGetValue("payment_method", out var value) ? (string?)value! : default!; + set => this["payment_method"] = value; + } + + /// + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos + /// en [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en + /// nuestras librerías. + /// + /// Para factura global debe ingresarse la clave `S01`. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Use + { + get => TryGetValue("use", out var value) ? (string?)value! : default!; + set => this["use"] = value; + } + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonIgnore] + public string? Currency + { + get => TryGetValue("currency", out var value) ? (string?)value! : default!; + set => this["currency"] = value; + } + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos + /// mexicanos (MXN) que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Opcional. + /// + [JsonIgnore] + public decimal? Exchange + { + get => TryGetValue("exchange", out var value) ? (decimal?)value! : default!; + set => this["exchange"] = value; + } + + /// + /// Condiciones de pago + /// Opcional. + /// + [JsonIgnore] + public string? Conditions + { + get => TryGetValue("conditions", out var value) ? (string?)value! : default!; + set => this["conditions"] = value; + } + + /// + /// Documentos relacionados con la factura. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// Información del periodo que abarca una factura global. En una factura de ingreso, este objeto es obligatorio cuando el receptor tiene `tax_id=XAXX010101000` y `legal_name=PUBLICO EN GENERAL`. Incluye periodicity, months y year. + /// Opcional. + /// + [JsonIgnore] + public InvoiceCreateInputGlobal? Global + { + get => TryGetValue("global", out var value) ? (InvoiceCreateInputGlobal?)value! : default!; + set => this["global"] = value; + } + + /// + /// Indica si el comprobante ampara una operación de exportación. + /// + /// - `01`: No aplica + /// - `02`: Definitiva con clave A1 + /// - `03`: Temporal + /// - `04`: Definitiva con clave distinta a A1 o cuando no existe enajenación en términos del CFF + /// Valores: "01", "04", "02", "03". + /// Opcional. + /// + [JsonIgnore] + public string? Export + { + get => TryGetValue("export", out var value) ? (string?)value! : default!; + set => this["export"] = value; + } + + /// + /// Complementos a incluir en la factura. Puedes incluir cualquier complemento en la + /// factura si tú mismo construyes el nodo XML del complemento y usas el tipo `custom`. + /// Es necesario agregar la información del complemento al PDF por separado usando el + /// parámetro `pdf_custom_section`. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// Estado de la factura. El valor `draft` identifica un borrador que no se ha timbrado ni enviado al SAT. + /// Sólo es posible editar facturas con este estado; al editarlas, no se puede cambiar `status`. + /// Valores: "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). No puede ser anterior a 72 horas en el pasado, ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonEditInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonEditInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonEditInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonEditInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + /// + /// Cliente receptor de la factura. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + } +} diff --git a/Models/Inputs/InvoiceIngresoInput.cs b/Models/Inputs/InvoiceIngresoInput.cs new file mode 100644 index 0000000..cc5b523 --- /dev/null +++ b/Models/Inputs/InvoiceIngresoInput.cs @@ -0,0 +1,330 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Ingreso + /// + public class InvoiceIngresoInput : Dictionary + { + /// + /// Crea InvoiceIngresoInput. + /// + /// Conceptos a incluir en la factura. El número máximo de elementos que puedes incluir en una factura es de 5,000. Si necesitas emitir una factura con más de 5,000 conceptos, puedes dividir la transacción en varias facturas. Requerido. + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). Requerido. + public InvoiceIngresoInput(List @items, string @paymentForm) + { + this["items"] = @items; + this["payment_form"] = @paymentForm; + this["type"] = "I"; + } + + /// + /// Tipo de comprobante. El valor default es `“I”` (Ingreso). + /// Valores: "I". + /// Opcional. + /// + [JsonIgnore] + public string? Type + { + get => TryGetValue("type", out var value) ? (string?)value! : default!; + set => this["type"] = value; + } + + /// + /// Conceptos a incluir en la factura. + /// + /// El número máximo de elementos que puedes incluir en una factura es de 5,000. Si necesitas + /// emitir una factura con más de 5,000 conceptos, puedes dividir la transacción en varias facturas. + /// Requerido. + /// + [JsonIgnore] + public List Items + { + get => TryGetValue("items", out var value) ? (List)value! : default!; + set => this["items"] = value; + } + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Requerido. + /// + [JsonIgnore] + public string PaymentForm + { + get => TryGetValue("payment_form", out var value) ? (string)value! : default!; + set => this["payment_form"] = value; + } + + /// + /// Código del método de pago según el catálogo del SAT. + /// + /// - `PUE`: Pago en Una sola Exhibición + /// - `PPD`: Pago en Parcialidades o Diferido + /// Valores: "PUE", "PPD". + /// Opcional. + /// + [JsonIgnore] + public string? PaymentMethod + { + get => TryGetValue("payment_method", out var value) ? (string?)value! : default!; + set => this["payment_method"] = value; + } + + /// + /// Si se omite o es null, se utiliza el uso configurado en el cliente; si no tiene uno, se utiliza G03. Para clientes extranjeros o con RFC genérico se utiliza S01, incluso si se envía otro uso válido del catálogo. + /// + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos + /// en [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en + /// nuestras librerías. + /// + /// En una factura global, el uso es `S01`. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Use + { + get => TryGetValue("use", out var value) ? (string?)value! : default!; + set => this["use"] = value; + } + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonIgnore] + public string? Currency + { + get => TryGetValue("currency", out var value) ? (string?)value! : default!; + set => this["currency"] = value; + } + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos + /// mexicanos (MXN) que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Opcional. + /// + [JsonIgnore] + public decimal? Exchange + { + get => TryGetValue("exchange", out var value) ? (decimal?)value! : default!; + set => this["exchange"] = value; + } + + /// + /// Condiciones de pago + /// Opcional. + /// + [JsonIgnore] + public string? Conditions + { + get => TryGetValue("conditions", out var value) ? (string?)value! : default!; + set => this["conditions"] = value; + } + + /// + /// Documentos relacionados con la factura. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// Información del periodo que abarca una factura global. En una factura de ingreso, este objeto es obligatorio cuando el receptor tiene `tax_id=XAXX010101000` y `legal_name=PUBLICO EN GENERAL`. Incluye periodicity, months y year. + /// Opcional. + /// + [JsonIgnore] + public InvoiceCreateInputGlobal? Global + { + get => TryGetValue("global", out var value) ? (InvoiceCreateInputGlobal?)value! : default!; + set => this["global"] = value; + } + + /// + /// Indica si el comprobante ampara una operación de exportación. + /// + /// - `01`: No aplica + /// - `02`: Definitiva con clave A1 + /// - `03`: Temporal + /// - `04`: Definitiva con clave distinta a A1 o cuando no existe enajenación en términos del CFF + /// Valores: "01", "04", "02", "03". + /// Opcional. + /// + [JsonIgnore] + public string? Export + { + get => TryGetValue("export", out var value) ? (string?)value! : default!; + set => this["export"] = value; + } + + /// + /// Complementos a incluir en la factura. Puedes incluir cualquier complemento en la + /// factura si tú mismo construyes el nodo XML del complemento y usas el tipo `custom`. + /// Es necesario agregar la información del complemento al PDF por separado usando el + /// parámetro `pdf_custom_section`. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// customer + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// Estado inicial de la factura. Si se envía `draft`, la factura se guardará como borrador y no se timbrará ni se + /// enviará al SAT. También al enviar `draft`, todos los campos requeridos se vuelven + /// opcionales. Si se omite, el estado por default es `pending` y una vez timbrada (en la respuesta) este + /// campo se actualizará a `valid`. Para facturas asíncronas, este campo se quedará en `pending` hasta que + /// se timbre la factura. + /// Valores: "pending", "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601. Si se omite, se utiliza la fecha y hora actuales. No puede ser anterior a 72 horas en el pasado ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceItemEgresoInput.cs b/Models/Inputs/InvoiceItemEgresoInput.cs new file mode 100644 index 0000000..50f3136 --- /dev/null +++ b/Models/Inputs/InvoiceItemEgresoInput.cs @@ -0,0 +1,103 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Conceptos incluidos en el documento + /// + public class InvoiceItemEgresoInput : Dictionary + { + /// + /// Crea InvoiceItemEgresoInput. + /// + /// Objeto con información del producto o servicio facturado. Requerido. + public InvoiceItemEgresoInput(OneOf @product) + { + this["product"] = @product.Value; + } + + /// + /// Cantidad de unidades incluidas del mismo concepto. + /// Opcional. + /// + [JsonIgnore] + public decimal? Quantity + { + get => TryGetValue("quantity", out var value) ? (decimal?)value! : default!; + set => this["quantity"] = value; + } + + /// + /// Monto total de descuento aplicado a este concepto. + /// Opcional. + /// + [JsonIgnore] + public decimal? Discount + { + get => TryGetValue("discount", out var value) ? (decimal?)value! : default!; + set => this["discount"] = value; + } + + /// + /// Objeto con información del producto o servicio facturado. + /// Requerido. + /// + [JsonIgnore] + public OneOf Product + { + get => TryGetValue("product", out var value) ? OneOf.FromValue(value) : default!; + set => this["product"] = value.Value; + } + + /// + /// parts + /// Opcional. + /// + [JsonIgnore] + public List? Parts + { + get => TryGetValue("parts", out var value) ? (List?)value! : default!; + set => this["parts"] = value; + } + + /// + /// Números de pedimento asociados a este concepto. + /// Opcional. + /// + [JsonIgnore] + public List? CustomsKeys + { + get => TryGetValue("customs_keys", out var value) ? (List?)value! : default!; + set => this["customs_keys"] = value; + } + + /// + /// Código XML de tu complemento concepto, el complemento Hidrocarburos y Petrolíferos o el complemento Instituciones Educativas Privadas. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Complement + { + get => TryGetValue("complement", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["complement"] = value?.Value; + } + + /// + /// third_party + /// Opcional. + /// + [JsonIgnore] + public InvoiceItemInputThirdParty? ThirdParty + { + get => TryGetValue("third_party", out var value) ? (InvoiceItemInputThirdParty?)value! : default!; + set => this["third_party"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceItemInput.cs b/Models/Inputs/InvoiceItemInput.cs new file mode 100644 index 0000000..2676def --- /dev/null +++ b/Models/Inputs/InvoiceItemInput.cs @@ -0,0 +1,114 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Conceptos incluidos en el documento + /// + public class InvoiceItemInput : Dictionary + { + /// + /// Crea InvoiceItemInput. + /// + /// Objeto con información del producto o servicio facturado. Requerido. + public InvoiceItemInput(OneOf @product) + { + this["product"] = @product.Value; + } + + /// + /// Cantidad de unidades incluidas del mismo concepto. + /// Opcional. + /// + [JsonIgnore] + public decimal? Quantity + { + get => TryGetValue("quantity", out var value) ? (decimal?)value! : default!; + set => this["quantity"] = value; + } + + /// + /// Monto total de descuento aplicado a este concepto. + /// Opcional. + /// + [JsonIgnore] + public decimal? Discount + { + get => TryGetValue("discount", out var value) ? (decimal?)value! : default!; + set => this["discount"] = value; + } + + /// + /// Objeto con información del producto o servicio facturado. + /// Requerido. + /// + [JsonIgnore] + public OneOf Product + { + get => TryGetValue("product", out var value) ? OneOf.FromValue(value) : default!; + set => this["product"] = value.Value; + } + + /// + /// parts + /// Opcional. + /// + [JsonIgnore] + public List? Parts + { + get => TryGetValue("parts", out var value) ? (List?)value! : default!; + set => this["parts"] = value; + } + + /// + /// Números de pedimento asociados a este concepto. + /// Opcional. + /// + [JsonIgnore] + public List? CustomsKeys + { + get => TryGetValue("customs_keys", out var value) ? (List?)value! : default!; + set => this["customs_keys"] = value; + } + + /// + /// Código XML de tu complemento concepto, el complemento Hidrocarburos y Petrolíferos o el complemento Instituciones Educativas Privadas. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Complement + { + get => TryGetValue("complement", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["complement"] = value?.Value; + } + + /// + /// third_party + /// Opcional. + /// + [JsonIgnore] + public InvoiceItemInputThirdParty? ThirdParty + { + get => TryGetValue("third_party", out var value) ? (InvoiceItemInputThirdParty?)value! : default!; + set => this["third_party"] = value; + } + + /// + /// Números de cuenta para el impuesto predial. + /// Opcional. + /// + [JsonIgnore] + public List? PropertyTaxAccount + { + get => TryGetValue("property_tax_account", out var value) ? (List?)value! : default!; + set => this["property_tax_account"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceItemInputThirdParty.cs b/Models/Inputs/InvoiceItemInputThirdParty.cs new file mode 100644 index 0000000..035c622 --- /dev/null +++ b/Models/Inputs/InvoiceItemInputThirdParty.cs @@ -0,0 +1,61 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceItemInputThirdParty + /// + public class InvoiceItemInputThirdParty : Dictionary + { + /// + /// Nombre o razón social del tercero. + /// Opcional. + /// + [JsonIgnore] + public string? LegalName + { + get => TryGetValue("legal_name", out var value) ? (string?)value! : default!; + set => this["legal_name"] = value; + } + + /// + /// RFC del tercero. + /// Opcional. + /// + [JsonIgnore] + public string? TaxId + { + get => TryGetValue("tax_id", out var value) ? (string?)value! : default!; + set => this["tax_id"] = value; + } + + /// + /// Régimen fiscal del tercero. + /// Opcional. + /// + [JsonIgnore] + public string? TaxSystem + { + get => TryGetValue("tax_system", out var value) ? (string?)value! : default!; + set => this["tax_system"] = value; + } + + /// + /// Código postal del tercero. + /// Opcional. + /// + [JsonIgnore] + public string? Zip + { + get => TryGetValue("zip", out var value) ? (string?)value! : default!; + set => this["zip"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceItemProductEgresoInput.cs b/Models/Inputs/InvoiceItemProductEgresoInput.cs new file mode 100644 index 0000000..e545dd1 --- /dev/null +++ b/Models/Inputs/InvoiceItemProductEgresoInput.cs @@ -0,0 +1,143 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Product + /// + public class InvoiceItemProductEgresoInput : Dictionary + { + /// + /// Crea InvoiceItemProductEgresoInput. + /// + /// Resumen de la operación en una sola descripción. Deben mencionarse cada uno de los productos que contempla el descuento, devolución o bonificación aplicada y que contienen las facturas relacionadas. Si el egreso está basado en un pocentaje (como al aplicar un 30% de descuento), dicho porcentaje debe incluirse en la descripción junto al nombre del producto que corresponda. Requerido. + /// Suma total de la cantidad devuelta, descontada o bonificada. Requerido. + public InvoiceItemProductEgresoInput(string @description, decimal @price) + { + this["description"] = @description; + this["price"] = @price; + } + + /// + /// Resumen de la operación en una sola descripción. Deben mencionarse cada uno de los productos que contempla el descuento, devolución o bonificación aplicada y que contienen las facturas relacionadas. Si el egreso está basado en un pocentaje (como al aplicar un 30% de descuento), dicho porcentaje debe incluirse en la descripción junto al nombre del producto que corresponda. + /// Requerido. + /// + [JsonIgnore] + public string Description + { + get => TryGetValue("description", out var value) ? (string)value! : default!; + set => this["description"] = value; + } + + /// + /// Clave de producto/servicio, del catálogo del SAT. Nosotros te proporcionamos una manera más conveniente de encontrarlo utilizando nuestra [herramienta de búsqueda de claves](https://dashboard.facturapi.io/catalogs/productKey). + /// Opcional. + /// + [JsonIgnore] + public string? ProductKey + { + get => TryGetValue("product_key", out var value) ? (string?)value! : default!; + set => this["product_key"] = value; + } + + /// + /// Suma total de la cantidad devuelta, descontada o bonificada. + /// Requerido. + /// + [JsonIgnore] + public decimal Price + { + get => TryGetValue("price", out var value) ? (decimal)value! : default!; + set => this["price"] = value; + } + + /// + /// - `true`: Indica que todos los impuestos aplicables están incluidos en el precio (atributo price) y se desglosarán automáticamente al emitir la factura. + /// - `false`: Indica que el atributo price no incluye impuestos, por lo que aquellos impuestos a aplicar se sumarán en el precio final. + /// Opcional. + /// + [JsonIgnore] + public bool? TaxIncluded + { + get => TryGetValue("tax_included", out var value) ? (bool?)value! : default!; + set => this["tax_included"] = value; + } + + /// + /// Código que representa si el bien o servicio es objeto de impuesto o no. Este atributo corresponde al campo "ObjetoImp" en el CFDI. + /// + /// - `01`: No objeto de impuesto. + /// - `02`: Sí objeto de impuesto. + /// - `03`: Sí objeto de impuesto, pero no obligado a desglose. + /// - `04`: Sí objeto de impuesto, y no causa impuesto. + /// - `05`: Sí objeto de impuesto, IVA crédito PODEBI. + /// Valores: "01", "04", "02", "03", "05", "06", "07", "08". + /// Opcional. + /// + [JsonIgnore] + public string? Taxability + { + get => TryGetValue("taxability", out var value) ? (string?)value! : default!; + set => this["taxability"] = value; + } + + /// + /// Lista de impuestos que deberán aplicarse a este producto. + /// + /// Resolución cuando `taxes` se omite o es `null`: + /// - `taxability` omitido o `"02"`: se agrega IVA trasladado 16%. + /// - `taxability` en `"01"`, `"03"`, `"04"`, `"05"`, `"06"` o `"08"`: se guarda `[]`. + /// - `taxability = "07"`: la solicitud es inválida; debes enviar al menos un IEPS de traslado y no incluir IVA. + /// + /// Si envías `taxes` explícitamente, se usa el arreglo enviado. + /// Opcional. + /// + [JsonIgnore] + public List? Taxes + { + get => TryGetValue("taxes", out var value) ? (List?)value! : default!; + set => this["taxes"] = value; + } + + /// + /// Arreglo de impuestos locales (estatales o municipales), en caso de haberlos. + /// Opcional. + /// + [JsonIgnore] + public List? LocalTaxes + { + get => TryGetValue("local_taxes", out var value) ? (List?)value! : default!; + set => this["local_taxes"] = value; + } + + /// + /// Clave de unidad de medida, del catálogo del SAT. + /// Puedes encontrar la clave utilizando nuestra [herramienta de búsqueda de claves](https://dashboard.facturapi.io/catalogs/unit). + /// Opcional. + /// + [JsonIgnore] + public string? UnitKey + { + get => TryGetValue("unit_key", out var value) ? (string?)value! : default!; + set => this["unit_key"] = value; + } + + /// + /// Palabra que representa la unidad de medida de tu producto. Debe estar relacionada con la clave de unidad `unit_key`. + /// Opcional. + /// + [JsonIgnore] + public string? UnitName + { + get => TryGetValue("unit_name", out var value) ? (string?)value! : default!; + set => this["unit_name"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceItemProductInput.cs b/Models/Inputs/InvoiceItemProductInput.cs new file mode 100644 index 0000000..c41ad2d --- /dev/null +++ b/Models/Inputs/InvoiceItemProductInput.cs @@ -0,0 +1,160 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Product + /// + public class InvoiceItemProductInput : Dictionary + { + /// + /// Crea InvoiceItemProductInput. + /// + /// Descripción del bien o servicio como aparecerá en la factura. Requerido. + /// Clave de producto/servicio, del catálogo del SAT. Nosotros te proporcionamos una manera más conveniente de encontrarlo utilizando nuestra [herramienta de búsqueda de claves](https://dashboard.facturapi.io/catalogs/productKey). Requerido. + /// Precio por unidad del bien o servicio. Este valor representará el precio con IVA incluido o sin él, dependiendo del valor de `tax_included`. Requerido. + public InvoiceItemProductInput(string @description, string @productKey, decimal @price) + { + this["description"] = @description; + this["product_key"] = @productKey; + this["price"] = @price; + } + + /// + /// Palabra que representa la unidad de medida de tu producto. Debe estar relacionada con la clave de unidad `unit_key`. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? UnitName + { + get => TryGetValue("unit_name", out var value) ? (string?)value! : default!; + set => this["unit_name"] = value; + } + + /// + /// Descripción del bien o servicio como aparecerá en la factura. + /// Requerido. + /// + [JsonIgnore] + public string Description + { + get => TryGetValue("description", out var value) ? (string)value! : default!; + set => this["description"] = value; + } + + /// + /// Clave de producto/servicio, del catálogo del SAT. Nosotros te proporcionamos una manera más conveniente de encontrarlo utilizando nuestra [herramienta de búsqueda de claves](https://dashboard.facturapi.io/catalogs/productKey). + /// Requerido. + /// + [JsonIgnore] + public string ProductKey + { + get => TryGetValue("product_key", out var value) ? (string)value! : default!; + set => this["product_key"] = value; + } + + /// + /// Precio por unidad del bien o servicio. Este valor representará el precio con IVA incluido o sin él, dependiendo del valor de `tax_included`. + /// Requerido. + /// + [JsonIgnore] + public decimal Price + { + get => TryGetValue("price", out var value) ? (decimal)value! : default!; + set => this["price"] = value; + } + + /// + /// - `true`: Indica que todos los impuestos aplicables están incluidos en el precio (atributo price) y se desglosarán automáticamente al emitir la factura. + /// - `false`: Indica que el atributo price no incluye impuestos, por lo que aquellos impuestos a aplicar se sumarán en el precio final. + /// Opcional. + /// + [JsonIgnore] + public bool? TaxIncluded + { + get => TryGetValue("tax_included", out var value) ? (bool?)value! : default!; + set => this["tax_included"] = value; + } + + /// + /// Código que representa si el bien o servicio es objeto de impuesto o no. Este atributo corresponde al campo "ObjetoImp" en el CFDI. + /// + /// - `01`: No objeto de impuesto. + /// - `02`: Sí objeto de impuesto. + /// - `03`: Sí objeto de impuesto, pero no obligado a desglose. + /// - `04`: Sí objeto de impuesto, y no causa impuesto. + /// - `05`: Sí objeto de impuesto, IVA crédito PODEBI. + /// - `06`: Sí objeto de impuesto, no IVA trasladado. + /// - `07`: No traslado de IVA, pero desglose de IEPS. + /// - `08`: No traslado de IVA sin desglose de IEPS. + /// Valores: "01", "04", "02", "03", "05", "06", "07", "08". + /// Opcional. + /// + [JsonIgnore] + public string? Taxability + { + get => TryGetValue("taxability", out var value) ? (string?)value! : default!; + set => this["taxability"] = value; + } + + /// + /// Lista de impuestos que deberán aplicarse a este producto. + /// + /// Resolución cuando `taxes` se omite o es `null`: + /// - `taxability` omitido o `"02"`: se agrega IVA trasladado 16%. + /// - `taxability` en `"01"`, `"03"`, `"04"`, `"05"`, `"06"` o `"08"`: se guarda `[]`. + /// - `taxability = "07"`: la solicitud es inválida; debes enviar al menos un IEPS de traslado y no incluir IVA. + /// + /// Si envías `taxes` explícitamente, se usa el arreglo enviado. + /// Opcional. + /// + [JsonIgnore] + public List? Taxes + { + get => TryGetValue("taxes", out var value) ? (List?)value! : default!; + set => this["taxes"] = value; + } + + /// + /// Arreglo de impuestos locales (estatales o municipales), en caso de haberlos. + /// Opcional. + /// + [JsonIgnore] + public List? LocalTaxes + { + get => TryGetValue("local_taxes", out var value) ? (List?)value! : default!; + set => this["local_taxes"] = value; + } + + /// + /// Clave de unidad de medida, del catálogo del SAT. El valor por default `"H87"` (elemento) es la clave para representar una pieza o unidad de venta (lápiz, cuaderno, televisión, etc). + /// Si la unidad de tu producto es kilogramos, litros, horas u otra unidad, puedes encontrar la clave utilizando nuestra [herramienta de búsqueda de claves](https://dashboard.facturapi.io/catalogs/unit). + /// Opcional. + /// + [JsonIgnore] + public string? UnitKey + { + get => TryGetValue("unit_key", out var value) ? (string?)value! : default!; + set => this["unit_key"] = value; + } + + /// + /// Identificador de uso interno designado por la empresa. Puede tener cualquier valor. + /// Opcional. + /// + [JsonIgnore] + public string? Sku + { + get => TryGetValue("sku", out var value) ? (string?)value! : default!; + set => this["sku"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceItemProductTrasladoInput.cs b/Models/Inputs/InvoiceItemProductTrasladoInput.cs new file mode 100644 index 0000000..555a10d --- /dev/null +++ b/Models/Inputs/InvoiceItemProductTrasladoInput.cs @@ -0,0 +1,82 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Product + /// + public class InvoiceItemProductTrasladoInput : Dictionary + { + /// + /// Crea InvoiceItemProductTrasladoInput. + /// + /// Descripción del bien o servicio como aparecerá en la factura. Requerido. + public InvoiceItemProductTrasladoInput(string @description) + { + this["description"] = @description; + } + + /// + /// Descripción del bien o servicio como aparecerá en la factura. + /// Requerido. + /// + [JsonIgnore] + public string Description + { + get => TryGetValue("description", out var value) ? (string)value! : default!; + set => this["description"] = value; + } + + /// + /// Clave de producto/servicio, del catálogo del SAT. Nosotros te proporcionamos una manera más conveniente de encontrarlo utilizando nuestra [herramienta de búsqueda de claves](https://dashboard.facturapi.io/catalogs/productKey). + /// Opcional. + /// + [JsonIgnore] + public string? ProductKey + { + get => TryGetValue("product_key", out var value) ? (string?)value! : default!; + set => this["product_key"] = value; + } + + /// + /// Clave de unidad de medida, del catálogo del SAT. El valor por default `"H87"` (elemento) es la clave para representar una pieza o unidad de venta (lápiz, cuaderno, televisión, etc). + /// Si la unidad de tu producto es kilogramos, litros, horas u otra unidad, te proporcionamos una manera conveniente de encontrar la clave utilizando nuestra [herramienta de búsqueda de claves](https://dashboard.facturapi.io/catalogs/unit). + /// Opcional. + /// + [JsonIgnore] + public string? UnitKey + { + get => TryGetValue("unit_key", out var value) ? (string?)value! : default!; + set => this["unit_key"] = value; + } + + /// + /// Palabra que representa la unidad de medida de tu producto. Debe estar relacionada con la clave de unidad `unit_key`. + /// Opcional. + /// + [JsonIgnore] + public string? UnitName + { + get => TryGetValue("unit_name", out var value) ? (string?)value! : default!; + set => this["unit_name"] = value; + } + + /// + /// Identificador de uso interno designado por la empresa. Puede tener cualquier valor. + /// Opcional. + /// + [JsonIgnore] + public string? Sku + { + get => TryGetValue("sku", out var value) ? (string?)value! : default!; + set => this["sku"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceItemThirdPartyInput.cs b/Models/Inputs/InvoiceItemThirdPartyInput.cs new file mode 100644 index 0000000..1572cd8 --- /dev/null +++ b/Models/Inputs/InvoiceItemThirdPartyInput.cs @@ -0,0 +1,61 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceItemThirdPartyInput + /// + public class InvoiceItemThirdPartyInput : Dictionary + { + /// + /// Nombre o razón social del tercero. + /// Opcional. + /// + [JsonIgnore] + public string? LegalName + { + get => TryGetValue("legal_name", out var value) ? (string?)value! : default!; + set => this["legal_name"] = value; + } + + /// + /// RFC del tercero. + /// Opcional. + /// + [JsonIgnore] + public string? TaxId + { + get => TryGetValue("tax_id", out var value) ? (string?)value! : default!; + set => this["tax_id"] = value; + } + + /// + /// Régimen fiscal del tercero. + /// Opcional. + /// + [JsonIgnore] + public string? TaxSystem + { + get => TryGetValue("tax_system", out var value) ? (string?)value! : default!; + set => this["tax_system"] = value; + } + + /// + /// Código postal del tercero. + /// Opcional. + /// + [JsonIgnore] + public string? Zip + { + get => TryGetValue("zip", out var value) ? (string?)value! : default!; + set => this["zip"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceItemTrasladoInput.cs b/Models/Inputs/InvoiceItemTrasladoInput.cs new file mode 100644 index 0000000..0c46cd2 --- /dev/null +++ b/Models/Inputs/InvoiceItemTrasladoInput.cs @@ -0,0 +1,93 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Conceptos incluidos en el documento + /// + public class InvoiceItemTrasladoInput : Dictionary + { + /// + /// Crea InvoiceItemTrasladoInput. + /// + /// Objeto con información del producto o servicio facturado. Requerido. + public InvoiceItemTrasladoInput(OneOf @product) + { + this["product"] = @product.Value; + } + + /// + /// Cantidad de unidades incluidas del mismo concepto. + /// Opcional. + /// + [JsonIgnore] + public decimal? Quantity + { + get => TryGetValue("quantity", out var value) ? (decimal?)value! : default!; + set => this["quantity"] = value; + } + + /// + /// Objeto con información del producto o servicio facturado. + /// Requerido. + /// + [JsonIgnore] + public OneOf Product + { + get => TryGetValue("product", out var value) ? OneOf.FromValue(value) : default!; + set => this["product"] = value.Value; + } + + /// + /// Números de pedimento asociados a este concepto. + /// Opcional. + /// + [JsonIgnore] + public List? CustomsKeys + { + get => TryGetValue("customs_keys", out var value) ? (List?)value! : default!; + set => this["customs_keys"] = value; + } + + /// + /// Format: xml + /// Código XML de tu complemento concepto. + /// Opcional. + /// + [JsonIgnore] + public string? Complement + { + get => TryGetValue("complement", out var value) ? (string?)value! : default!; + set => this["complement"] = value; + } + + /// + /// parts + /// Opcional. + /// + [JsonIgnore] + public List? Parts + { + get => TryGetValue("parts", out var value) ? (List?)value! : default!; + set => this["parts"] = value; + } + + /// + /// third_party + /// Opcional. + /// + [JsonIgnore] + public InvoiceItemTrasladoInputThirdParty? ThirdParty + { + get => TryGetValue("third_party", out var value) ? (InvoiceItemTrasladoInputThirdParty?)value! : default!; + set => this["third_party"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceItemTrasladoInputThirdParty.cs b/Models/Inputs/InvoiceItemTrasladoInputThirdParty.cs new file mode 100644 index 0000000..b7f56ca --- /dev/null +++ b/Models/Inputs/InvoiceItemTrasladoInputThirdParty.cs @@ -0,0 +1,76 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceItemTrasladoInputThirdParty + /// + public class InvoiceItemTrasladoInputThirdParty : Dictionary + { + /// + /// Crea InvoiceItemTrasladoInputThirdParty. + /// + /// Nombre o razón social del tercero. Requerido. + /// RFC del tercero. Requerido. + /// Régimen fiscal del tercero. Requerido. + /// Código postal del tercero. Requerido. + public InvoiceItemTrasladoInputThirdParty(string @legalName, string @taxId, string @taxSystem, string @zip) + { + this["legal_name"] = @legalName; + this["tax_id"] = @taxId; + this["tax_system"] = @taxSystem; + this["zip"] = @zip; + } + + /// + /// Nombre o razón social del tercero. + /// Requerido. + /// + [JsonIgnore] + public string LegalName + { + get => TryGetValue("legal_name", out var value) ? (string)value! : default!; + set => this["legal_name"] = value; + } + + /// + /// RFC del tercero. + /// Requerido. + /// + [JsonIgnore] + public string TaxId + { + get => TryGetValue("tax_id", out var value) ? (string)value! : default!; + set => this["tax_id"] = value; + } + + /// + /// Régimen fiscal del tercero. + /// Requerido. + /// + [JsonIgnore] + public string TaxSystem + { + get => TryGetValue("tax_system", out var value) ? (string)value! : default!; + set => this["tax_system"] = value; + } + + /// + /// Código postal del tercero. + /// Requerido. + /// + [JsonIgnore] + public string Zip + { + get => TryGetValue("zip", out var value) ? (string)value! : default!; + set => this["zip"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceListParams.cs b/Models/Inputs/InvoiceListParams.cs new file mode 100644 index 0000000..43fcb82 --- /dev/null +++ b/Models/Inputs/InvoiceListParams.cs @@ -0,0 +1,233 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceListParams + /// + public class InvoiceListParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Consulta. Texto a buscar en la factura. + /// + /// La búsqueda se realizará por coincidencias **parciales** en los campos: + /// + /// - `items[].product.description` + /// - `customer.legal_name` + /// + /// Y por coincidencias **exactas** en los campos: + /// + /// - `id` + /// - `uuid` + /// - `customer.tax_id` + /// - `folio_number` + /// - `total` + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// Identificador del cliente. Útil para obtener las facturas emitidas a un sólo cliente. + /// Opcional. + /// + [JsonIgnore] + public string? Customer + { + get => TryGetValue("customer", out var value) ? (string?)value! : default!; + set => this["customer"] = value; + } + + /// + /// Tipo de factura. Búsqueda por tipo de factura con las claves exactas. + /// Valores: "E", "I", "T", "N", "P". + /// Opcional. + /// + [JsonIgnore] + public string? Type + { + get => TryGetValue("type", out var value) ? (string?)value! : default!; + set => this["type"] = value; + } + + /// + /// Método de pago. Búsqueda exacta por método de pago. + /// Valores: "PUE", "PPD". + /// Opcional. + /// + [JsonIgnore] + public string? PaymentMethod + { + get => TryGetValue("payment_method", out var value) ? (string?)value! : default!; + set => this["payment_method"] = value; + } + + /// + /// Filtrar por folio de la factura. Coincidencia exacta. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Filtrar por serie de la factura. Coincidencia exacta. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Filtrar por identificador externo. Coincidencia exacta. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Filtra por procedencia: `true` para CFDIs importados del SAT, `false` para CFDIs sin importación del SAT. Omitido incluye ambas procedencias. + /// Opcional. + /// + [JsonIgnore] + public bool? SatImported + { + get => TryGetValue("sat_imported", out var value) ? (bool?)value! : default!; + set => this["sat_imported"] = value; + } + + /// + /// Filtrar por tipo de emisión. + /// Valores: "issuing", "receiving". + /// Opcional. + /// + [JsonIgnore] + public string? IssuerType + { + get => TryGetValue("issuer_type", out var value) ? (string?)value! : default!; + set => this["issuer_type"] = value; + } + + /// + /// Filtrar por uno o más estados de cancelación. + /// Opcional. + /// + [JsonIgnore] + public List? CancellationStatus + { + get => TryGetValue("cancellation_status", out var value) ? (List?)value! : default!; + set => this["cancellation_status"] = value; + } + + /// + /// Filtrar por el UUID del CFDI. Coincidencia exacta. + /// Opcional. + /// + [JsonIgnore] + public string? Uuid + { + get => TryGetValue("uuid", out var value) ? (string?)value! : default!; + set => this["uuid"] = value; + } + + /// + /// Filtrar por estado de pago. Coincidencia exacta. + /// Valores: "paid", "unpaid". + /// Opcional. + /// + [JsonIgnore] + public string? PaymentStatus + { + get => TryGetValue("payment_status", out var value) ? (string?)value! : default!; + set => this["payment_status"] = value; + } + + /// + /// Objeto con rango de fechas solicitado. El rango filtra el campo `date` de la factura. + /// Opcional. + /// + [JsonIgnore] + public DateRangeInput? Date + { + get => TryGetValue("date", out var value) ? (DateRangeInput?)value! : default!; + set => this["date"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados (con el `limit` por defecto de 100, la página máxima es 30). + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceListZipRequestsParams.cs b/Models/Inputs/InvoiceListZipRequestsParams.cs new file mode 100644 index 0000000..5f409ca --- /dev/null +++ b/Models/Inputs/InvoiceListZipRequestsParams.cs @@ -0,0 +1,107 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceListZipRequestsParams + /// + public class InvoiceListZipRequestsParams : Dictionary + { + /// + /// Año a filtrar. Debe enviarse junto con `month`. + /// Opcional. + /// + [JsonIgnore] + public int? Year + { + get => TryGetValue("year", out var value) ? (int?)value! : default!; + set => this["year"] = value; + } + + /// + /// Mes a filtrar. Debe enviarse junto con `year`. + /// Opcional. + /// + [JsonIgnore] + public int? Month + { + get => TryGetValue("month", out var value) ? (int?)value! : default!; + set => this["month"] = value; + } + + /// + /// Status de la solicitud. + /// Valores: "none", "created", "processing", "finished", "failed". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Filtra por procedencia: `true` para CFDIs importados del SAT, `false` para CFDIs sin importación del SAT. Omitido incluye ambas procedencias. + /// Opcional. + /// + [JsonIgnore] + public bool? SatImported + { + get => TryGetValue("sat_imported", out var value) ? (bool?)value! : default!; + set => this["sat_imported"] = value; + } + + /// + /// Filtra facturas emitidas o recibidas. + /// Valores: "issuing", "receiving". + /// Opcional. + /// + [JsonIgnore] + public string? IssuerType + { + get => TryGetValue("issuer_type", out var value) ? (string?)value! : default!; + set => this["issuer_type"] = value; + } + + /// + /// Filtra por un tipo de factura o por un arreglo normalizado exacto. + /// Opcional. + /// + [JsonIgnore] + public List? InvoiceTypes + { + get => TryGetValue("invoice_types", out var value) ? (List?)value! : default!; + set => this["invoice_types"] = value; + } + + /// + /// Página de resultados, empezando en 1. + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceNominaDraftInput.cs b/Models/Inputs/InvoiceNominaDraftInput.cs new file mode 100644 index 0000000..07ff576 --- /dev/null +++ b/Models/Inputs/InvoiceNominaDraftInput.cs @@ -0,0 +1,201 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Datos de la factura según su tipo y estado inicial. Omite status para timbrar; usa draft para guardar un borrador. + /// + public class InvoiceNominaDraftInput : Dictionary + { + /// + /// Crea InvoiceNominaDraftInput. + /// + public InvoiceNominaDraftInput() + { + this["type"] = "N"; + this["status"] = "draft"; + } + + /// + /// customer + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// Tipo de comprobante de esta variante de entrada. + /// Valores: "N". + /// Opcional. + /// + [JsonIgnore] + public string? Type + { + get => TryGetValue("type", out var value) ? (string?)value! : default!; + set => this["type"] = value; + } + + /// + /// Complementos a incluir en la factura. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// Documentos relacionados con la factura. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// Estado de la factura. El valor `draft` identifica un borrador que no se ha timbrado ni enviado al SAT. + /// Sólo es posible editar facturas con este estado; al editarlas, no se puede cambiar `status`. + /// Valores: "draft". + /// Requerido. + /// + [JsonIgnore] + public string Status + { + get => TryGetValue("status", out var value) ? (string)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). No puede ser anterior a 72 horas en el pasado, ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonEditInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonEditInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonEditInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonEditInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceNominaEditInput.cs b/Models/Inputs/InvoiceNominaEditInput.cs new file mode 100644 index 0000000..9ff1eaa --- /dev/null +++ b/Models/Inputs/InvoiceNominaEditInput.cs @@ -0,0 +1,201 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Nómina + /// + public class InvoiceNominaEditInput : Dictionary + { + /// + /// Crea InvoiceNominaEditInput. + /// + public InvoiceNominaEditInput() + { + this["type"] = "N"; + this["status"] = "draft"; + } + + /// + /// customer + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// Tipo de comprobante de esta variante de entrada. + /// Valores: "N". + /// Opcional. + /// + [JsonIgnore] + public string? Type + { + get => TryGetValue("type", out var value) ? (string?)value! : default!; + set => this["type"] = value; + } + + /// + /// Complementos a incluir en la factura. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// Documentos relacionados con la factura. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// Estado de la factura. El valor `draft` identifica un borrador que no se ha timbrado ni enviado al SAT. + /// Sólo es posible editar facturas con este estado; al editarlas, no se puede cambiar `status`. + /// Valores: "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). No puede ser anterior a 72 horas en el pasado, ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonEditInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonEditInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonEditInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonEditInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceNominaInput.cs b/Models/Inputs/InvoiceNominaInput.cs new file mode 100644 index 0000000..f7e8ee7 --- /dev/null +++ b/Models/Inputs/InvoiceNominaInput.cs @@ -0,0 +1,205 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Nómina + /// + public class InvoiceNominaInput : Dictionary + { + /// + /// Crea InvoiceNominaInput. + /// + /// Complementos a incluir en la factura. Requerido. + public InvoiceNominaInput(List @complements) + { + this["complements"] = @complements; + this["type"] = "N"; + } + + /// + /// type + /// Valores: "N". + /// Requerido. + /// + [JsonIgnore] + public string Type + { + get => TryGetValue("type", out var value) ? (string)value! : default!; + set => this["type"] = value; + } + + /// + /// Complementos a incluir en la factura. + /// Requerido. + /// + [JsonIgnore] + public List Complements + { + get => TryGetValue("complements", out var value) ? (List)value! : default!; + set => this["complements"] = value; + } + + /// + /// Documentos relacionados con la factura. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// customer + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// Estado inicial de la factura. Si se envía `draft`, la factura se guardará como borrador y no se timbrará ni se + /// enviará al SAT. También al enviar `draft`, todos los campos requeridos se vuelven + /// opcionales. Si se omite, el estado por default es `pending` y una vez timbrada (en la respuesta) este + /// campo se actualizará a `valid`. Para facturas asíncronas, este campo se quedará en `pending` hasta que + /// se timbre la factura. + /// Valores: "pending", "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601. Si se omite, se utiliza la fecha y hora actuales. No puede ser anterior a 72 horas en el pasado ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + } +} diff --git a/Models/Inputs/InvoicePagoDraftInput.cs b/Models/Inputs/InvoicePagoDraftInput.cs new file mode 100644 index 0000000..83aebb1 --- /dev/null +++ b/Models/Inputs/InvoicePagoDraftInput.cs @@ -0,0 +1,212 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Datos de la factura según su tipo y estado inicial. Omite status para timbrar; usa draft para guardar un borrador. + /// + public class InvoicePagoDraftInput : Dictionary + { + /// + /// Crea InvoicePagoDraftInput. + /// + public InvoicePagoDraftInput() + { + this["type"] = "P"; + this["status"] = "draft"; + } + + /// + /// Tipo de comprobante de esta variante de entrada. + /// Valores: "P". + /// Opcional. + /// + [JsonIgnore] + public string? Type + { + get => TryGetValue("type", out var value) ? (string?)value! : default!; + set => this["type"] = value; + } + + /// + /// Documentos relacionados con la factura. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// third_party + /// Opcional. + /// + [JsonIgnore] + public InvoiceItemInputThirdParty? ThirdParty + { + get => TryGetValue("third_party", out var value) ? (InvoiceItemInputThirdParty?)value! : default!; + set => this["third_party"] = value; + } + + /// + /// Complementos a incluir en la factura. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// Estado de la factura. El valor `draft` identifica un borrador que no se ha timbrado ni enviado al SAT. + /// Sólo es posible editar facturas con este estado; al editarlas, no se puede cambiar `status`. + /// Valores: "draft". + /// Requerido. + /// + [JsonIgnore] + public string Status + { + get => TryGetValue("status", out var value) ? (string)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). No puede ser anterior a 72 horas en el pasado, ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonEditInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonEditInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonEditInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonEditInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + /// + /// Cliente receptor de la factura. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + } +} diff --git a/Models/Inputs/InvoicePagoEditInput.cs b/Models/Inputs/InvoicePagoEditInput.cs new file mode 100644 index 0000000..65a5115 --- /dev/null +++ b/Models/Inputs/InvoicePagoEditInput.cs @@ -0,0 +1,212 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Pago + /// + public class InvoicePagoEditInput : Dictionary + { + /// + /// Crea InvoicePagoEditInput. + /// + public InvoicePagoEditInput() + { + this["type"] = "P"; + this["status"] = "draft"; + } + + /// + /// Tipo de comprobante de esta variante de entrada. + /// Valores: "P". + /// Opcional. + /// + [JsonIgnore] + public string? Type + { + get => TryGetValue("type", out var value) ? (string?)value! : default!; + set => this["type"] = value; + } + + /// + /// Documentos relacionados con la factura. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// third_party + /// Opcional. + /// + [JsonIgnore] + public InvoiceItemInputThirdParty? ThirdParty + { + get => TryGetValue("third_party", out var value) ? (InvoiceItemInputThirdParty?)value! : default!; + set => this["third_party"] = value; + } + + /// + /// Complementos a incluir en la factura. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// Estado de la factura. El valor `draft` identifica un borrador que no se ha timbrado ni enviado al SAT. + /// Sólo es posible editar facturas con este estado; al editarlas, no se puede cambiar `status`. + /// Valores: "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). No puede ser anterior a 72 horas en el pasado, ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonEditInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonEditInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonEditInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonEditInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + /// + /// Cliente receptor de la factura. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + } +} diff --git a/Models/Inputs/InvoicePagoInput.cs b/Models/Inputs/InvoicePagoInput.cs new file mode 100644 index 0000000..bb379f6 --- /dev/null +++ b/Models/Inputs/InvoicePagoInput.cs @@ -0,0 +1,216 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Pago + /// + public class InvoicePagoInput : Dictionary + { + /// + /// Crea InvoicePagoInput. + /// + /// Complementos a incluir en la factura. Requerido. + public InvoicePagoInput(List @complements) + { + this["complements"] = @complements; + this["type"] = "P"; + } + + /// + /// type + /// Valores: "P". + /// Requerido. + /// + [JsonIgnore] + public string Type + { + get => TryGetValue("type", out var value) ? (string)value! : default!; + set => this["type"] = value; + } + + /// + /// Documentos relacionados con la factura. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// third_party + /// Opcional. + /// + [JsonIgnore] + public InvoiceItemInputThirdParty? ThirdParty + { + get => TryGetValue("third_party", out var value) ? (InvoiceItemInputThirdParty?)value! : default!; + set => this["third_party"] = value; + } + + /// + /// Complementos a incluir en la factura. + /// Requerido. + /// + [JsonIgnore] + public List Complements + { + get => TryGetValue("complements", out var value) ? (List)value! : default!; + set => this["complements"] = value; + } + + /// + /// customer + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// Estado inicial de la factura. Si se envía `draft`, la factura se guardará como borrador y no se timbrará ni se + /// enviará al SAT. También al enviar `draft`, todos los campos requeridos se vuelven + /// opcionales. Si se omite, el estado por default es `pending` y una vez timbrada (en la respuesta) este + /// campo se actualizará a `valid`. Para facturas asíncronas, este campo se quedará en `pending` hasta que + /// se timbre la factura. + /// Valores: "pending", "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601. Si se omite, se utiliza la fecha y hora actuales. No puede ser anterior a 72 horas en el pasado ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceReceiptInput.cs b/Models/Inputs/InvoiceReceiptInput.cs new file mode 100644 index 0000000..f91defb --- /dev/null +++ b/Models/Inputs/InvoiceReceiptInput.cs @@ -0,0 +1,122 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceReceiptInput + /// + public class InvoiceReceiptInput : Dictionary + { + /// + /// Cliente receptor de la factura. Puedes enviarlo como ID de un cliente existente + /// o como objeto para crear un cliente nuevo. Si lo omites, el recibo debe tener + /// un cliente asignado previamente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos en [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en nuestras librerías. + /// Opcional. + /// + [JsonIgnore] + public string? Use + { + get => TryGetValue("use", out var value) ? (string?)value! : default!; + set => this["use"] = value; + } + + /// + /// Condiciones de pago + /// Opcional. + /// + [JsonIgnore] + public string? Conditions + { + get => TryGetValue("conditions", out var value) ? (string?)value! : default!; + set => this["conditions"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceStampDraftParams.cs b/Models/Inputs/InvoiceStampDraftParams.cs new file mode 100644 index 0000000..fd360d3 --- /dev/null +++ b/Models/Inputs/InvoiceStampDraftParams.cs @@ -0,0 +1,30 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceStampDraftParams + /// + public class InvoiceStampDraftParams : Dictionary + { + /// + /// Útil para facturas de gran tamaño. Si se envía `false` o no se envía, la llamada esperará a que el SAT responda timbrando la factura. + /// Si se envía `true`, la llamada regresará inmediatamente con el objeto `invoice` en status `pending`, y podrá consultarse su cambio de status + /// a `valid` en un momento posterior. + /// Opcional. + /// + [JsonIgnore] + public bool? Async + { + get => TryGetValue("async", out var value) ? (bool?)value! : default!; + set => this["async"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceTrasladoDraftInput.cs b/Models/Inputs/InvoiceTrasladoDraftInput.cs new file mode 100644 index 0000000..4b297c2 --- /dev/null +++ b/Models/Inputs/InvoiceTrasladoDraftInput.cs @@ -0,0 +1,253 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Datos de la factura según su tipo y estado inicial. Omite status para timbrar; usa draft para guardar un borrador. + /// + public class InvoiceTrasladoDraftInput : Dictionary + { + /// + /// Crea InvoiceTrasladoDraftInput. + /// + public InvoiceTrasladoDraftInput() + { + this["type"] = "T"; + this["status"] = "draft"; + } + + /// + /// customer + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// Tipo de comprobante de esta variante de entrada. + /// Valores: "T". + /// Opcional. + /// + [JsonIgnore] + public string? Type + { + get => TryGetValue("type", out var value) ? (string?)value! : default!; + set => this["type"] = value; + } + + /// + /// Conceptos a incluir en el comprobante de Traslado. + /// + /// El número máximo de elementos que puedes incluir en un comprobante es de 5,000. Si necesitas + /// emitir un comprobante con más de 5,000 conceptos, puedes dividir la transacción en varios comprobantes. + /// Opcional. + /// + [JsonIgnore] + public List? Items + { + get => TryGetValue("items", out var value) ? (List?)value! : default!; + set => this["items"] = value; + } + + /// + /// Complementos a incluir en el comprobante. Puedes incluir cualquier complemento en + /// el comprobante si tú mismo construyes el nodo XML del complemento y usas el tipo + /// `custom`. Es necesario agregar la información del complemento al PDF por separado + /// usando el parámetro `pdf_custom_section`. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos en + /// [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en nuestras librerías. + /// Opcional. + /// + [JsonIgnore] + public string? Use + { + get => TryGetValue("use", out var value) ? (string?)value! : default!; + set => this["use"] = value; + } + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonIgnore] + public string? Currency + { + get => TryGetValue("currency", out var value) ? (string?)value! : default!; + set => this["currency"] = value; + } + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos + /// (MXN) que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Opcional. + /// + [JsonIgnore] + public decimal? Exchange + { + get => TryGetValue("exchange", out var value) ? (decimal?)value! : default!; + set => this["exchange"] = value; + } + + /// + /// Documentos relacionados con el comprobante. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// Estado de la factura. El valor `draft` identifica un borrador que no se ha timbrado ni enviado al SAT. + /// Sólo es posible editar facturas con este estado; al editarlas, no se puede cambiar `status`. + /// Valores: "draft". + /// Requerido. + /// + [JsonIgnore] + public string Status + { + get => TryGetValue("status", out var value) ? (string)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). No puede ser anterior a 72 horas en el pasado, ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonEditInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonEditInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonEditInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonEditInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceTrasladoEditInput.cs b/Models/Inputs/InvoiceTrasladoEditInput.cs new file mode 100644 index 0000000..7d573b6 --- /dev/null +++ b/Models/Inputs/InvoiceTrasladoEditInput.cs @@ -0,0 +1,253 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Traslado + /// + public class InvoiceTrasladoEditInput : Dictionary + { + /// + /// Crea InvoiceTrasladoEditInput. + /// + public InvoiceTrasladoEditInput() + { + this["type"] = "T"; + this["status"] = "draft"; + } + + /// + /// customer + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// Tipo de comprobante de esta variante de entrada. + /// Valores: "T". + /// Opcional. + /// + [JsonIgnore] + public string? Type + { + get => TryGetValue("type", out var value) ? (string?)value! : default!; + set => this["type"] = value; + } + + /// + /// Conceptos a incluir en el comprobante de Traslado. + /// + /// El número máximo de elementos que puedes incluir en un comprobante es de 5,000. Si necesitas + /// emitir un comprobante con más de 5,000 conceptos, puedes dividir la transacción en varios comprobantes. + /// Opcional. + /// + [JsonIgnore] + public List? Items + { + get => TryGetValue("items", out var value) ? (List?)value! : default!; + set => this["items"] = value; + } + + /// + /// Complementos a incluir en el comprobante. Puedes incluir cualquier complemento en + /// el comprobante si tú mismo construyes el nodo XML del complemento y usas el tipo + /// `custom`. Es necesario agregar la información del complemento al PDF por separado + /// usando el parámetro `pdf_custom_section`. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos en + /// [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en nuestras librerías. + /// Opcional. + /// + [JsonIgnore] + public string? Use + { + get => TryGetValue("use", out var value) ? (string?)value! : default!; + set => this["use"] = value; + } + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonIgnore] + public string? Currency + { + get => TryGetValue("currency", out var value) ? (string?)value! : default!; + set => this["currency"] = value; + } + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos + /// (MXN) que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Opcional. + /// + [JsonIgnore] + public decimal? Exchange + { + get => TryGetValue("exchange", out var value) ? (decimal?)value! : default!; + set => this["exchange"] = value; + } + + /// + /// Documentos relacionados con el comprobante. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// Estado de la factura. El valor `draft` identifica un borrador que no se ha timbrado ni enviado al SAT. + /// Sólo es posible editar facturas con este estado; al editarlas, no se puede cambiar `status`. + /// Valores: "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). No puede ser anterior a 72 horas en el pasado, ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonEditInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonEditInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonEditInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonEditInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceTrasladoInput.cs b/Models/Inputs/InvoiceTrasladoInput.cs new file mode 100644 index 0000000..d035329 --- /dev/null +++ b/Models/Inputs/InvoiceTrasladoInput.cs @@ -0,0 +1,257 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Traslado + /// + public class InvoiceTrasladoInput : Dictionary + { + /// + /// Crea InvoiceTrasladoInput. + /// + /// Conceptos a incluir en el comprobante de Traslado. El número máximo de elementos que puedes incluir en un comprobante es de 5,000. Si necesitas emitir un comprobante con más de 5,000 conceptos, puedes dividir la transacción en varios comprobantes. Requerido. + public InvoiceTrasladoInput(List @items) + { + this["items"] = @items; + this["type"] = "T"; + } + + /// + /// type + /// Valores: "T". + /// Requerido. + /// + [JsonIgnore] + public string Type + { + get => TryGetValue("type", out var value) ? (string)value! : default!; + set => this["type"] = value; + } + + /// + /// Conceptos a incluir en el comprobante de Traslado. + /// + /// El número máximo de elementos que puedes incluir en un comprobante es de 5,000. Si necesitas + /// emitir un comprobante con más de 5,000 conceptos, puedes dividir la transacción en varios comprobantes. + /// Requerido. + /// + [JsonIgnore] + public List Items + { + get => TryGetValue("items", out var value) ? (List)value! : default!; + set => this["items"] = value; + } + + /// + /// Complementos a incluir en el comprobante. Puedes incluir cualquier complemento en + /// el comprobante si tú mismo construyes el nodo XML del complemento y usas el tipo + /// `custom`. Es necesario agregar la información del complemento al PDF por separado + /// usando el parámetro `pdf_custom_section`. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos en + /// [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en nuestras librerías. + /// Opcional. + /// + [JsonIgnore] + public string? Use + { + get => TryGetValue("use", out var value) ? (string?)value! : default!; + set => this["use"] = value; + } + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonIgnore] + public string? Currency + { + get => TryGetValue("currency", out var value) ? (string?)value! : default!; + set => this["currency"] = value; + } + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos + /// (MXN) que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Opcional. + /// + [JsonIgnore] + public decimal? Exchange + { + get => TryGetValue("exchange", out var value) ? (decimal?)value! : default!; + set => this["exchange"] = value; + } + + /// + /// Documentos relacionados con el comprobante. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// customer + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// Estado inicial de la factura. Si se envía `draft`, la factura se guardará como borrador y no se timbrará ni se + /// enviará al SAT. También al enviar `draft`, todos los campos requeridos se vuelven + /// opcionales. Si se omite, el estado por default es `pending` y una vez timbrada (en la respuesta) este + /// campo se actualizará a `valid`. Para facturas asíncronas, este campo se quedará en `pending` hasta que + /// se timbre la factura. + /// Valores: "pending", "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601. Si se omite, se utiliza la fecha y hora actuales. No puede ser anterior a 72 horas en el pasado ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceZipRequestCreateInput.cs b/Models/Inputs/InvoiceZipRequestCreateInput.cs new file mode 100644 index 0000000..7ba049d --- /dev/null +++ b/Models/Inputs/InvoiceZipRequestCreateInput.cs @@ -0,0 +1,84 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceZipRequestCreateInput + /// + public class InvoiceZipRequestCreateInput : Dictionary + { + /// + /// Crea InvoiceZipRequestCreateInput. + /// + /// year Requerido. + /// month Requerido. + public InvoiceZipRequestCreateInput(int @year, int @month) + { + this["year"] = @year; + this["month"] = @month; + } + + /// + /// year + /// Requerido. + /// + [JsonIgnore] + public int Year + { + get => TryGetValue("year", out var value) ? (int)value! : default!; + set => this["year"] = value; + } + + /// + /// month + /// Requerido. + /// + [JsonIgnore] + public int Month + { + get => TryGetValue("month", out var value) ? (int)value! : default!; + set => this["month"] = value; + } + + /// + /// issuer_type + /// Valores: "issuing", "receiving". + /// Opcional. + /// + [JsonIgnore] + public string? IssuerType + { + get => TryGetValue("issuer_type", out var value) ? (string?)value! : default!; + set => this["issuer_type"] = value; + } + + /// + /// Filtra por procedencia: `true` para CFDIs importados del SAT, `false` para CFDIs sin importación del SAT. Omitido incluye ambas procedencias. + /// Opcional. + /// + [JsonIgnore] + public bool? SatImported + { + get => TryGetValue("sat_imported", out var value) ? (bool?)value! : default!; + set => this["sat_imported"] = value; + } + + /// + /// Tipos de factura a incluir. Por defecto se incluyen todos. + /// Opcional. + /// + [JsonIgnore] + public List? InvoiceTypes + { + get => TryGetValue("invoice_types", out var value) ? (List?)value! : default!; + set => this["invoice_types"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceableCommonEditInput.cs b/Models/Inputs/InvoiceableCommonEditInput.cs new file mode 100644 index 0000000..c7be6ed --- /dev/null +++ b/Models/Inputs/InvoiceableCommonEditInput.cs @@ -0,0 +1,87 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceableCommonEditInput + /// + public class InvoiceableCommonEditInput : Dictionary + { + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonEditInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonEditInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceableCommonEditInputPdfOptions.cs b/Models/Inputs/InvoiceableCommonEditInputPdfOptions.cs new file mode 100644 index 0000000..fd02f75 --- /dev/null +++ b/Models/Inputs/InvoiceableCommonEditInputPdfOptions.cs @@ -0,0 +1,193 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceableCommonEditInputPdfOptions + /// + public class InvoiceableCommonEditInputPdfOptions : Dictionary + { + /// + /// Mostrar códigos de catálogos del SAT junto a sus descripciones. Ejemplo: “KGM Kilogramo”. + /// Opcional. + /// + [JsonIgnore] + public bool? Codes + { + get => TryGetValue("codes", out var value) ? (bool?)value! : default!; + set => this["codes"] = value; + } + + /// + /// Mostrar la clave de producto-servicio. + /// Opcional. + /// + [JsonIgnore] + public bool? ProductKey + { + get => TryGetValue("product_key", out var value) ? (bool?)value! : default!; + set => this["product_key"] = value; + } + + /// + /// Mostrar los códigos estandarizados de estado y de país en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? AddressCodes + { + get => TryGetValue("address_codes", out var value) ? (bool?)value! : default!; + set => this["address_codes"] = value; + } + + /// + /// Mostrar la clave de exportación en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? ExportKey + { + get => TryGetValue("export_key", out var value) ? (bool?)value! : default!; + set => this["export_key"] = value; + } + + /// + /// Redondear el precio unitario en el PDF a 2 decimales, pero conservar los 6 decimales en el XML. + /// Opcional. + /// + [JsonIgnore] + public bool? RoundUnitPrice + { + get => TryGetValue("round_unit_price", out var value) ? (bool?)value! : default!; + set => this["round_unit_price"] = value; + } + + /// + /// Mostrar el desglose de impuestos en el PDF. Si se desactiva, sólo se mostratán los impuestos en los totales, pero no en el detalle de cada concepto. + /// Opcional. + /// + [JsonIgnore] + public bool? TaxBreakdown + { + get => TryGetValue("tax_breakdown", out var value) ? (bool?)value! : default!; + set => this["tax_breakdown"] = value; + } + + /// + /// Mostrar el desglose de IEPS en el PDF. Si se desactiva, solo se mostrarán los impuestos relacionados al IVA en el subtotal. + /// Opcional. + /// + [JsonIgnore] + public bool? IepsBreakdown + { + get => TryGetValue("ieps_breakdown", out var value) ? (bool?)value! : default!; + set => this["ieps_breakdown"] = value; + } + + /// + /// Suma IEPS con subtotal sin desglosarlo en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? CombineIepsWithSubtotal + { + get => TryGetValue("combine_ieps_with_subtotal", out var value) ? (bool?)value! : default!; + set => this["combine_ieps_with_subtotal"] = value; + } + + /// + /// Renderizar el complemento de Carta Porte 3.1 en el PDF sólo si el complemento de carta porte está incluido en la factura. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderCartaPorte + { + get => TryGetValue("render_carta_porte", out var value) ? (bool?)value! : default!; + set => this["render_carta_porte"] = value; + } + + /// + /// Renderizar el complemento de Instituciones Educativas Privadas en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderIedu + { + get => TryGetValue("render_iedu", out var value) ? (bool?)value! : default!; + set => this["render_iedu"] = value; + } + + /// + /// Renderizar el complemento de hidrocarburos y petrolíferos en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderHypComplement + { + get => TryGetValue("render_hyp_complement", out var value) ? (bool?)value! : default!; + set => this["render_hyp_complement"] = value; + } + + /// + /// Renderizar el complemento de comercio exterior en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderComercioExterior + { + get => TryGetValue("render_comercio_exterior", out var value) ? (bool?)value! : default!; + set => this["render_comercio_exterior"] = value; + } + + /// + /// Mostrar el teléfono del receptor en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderPhone + { + get => TryGetValue("render_phone", out var value) ? (bool?)value! : default!; + set => this["render_phone"] = value; + } + + /// + /// Repetir la firma electrónica en cada página del PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? RepeatSignature + { + get => TryGetValue("repeat_signature", out var value) ? (bool?)value! : default!; + set => this["repeat_signature"] = value; + } + + /// + /// Mostrar el domicilio fiscal de la organización en vez del lugar de expedición de la factura. Solo se muestra una dirección. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderOrganizationAddress + { + get => TryGetValue("render_organization_address", out var value) ? (bool?)value! : default!; + set => this["render_organization_address"] = value; + } + + /// + /// payroll_options + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonEditInputPdfOptionsPayrollOptions? PayrollOptions + { + get => TryGetValue("payroll_options", out var value) ? (InvoiceableCommonEditInputPdfOptionsPayrollOptions?)value! : default!; + set => this["payroll_options"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceableCommonEditInputPdfOptionsPayrollOptions.cs b/Models/Inputs/InvoiceableCommonEditInputPdfOptionsPayrollOptions.cs new file mode 100644 index 0000000..6454f14 --- /dev/null +++ b/Models/Inputs/InvoiceableCommonEditInputPdfOptionsPayrollOptions.cs @@ -0,0 +1,61 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceableCommonEditInputPdfOptionsPayrollOptions + /// + public class InvoiceableCommonEditInputPdfOptionsPayrollOptions : Dictionary + { + /// + /// tipo_contrato + /// Opcional. + /// + [JsonIgnore] + public bool? TipoContrato + { + get => TryGetValue("tipo_contrato", out var value) ? (bool?)value! : default!; + set => this["tipo_contrato"] = value; + } + + /// + /// puesto + /// Opcional. + /// + [JsonIgnore] + public bool? Puesto + { + get => TryGetValue("puesto", out var value) ? (bool?)value! : default!; + set => this["puesto"] = value; + } + + /// + /// riesgo_puesto + /// Opcional. + /// + [JsonIgnore] + public bool? RiesgoPuesto + { + get => TryGetValue("riesgo_puesto", out var value) ? (bool?)value! : default!; + set => this["riesgo_puesto"] = value; + } + + /// + /// antiguedad + /// Opcional. + /// + [JsonIgnore] + public bool? Antiguedad + { + get => TryGetValue("antiguedad", out var value) ? (bool?)value! : default!; + set => this["antiguedad"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceableCommonInput.cs b/Models/Inputs/InvoiceableCommonInput.cs new file mode 100644 index 0000000..aded5fe --- /dev/null +++ b/Models/Inputs/InvoiceableCommonInput.cs @@ -0,0 +1,87 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceableCommonInput + /// + public class InvoiceableCommonInput : Dictionary + { + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceableCommonInputPdfOptions.cs b/Models/Inputs/InvoiceableCommonInputPdfOptions.cs new file mode 100644 index 0000000..b89d635 --- /dev/null +++ b/Models/Inputs/InvoiceableCommonInputPdfOptions.cs @@ -0,0 +1,193 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceableCommonInputPdfOptions + /// + public class InvoiceableCommonInputPdfOptions : Dictionary + { + /// + /// Mostrar códigos de catálogos del SAT junto a sus descripciones. Ejemplo: “KGM Kilogramo”. + /// Opcional. + /// + [JsonIgnore] + public bool? Codes + { + get => TryGetValue("codes", out var value) ? (bool?)value! : default!; + set => this["codes"] = value; + } + + /// + /// Mostrar la clave de producto-servicio. + /// Opcional. + /// + [JsonIgnore] + public bool? ProductKey + { + get => TryGetValue("product_key", out var value) ? (bool?)value! : default!; + set => this["product_key"] = value; + } + + /// + /// Mostrar los códigos estandarizados de estado y de país en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? AddressCodes + { + get => TryGetValue("address_codes", out var value) ? (bool?)value! : default!; + set => this["address_codes"] = value; + } + + /// + /// Mostrar la clave de exportación en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? ExportKey + { + get => TryGetValue("export_key", out var value) ? (bool?)value! : default!; + set => this["export_key"] = value; + } + + /// + /// Redondear el precio unitario en el PDF a 2 decimales, pero conservar los 6 decimales en el XML. + /// Opcional. + /// + [JsonIgnore] + public bool? RoundUnitPrice + { + get => TryGetValue("round_unit_price", out var value) ? (bool?)value! : default!; + set => this["round_unit_price"] = value; + } + + /// + /// Mostrar el desglose de impuestos en el PDF. Si se desactiva, sólo se mostrarán los impuestos en los totales, pero no en el detalle de cada concepto. + /// Opcional. + /// + [JsonIgnore] + public bool? TaxBreakdown + { + get => TryGetValue("tax_breakdown", out var value) ? (bool?)value! : default!; + set => this["tax_breakdown"] = value; + } + + /// + /// Mostrar el desglose de IEPS en el PDF. Si se desactiva, solo se mostrarán los impuestos relacionados al IVA en el subtotal. + /// Opcional. + /// + [JsonIgnore] + public bool? IepsBreakdown + { + get => TryGetValue("ieps_breakdown", out var value) ? (bool?)value! : default!; + set => this["ieps_breakdown"] = value; + } + + /// + /// Suma IEPS con subtotal sin desglosarlo en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? CombineIepsWithSubtotal + { + get => TryGetValue("combine_ieps_with_subtotal", out var value) ? (bool?)value! : default!; + set => this["combine_ieps_with_subtotal"] = value; + } + + /// + /// Renderizar el complemento de Carta Porte 3.1 en el PDF sólo si el complemento de carta porte está incluido en la factura. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderCartaPorte + { + get => TryGetValue("render_carta_porte", out var value) ? (bool?)value! : default!; + set => this["render_carta_porte"] = value; + } + + /// + /// Renderizar el complemento de Instituciones Educativas Privadas en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderIedu + { + get => TryGetValue("render_iedu", out var value) ? (bool?)value! : default!; + set => this["render_iedu"] = value; + } + + /// + /// Renderizar el complemento de hidrocarburos y petrolíferos en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderHypComplement + { + get => TryGetValue("render_hyp_complement", out var value) ? (bool?)value! : default!; + set => this["render_hyp_complement"] = value; + } + + /// + /// Renderizar el complemento de comercio exterior en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderComercioExterior + { + get => TryGetValue("render_comercio_exterior", out var value) ? (bool?)value! : default!; + set => this["render_comercio_exterior"] = value; + } + + /// + /// Mostrar el teléfono del receptor en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderPhone + { + get => TryGetValue("render_phone", out var value) ? (bool?)value! : default!; + set => this["render_phone"] = value; + } + + /// + /// Repetir la firma electrónica en cada página del PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? RepeatSignature + { + get => TryGetValue("repeat_signature", out var value) ? (bool?)value! : default!; + set => this["repeat_signature"] = value; + } + + /// + /// Mostrar el domicilio fiscal de la organización en vez del lugar de expedición de la factura. Solo se muestra una dirección. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderOrganizationAddress + { + get => TryGetValue("render_organization_address", out var value) ? (bool?)value! : default!; + set => this["render_organization_address"] = value; + } + + /// + /// payroll_options + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonInputPdfOptionsPayrollOptions? PayrollOptions + { + get => TryGetValue("payroll_options", out var value) ? (InvoiceableCommonInputPdfOptionsPayrollOptions?)value! : default!; + set => this["payroll_options"] = value; + } + + } +} diff --git a/Models/Inputs/InvoiceableCommonInputPdfOptionsPayrollOptions.cs b/Models/Inputs/InvoiceableCommonInputPdfOptionsPayrollOptions.cs new file mode 100644 index 0000000..20cc10d --- /dev/null +++ b/Models/Inputs/InvoiceableCommonInputPdfOptionsPayrollOptions.cs @@ -0,0 +1,61 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceableCommonInputPdfOptionsPayrollOptions + /// + public class InvoiceableCommonInputPdfOptionsPayrollOptions : Dictionary + { + /// + /// tipo_contrato + /// Opcional. + /// + [JsonIgnore] + public bool? TipoContrato + { + get => TryGetValue("tipo_contrato", out var value) ? (bool?)value! : default!; + set => this["tipo_contrato"] = value; + } + + /// + /// puesto + /// Opcional. + /// + [JsonIgnore] + public bool? Puesto + { + get => TryGetValue("puesto", out var value) ? (bool?)value! : default!; + set => this["puesto"] = value; + } + + /// + /// riesgo_puesto + /// Opcional. + /// + [JsonIgnore] + public bool? RiesgoPuesto + { + get => TryGetValue("riesgo_puesto", out var value) ? (bool?)value! : default!; + set => this["riesgo_puesto"] = value; + } + + /// + /// antiguedad + /// Opcional. + /// + [JsonIgnore] + public bool? Antiguedad + { + get => TryGetValue("antiguedad", out var value) ? (bool?)value! : default!; + set => this["antiguedad"] = value; + } + + } +} diff --git a/Models/Inputs/LeyendasFiscalesDataInput.cs b/Models/Inputs/LeyendasFiscalesDataInput.cs new file mode 100644 index 0000000..c747fe8 --- /dev/null +++ b/Models/Inputs/LeyendasFiscalesDataInput.cs @@ -0,0 +1,37 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Complemento de Leyendas Fiscales versión 1.0. + /// + public class LeyendasFiscalesDataInput : Dictionary + { + /// + /// Crea LeyendasFiscalesDataInput. + /// + /// Leyendas fiscales a incluir en el comprobante. Requerido. + public LeyendasFiscalesDataInput(List @leyendas) + { + this["leyendas"] = @leyendas; + } + + /// + /// Leyendas fiscales a incluir en el comprobante. + /// Requerido. + /// + [JsonIgnore] + public List Leyendas + { + get => TryGetValue("leyendas", out var value) ? (List)value! : default!; + set => this["leyendas"] = value; + } + + } +} diff --git a/Models/Inputs/LeyendasFiscalesDataInputLeyendasItem.cs b/Models/Inputs/LeyendasFiscalesDataInputLeyendasItem.cs new file mode 100644 index 0000000..f4f4c16 --- /dev/null +++ b/Models/Inputs/LeyendasFiscalesDataInputLeyendasItem.cs @@ -0,0 +1,59 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// LeyendasFiscalesDataInputLeyendasItem + /// + public class LeyendasFiscalesDataInputLeyendasItem : Dictionary + { + /// + /// Crea LeyendasFiscalesDataInputLeyendasItem. + /// + /// Texto de la leyenda fiscal. Requerido. + public LeyendasFiscalesDataInputLeyendasItem(string @textoLeyenda) + { + this["texto_leyenda"] = @textoLeyenda; + } + + /// + /// Disposición fiscal aplicable a la leyenda. + /// Opcional. + /// + [JsonIgnore] + public string? DisposicionFiscal + { + get => TryGetValue("disposicion_fiscal", out var value) ? (string?)value! : default!; + set => this["disposicion_fiscal"] = value; + } + + /// + /// Norma que regula la leyenda. + /// Opcional. + /// + [JsonIgnore] + public string? Norma + { + get => TryGetValue("norma", out var value) ? (string?)value! : default!; + set => this["norma"] = value; + } + + /// + /// Texto de la leyenda fiscal. + /// Requerido. + /// + [JsonIgnore] + public string TextoLeyenda + { + get => TryGetValue("texto_leyenda", out var value) ? (string)value! : default!; + set => this["texto_leyenda"] = value; + } + + } +} diff --git a/Models/Inputs/LeyendasFiscalesInput.cs b/Models/Inputs/LeyendasFiscalesInput.cs new file mode 100644 index 0000000..3626769 --- /dev/null +++ b/Models/Inputs/LeyendasFiscalesInput.cs @@ -0,0 +1,48 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// LeyendasFiscalesInput + /// + public class LeyendasFiscalesInput : InvoiceComplementInput + { + /// + /// Crea LeyendasFiscalesInput. + /// + public LeyendasFiscalesInput() : base("leyendas_fiscales") + { + this["type"] = "leyendas_fiscales"; + } + + /// + /// type + /// Valores: "leyendas_fiscales". + /// Requerido. + /// + [JsonIgnore] + public new string Type + { + get => TryGetValue("type", out var value) ? (string)value! : default!; + set => this["type"] = value; + } + + /// + /// data + /// Opcional. + /// + [JsonIgnore] + public new LeyendasFiscalesDataInput? Data + { + get => TryGetValue("data", out var value) ? (LeyendasFiscalesDataInput?)value! : default!; + set => this["data"] = value; + } + + } +} diff --git a/Models/Inputs/LocalTaxInput.cs b/Models/Inputs/LocalTaxInput.cs new file mode 100644 index 0000000..9d68102 --- /dev/null +++ b/Models/Inputs/LocalTaxInput.cs @@ -0,0 +1,85 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// LocalTaxInput + /// + public class LocalTaxInput : Dictionary + { + /// + /// Crea LocalTaxInput. + /// + /// Tasa del impuesto en fracción decimal. Requerido. + /// Nombre del impuesto. Texto libre. Requerido. + public LocalTaxInput(decimal @rate, string @type) + { + this["rate"] = @rate; + this["type"] = @type; + } + + /// + /// Tasa del impuesto en fracción decimal. + /// Requerido. + /// + [JsonIgnore] + public decimal Rate + { + get => TryGetValue("rate", out var value) ? (decimal)value! : default!; + set => this["rate"] = value; + } + + /// + /// Base del impuesto. Si se omite, se utiliza el subtotal completo del concepto. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public decimal? Base + { + get => TryGetValue("base", out var value) ? (decimal?)value! : default!; + set => this["base"] = value; + } + + /// + /// Nombre del impuesto. Texto libre. + /// Requerido. + /// + [JsonIgnore] + public string Type + { + get => TryGetValue("type", out var value) ? (string)value! : default!; + set => this["type"] = value; + } + + /// + /// Indica si se trata de un impuesto retenido (`true`), o un impuesto trasladado (`false`) + /// Opcional. + /// + [JsonIgnore] + public bool? Withholding + { + get => TryGetValue("withholding", out var value) ? (bool?)value! : default!; + set => this["withholding"] = value; + } + + /// + /// factor + /// Valores: "Tasa", "Cuota", "Exento". + /// Opcional. + /// + [JsonIgnore] + public string? Factor + { + get => TryGetValue("factor", out var value) ? (string?)value! : default!; + set => this["factor"] = value; + } + + } +} diff --git a/Models/Inputs/NamespaceInput.cs b/Models/Inputs/NamespaceInput.cs new file mode 100644 index 0000000..2e08aca --- /dev/null +++ b/Models/Inputs/NamespaceInput.cs @@ -0,0 +1,65 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NamespaceInput + /// + public class NamespaceInput : Dictionary + { + /// + /// Crea NamespaceInput. + /// + /// Prefijo o nombre del namespace. Requerido. + /// Format: url Dirección URL asociada al namespace. Requerido. + /// Format: url Dirección URL del esquema de validación XSD. Requerido. + public NamespaceInput(string @prefix, string @uri, string @schemaLocation) + { + this["prefix"] = @prefix; + this["uri"] = @uri; + this["schema_location"] = @schemaLocation; + } + + /// + /// Prefijo o nombre del namespace. + /// Requerido. + /// + [JsonIgnore] + public string Prefix + { + get => TryGetValue("prefix", out var value) ? (string)value! : default!; + set => this["prefix"] = value; + } + + /// + /// Format: url + /// Dirección URL asociada al namespace. + /// Requerido. + /// + [JsonIgnore] + public string Uri + { + get => TryGetValue("uri", out var value) ? (string)value! : default!; + set => this["uri"] = value; + } + + /// + /// Format: url + /// Dirección URL del esquema de validación XSD. + /// Requerido. + /// + [JsonIgnore] + public string SchemaLocation + { + get => TryGetValue("schema_location", out var value) ? (string)value! : default!; + set => this["schema_location"] = value; + } + + } +} diff --git a/Models/Inputs/NominaAccionesInput.cs b/Models/Inputs/NominaAccionesInput.cs new file mode 100644 index 0000000..492d123 --- /dev/null +++ b/Models/Inputs/NominaAccionesInput.cs @@ -0,0 +1,50 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Accion + /// + public class NominaAccionesInput : Dictionary + { + /// + /// Crea NominaAccionesInput. + /// + /// Valor de mercado de las Acciones o Títulos valor al ejercer la opción. Requerido. + /// Precio establecido al otorgarse la opción de ingresos en acciones o títulos valor. Requerido. + public NominaAccionesInput(decimal @valorMercado, decimal @precioAlOtorgarse) + { + this["valor_mercado"] = @valorMercado; + this["precio_al_otorgarse"] = @precioAlOtorgarse; + } + + /// + /// Valor de mercado de las Acciones o Títulos valor al ejercer la opción. + /// Requerido. + /// + [JsonIgnore] + public decimal ValorMercado + { + get => TryGetValue("valor_mercado", out var value) ? (decimal)value! : default!; + set => this["valor_mercado"] = value; + } + + /// + /// Precio establecido al otorgarse la opción de ingresos en acciones o títulos valor. + /// Requerido. + /// + [JsonIgnore] + public decimal PrecioAlOtorgarse + { + get => TryGetValue("precio_al_otorgarse", out var value) ? (decimal)value! : default!; + set => this["precio_al_otorgarse"] = value; + } + + } +} diff --git a/Models/Inputs/NominaCatalogSearchDeductionsParams.cs b/Models/Inputs/NominaCatalogSearchDeductionsParams.cs new file mode 100644 index 0000000..d78d20a --- /dev/null +++ b/Models/Inputs/NominaCatalogSearchDeductionsParams.cs @@ -0,0 +1,50 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaCatalogSearchDeductionsParams + /// + public class NominaCatalogSearchDeductionsParams : Dictionary + { + /// + /// Prefijo para buscar en `key` o `description`. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// page + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// limit + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/NominaCatalogSearchPerceptionsParams.cs b/Models/Inputs/NominaCatalogSearchPerceptionsParams.cs new file mode 100644 index 0000000..36d7f7c --- /dev/null +++ b/Models/Inputs/NominaCatalogSearchPerceptionsParams.cs @@ -0,0 +1,50 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaCatalogSearchPerceptionsParams + /// + public class NominaCatalogSearchPerceptionsParams : Dictionary + { + /// + /// Prefijo para buscar en `key` o `description`. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// page + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// limit + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/NominaCompensacionInput.cs b/Models/Inputs/NominaCompensacionInput.cs new file mode 100644 index 0000000..1ad160a --- /dev/null +++ b/Models/Inputs/NominaCompensacionInput.cs @@ -0,0 +1,63 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaCompensacionInput + /// + public class NominaCompensacionInput : Dictionary + { + /// + /// Crea NominaCompensacionInput. + /// + /// Monto por saldo a favor determinado por el patrón al trabajador en periodos o ejercicios anteriores. Requerido. + /// Año en que se determinó el saldo a favor del trabajador. Requerido. + /// Remanente del saldo a favor del trabajador. Requerido. + public NominaCompensacionInput(decimal @saldoAFavor, int @ano, decimal @remanenteSalFav) + { + this["saldo_a_favor"] = @saldoAFavor; + this["ano"] = @ano; + this["remanente_sal_fav"] = @remanenteSalFav; + } + + /// + /// Monto por saldo a favor determinado por el patrón al trabajador en periodos o ejercicios anteriores. + /// Requerido. + /// + [JsonIgnore] + public decimal SaldoAFavor + { + get => TryGetValue("saldo_a_favor", out var value) ? (decimal)value! : default!; + set => this["saldo_a_favor"] = value; + } + + /// + /// Año en que se determinó el saldo a favor del trabajador. + /// Requerido. + /// + [JsonIgnore] + public int Ano + { + get => TryGetValue("ano", out var value) ? (int)value! : default!; + set => this["ano"] = value; + } + + /// + /// Remanente del saldo a favor del trabajador. + /// Requerido. + /// + [JsonIgnore] + public decimal RemanenteSalFav + { + get => TryGetValue("remanente_sal_fav", out var value) ? (decimal)value! : default!; + set => this["remanente_sal_fav"] = value; + } + + } +} diff --git a/Models/Inputs/NominaComplementDataInput.cs b/Models/Inputs/NominaComplementDataInput.cs new file mode 100644 index 0000000..1162eb4 --- /dev/null +++ b/Models/Inputs/NominaComplementDataInput.cs @@ -0,0 +1,158 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Objeto con la información del complemento de nómina. + /// + public class NominaComplementDataInput : Dictionary + { + /// + /// Crea NominaComplementDataInput. + /// + /// Fecha inicial del periodo de pago. Requerido. + /// Fecha final del periodo de pago. Requerido. + /// Número de días pagados. Puede ser entero o fracción. Requerido. + /// receptor Requerido. + /// percepciones Requerido. + public NominaComplementDataInput(OneOf @fechaInicialPago, OneOf @fechaFinalPago, decimal @numDiasPagados, NominaReceptorInput @receptor, NominaPercepcionesInput @percepciones) + { + this["fecha_inicial_pago"] = @fechaInicialPago.Value; + this["fecha_final_pago"] = @fechaFinalPago.Value; + this["num_dias_pagados"] = @numDiasPagados; + this["receptor"] = @receptor; + this["percepciones"] = @percepciones; + } + + /// + /// Tipo de nómina. + /// - `“O”` (Ordinaria): Cuando corresponde a un pago que se realiza de manera habitual, como sueldos. + /// - `“E”` (Extraordinaria): Para pagos fuera de lo habitual, como liquidaciones, aguinaldos o bonos. + /// Valores: "O", "E". + /// Opcional. + /// + [JsonIgnore] + public string? TipoNomina + { + get => TryGetValue("tipo_nomina", out var value) ? (string?)value! : default!; + set => this["tipo_nomina"] = value; + } + + /// + /// Fecha de pago de la nómina al trabajador. Si se omite, se utiliza la fecha y hora actuales. + /// Opcional. + /// + [JsonIgnore] + public OneOf? FechaPago + { + get => TryGetValue("fecha_pago", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["fecha_pago"] = value?.Value; + } + + /// + /// Fecha inicial del periodo de pago. + /// Requerido. + /// + [JsonIgnore] + public OneOf FechaInicialPago + { + get => TryGetValue("fecha_inicial_pago", out var value) ? OneOf.FromValue(value) : default!; + set => this["fecha_inicial_pago"] = value.Value; + } + + /// + /// Fecha final del periodo de pago. + /// Requerido. + /// + [JsonIgnore] + public OneOf FechaFinalPago + { + get => TryGetValue("fecha_final_pago", out var value) ? OneOf.FromValue(value) : default!; + set => this["fecha_final_pago"] = value.Value; + } + + /// + /// Número de días pagados. Puede ser entero o fracción. + /// Requerido. + /// + [JsonIgnore] + public decimal NumDiasPagados + { + get => TryGetValue("num_dias_pagados", out var value) ? (decimal)value! : default!; + set => this["num_dias_pagados"] = value; + } + + /// + /// emisor + /// Opcional. + /// + [JsonIgnore] + public NominaEmisorInput? Emisor + { + get => TryGetValue("emisor", out var value) ? (NominaEmisorInput?)value! : default!; + set => this["emisor"] = value; + } + + /// + /// receptor + /// Requerido. + /// + [JsonIgnore] + public NominaReceptorInput Receptor + { + get => TryGetValue("receptor", out var value) ? (NominaReceptorInput)value! : default!; + set => this["receptor"] = value; + } + + /// + /// percepciones + /// Requerido. + /// + [JsonIgnore] + public NominaPercepcionesInput Percepciones + { + get => TryGetValue("percepciones", out var value) ? (NominaPercepcionesInput)value! : default!; + set => this["percepciones"] = value; + } + + /// + /// Arreglo de objetos donde se expresan las deducciones aplicables. + /// Opcional. + /// + [JsonIgnore] + public List? Deducciones + { + get => TryGetValue("deducciones", out var value) ? (List?)value! : default!; + set => this["deducciones"] = value; + } + + /// + /// Arreglo de objetos para expresar otros pagos aplicables. + /// Opcional. + /// + [JsonIgnore] + public List? OtrosPagos + { + get => TryGetValue("otros_pagos", out var value) ? (List?)value! : default!; + set => this["otros_pagos"] = value; + } + + /// + /// Arreglo de objetos con información de incapacidades. + /// Opcional. + /// + [JsonIgnore] + public List? Incapacidades + { + get => TryGetValue("incapacidades", out var value) ? (List?)value! : default!; + set => this["incapacidades"] = value; + } + + } +} diff --git a/Models/Inputs/NominaComplementDataInputOtrosPagosItem.cs b/Models/Inputs/NominaComplementDataInputOtrosPagosItem.cs new file mode 100644 index 0000000..047885d --- /dev/null +++ b/Models/Inputs/NominaComplementDataInputOtrosPagosItem.cs @@ -0,0 +1,100 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaComplementDataInputOtrosPagosItem + /// + public class NominaComplementDataInputOtrosPagosItem : Dictionary + { + /// + /// Crea NominaComplementDataInputOtrosPagosItem. + /// + /// Clave del catálogo [Tipo de Otro Pago](https://docs.facturapi.io/api/#tipo-de-otro-pago). Requerido. + /// Clave de otro pago de nómina propia de la contabilidad de cada patrón. Requerido. + /// Importe por concepto de otro pago. Requerido. + public NominaComplementDataInputOtrosPagosItem(string @tipoOtroPago, string @clave, decimal @importe) + { + this["tipo_otro_pago"] = @tipoOtroPago; + this["clave"] = @clave; + this["importe"] = @importe; + } + + /// + /// Clave del catálogo [Tipo de Otro Pago](https://docs.facturapi.io/api/#tipo-de-otro-pago). + /// Requerido. + /// + [JsonIgnore] + public string TipoOtroPago + { + get => TryGetValue("tipo_otro_pago", out var value) ? (string)value! : default!; + set => this["tipo_otro_pago"] = value; + } + + /// + /// Clave de otro pago de nómina propia de la contabilidad de cada patrón. + /// Requerido. + /// + [JsonIgnore] + public string Clave + { + get => TryGetValue("clave", out var value) ? (string)value! : default!; + set => this["clave"] = value; + } + + /// + /// Descripción alternativa correspondiente a la clave utilizada. + /// Opcional. + /// + [JsonIgnore] + public string? Concepto + { + get => TryGetValue("concepto", out var value) ? (string?)value! : default!; + set => this["concepto"] = value; + } + + /// + /// Importe por concepto de otro pago. + /// Requerido. + /// + [JsonIgnore] + public decimal Importe + { + get => TryGetValue("importe", out var value) ? (decimal)value! : default!; + set => this["importe"] = value; + } + + /// + /// Subsidio causado conforme a la tabla del subsidio para el empleo + /// publicada en el Anexo 8 de la Resolución Miscelánea Fiscal vigente. + /// + /// Este valor será insertado dentro del nodo `SubsidioAlEmpleo`, y es + /// requerido cuando el valor de `tipo_otro_pago` es `"002"`. + /// Opcional. + /// + [JsonIgnore] + public decimal? SubsidioCausado + { + get => TryGetValue("subsidio_causado", out var value) ? (decimal?)value! : default!; + set => this["subsidio_causado"] = value; + } + + /// + /// compensacion_saldos_a_favor + /// Opcional. + /// + [JsonIgnore] + public NominaCompensacionInput? CompensacionSaldosAFavor + { + get => TryGetValue("compensacion_saldos_a_favor", out var value) ? (NominaCompensacionInput?)value! : default!; + set => this["compensacion_saldos_a_favor"] = value; + } + + } +} diff --git a/Models/Inputs/NominaComplementDataNestedInput.cs b/Models/Inputs/NominaComplementDataNestedInput.cs new file mode 100644 index 0000000..6142710 --- /dev/null +++ b/Models/Inputs/NominaComplementDataNestedInput.cs @@ -0,0 +1,83 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaComplementDataNestedInput + /// + public class NominaComplementDataNestedInput : Dictionary + { + /// + /// emisor + /// Opcional. + /// + [JsonIgnore] + public NominaEmisorInput? Emisor + { + get => TryGetValue("emisor", out var value) ? (NominaEmisorInput?)value! : default!; + set => this["emisor"] = value; + } + + /// + /// receptor + /// Opcional. + /// + [JsonIgnore] + public NominaReceptorInput? Receptor + { + get => TryGetValue("receptor", out var value) ? (NominaReceptorInput?)value! : default!; + set => this["receptor"] = value; + } + + /// + /// percepciones + /// Opcional. + /// + [JsonIgnore] + public NominaPercepcionesInput? Percepciones + { + get => TryGetValue("percepciones", out var value) ? (NominaPercepcionesInput?)value! : default!; + set => this["percepciones"] = value; + } + + /// + /// Arreglo de objetos donde se expresan las deducciones aplicables. + /// Opcional. + /// + [JsonIgnore] + public List? Deducciones + { + get => TryGetValue("deducciones", out var value) ? (List?)value! : default!; + set => this["deducciones"] = value; + } + + /// + /// Arreglo de objetos para expresar otros pagos aplicables. + /// Opcional. + /// + [JsonIgnore] + public List? OtrosPagos + { + get => TryGetValue("otros_pagos", out var value) ? (List?)value! : default!; + set => this["otros_pagos"] = value; + } + + /// + /// Arreglo de objetos con información de incapacidades. + /// Opcional. + /// + [JsonIgnore] + public List? Incapacidades + { + get => TryGetValue("incapacidades", out var value) ? (List?)value! : default!; + set => this["incapacidades"] = value; + } + + } +} diff --git a/Models/Inputs/NominaComplementInput.cs b/Models/Inputs/NominaComplementInput.cs new file mode 100644 index 0000000..e6714d9 --- /dev/null +++ b/Models/Inputs/NominaComplementInput.cs @@ -0,0 +1,48 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaComplementInput + /// + public class NominaComplementInput : InvoiceComplementInput + { + /// + /// Crea NominaComplementInput. + /// + public NominaComplementInput() : base("nomina") + { + this["type"] = "nomina"; + } + + /// + /// type + /// Valores: "nomina". + /// Requerido. + /// + [JsonIgnore] + public new string Type + { + get => TryGetValue("type", out var value) ? (string)value! : default!; + set => this["type"] = value; + } + + /// + /// data + /// Opcional. + /// + [JsonIgnore] + public new NominaComplementDataInput? Data + { + get => TryGetValue("data", out var value) ? (NominaComplementDataInput?)value! : default!; + set => this["data"] = value; + } + + } +} diff --git a/Models/Inputs/NominaDeduccionInput.cs b/Models/Inputs/NominaDeduccionInput.cs new file mode 100644 index 0000000..011df77 --- /dev/null +++ b/Models/Inputs/NominaDeduccionInput.cs @@ -0,0 +1,74 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Deduccion + /// + public class NominaDeduccionInput : Dictionary + { + /// + /// Crea NominaDeduccionInput. + /// + /// Clave del catálogo [Tipo de deducción](https://docs.facturapi.io/api/#tipo-de-deducción). Requerido. + /// Clave de control interno que asigna el patrón a cada deducción (descuento) de nómina propia de su contabilidad. Requerido. + /// Importe del concepto de deducción. Requerido. + public NominaDeduccionInput(string @tipoDeduccion, string @clave, decimal @importe) + { + this["tipo_deduccion"] = @tipoDeduccion; + this["clave"] = @clave; + this["importe"] = @importe; + } + + /// + /// Clave del catálogo [Tipo de deducción](https://docs.facturapi.io/api/#tipo-de-deducción). + /// Requerido. + /// + [JsonIgnore] + public string TipoDeduccion + { + get => TryGetValue("tipo_deduccion", out var value) ? (string)value! : default!; + set => this["tipo_deduccion"] = value; + } + + /// + /// Concepto de la deducción. Si no se envía, se utilizará la descripción del catálogo del tipo de deducción. + /// Opcional. + /// + [JsonIgnore] + public string? Concepto + { + get => TryGetValue("concepto", out var value) ? (string?)value! : default!; + set => this["concepto"] = value; + } + + /// + /// Clave de control interno que asigna el patrón a cada deducción (descuento) de nómina propia de su contabilidad. + /// Requerido. + /// + [JsonIgnore] + public string Clave + { + get => TryGetValue("clave", out var value) ? (string)value! : default!; + set => this["clave"] = value; + } + + /// + /// Importe del concepto de deducción. + /// Requerido. + /// + [JsonIgnore] + public decimal Importe + { + get => TryGetValue("importe", out var value) ? (decimal)value! : default!; + set => this["importe"] = value; + } + + } +} diff --git a/Models/Inputs/NominaEmisorInput.cs b/Models/Inputs/NominaEmisorInput.cs new file mode 100644 index 0000000..de007e5 --- /dev/null +++ b/Models/Inputs/NominaEmisorInput.cs @@ -0,0 +1,61 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaEmisorInput + /// + public class NominaEmisorInput : Dictionary + { + /// + /// Requerido cuando el empleador es persona física. CURP del empleador. + /// Opcional. + /// + [JsonIgnore] + public string? Curp + { + get => TryGetValue("curp", out var value) ? (string?)value! : default!; + set => this["curp"] = value; + } + + /// + /// Clave de registro patronal asignada por la institución de seguridad social al patrón. + /// Opcional. + /// + [JsonIgnore] + public string? RegistroPatronal + { + get => TryGetValue("registro_patronal", out var value) ? (string?)value! : default!; + set => this["registro_patronal"] = value; + } + + /// + /// RFC de la persona que fungió como patrón. Se usa cuando el pago se realiza a través de un tercero. + /// Opcional. + /// + [JsonIgnore] + public string? RfcPatronOrigen + { + get => TryGetValue("rfc_patron_origen", out var value) ? (string?)value! : default!; + set => this["rfc_patron_origen"] = value; + } + + /// + /// Información para que las entidades adheridas al Sistema Nacional de Coordinación Fiscal realicen la identificación del origen de los recursos. + /// Opcional. + /// + [JsonIgnore] + public NominaEmisorInputEntidadSncf? EntidadSncf + { + get => TryGetValue("entidad_sncf", out var value) ? (NominaEmisorInputEntidadSncf?)value! : default!; + set => this["entidad_sncf"] = value; + } + + } +} diff --git a/Models/Inputs/NominaEmisorInputEntidadSncf.cs b/Models/Inputs/NominaEmisorInputEntidadSncf.cs new file mode 100644 index 0000000..12f289f --- /dev/null +++ b/Models/Inputs/NominaEmisorInputEntidadSncf.cs @@ -0,0 +1,53 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaEmisorInputEntidadSncf + /// + public class NominaEmisorInputEntidadSncf : Dictionary + { + /// + /// Crea NominaEmisorInputEntidadSncf. + /// + /// Clave de origen de recurso. - `“IP”`: Ingresos Propios - `“IF”`: Ingresos Federales - `“IM”`: Ingresos mixtos. Valores: "IM", "IP", "IF". Requerido. + public NominaEmisorInputEntidadSncf(string @origenRecurso) + { + this["origen_recurso"] = @origenRecurso; + } + + /// + /// Clave de origen de recurso. + /// + /// - `“IP”`: Ingresos Propios + /// - `“IF”`: Ingresos Federales + /// - `“IM”`: Ingresos mixtos. + /// Valores: "IM", "IP", "IF". + /// Requerido. + /// + [JsonIgnore] + public string OrigenRecurso + { + get => TryGetValue("origen_recurso", out var value) ? (string)value! : default!; + set => this["origen_recurso"] = value; + } + + /// + /// Importe de recursos propios. Requerido cuando el origen del recurso es por ingresos mixtos. + /// Opcional. + /// + [JsonIgnore] + public decimal? MontoRecursoPropio + { + get => TryGetValue("monto_recurso_propio", out var value) ? (decimal?)value! : default!; + set => this["monto_recurso_propio"] = value; + } + + } +} diff --git a/Models/Inputs/NominaEntidadSncfInput.cs b/Models/Inputs/NominaEntidadSncfInput.cs new file mode 100644 index 0000000..6143ec6 --- /dev/null +++ b/Models/Inputs/NominaEntidadSncfInput.cs @@ -0,0 +1,49 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaEntidadSncfInput + /// + public class NominaEntidadSncfInput : Dictionary + { + /// + /// Crea NominaEntidadSncfInput. + /// + /// origen_recurso Valores: "IM", "IP", "IF". Requerido. + public NominaEntidadSncfInput(string @origenRecurso) + { + this["origen_recurso"] = @origenRecurso; + } + + /// + /// origen_recurso + /// Valores: "IM", "IP", "IF". + /// Requerido. + /// + [JsonIgnore] + public string OrigenRecurso + { + get => TryGetValue("origen_recurso", out var value) ? (string)value! : default!; + set => this["origen_recurso"] = value; + } + + /// + /// monto_recurso_propio + /// Opcional. + /// + [JsonIgnore] + public decimal? MontoRecursoPropio + { + get => TryGetValue("monto_recurso_propio", out var value) ? (decimal?)value! : default!; + set => this["monto_recurso_propio"] = value; + } + + } +} diff --git a/Models/Inputs/NominaHorasExtraInput.cs b/Models/Inputs/NominaHorasExtraInput.cs new file mode 100644 index 0000000..3afbcf4 --- /dev/null +++ b/Models/Inputs/NominaHorasExtraInput.cs @@ -0,0 +1,76 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// HorasExtra + /// + public class NominaHorasExtraInput : Dictionary + { + /// + /// Crea NominaHorasExtraInput. + /// + /// Número de días en que el trabajador laboró horas extra adicionales a su jornada normal de trabajo. Requerido. + /// Clave del catálogo [Tipo de Horas](https://docs.facturapi.io/api/#tipo-de-Horas). Requerido. + /// Número de horas extra trabajadas en el periodo. Requerido. + /// Importe pagado por las horas extra. Requerido. + public NominaHorasExtraInput(int @dias, string @tipoHoras, int @horasExtra, decimal @importePagado) + { + this["dias"] = @dias; + this["tipo_horas"] = @tipoHoras; + this["horas_extra"] = @horasExtra; + this["importe_pagado"] = @importePagado; + } + + /// + /// Número de días en que el trabajador laboró horas extra adicionales a su jornada normal de trabajo. + /// Requerido. + /// + [JsonIgnore] + public int Dias + { + get => TryGetValue("dias", out var value) ? (int)value! : default!; + set => this["dias"] = value; + } + + /// + /// Clave del catálogo [Tipo de Horas](https://docs.facturapi.io/api/#tipo-de-Horas). + /// Requerido. + /// + [JsonIgnore] + public string TipoHoras + { + get => TryGetValue("tipo_horas", out var value) ? (string)value! : default!; + set => this["tipo_horas"] = value; + } + + /// + /// Número de horas extra trabajadas en el periodo. + /// Requerido. + /// + [JsonIgnore] + public int HorasExtra + { + get => TryGetValue("horas_extra", out var value) ? (int)value! : default!; + set => this["horas_extra"] = value; + } + + /// + /// Importe pagado por las horas extra. + /// Requerido. + /// + [JsonIgnore] + public decimal ImportePagado + { + get => TryGetValue("importe_pagado", out var value) ? (decimal)value! : default!; + set => this["importe_pagado"] = value; + } + + } +} diff --git a/Models/Inputs/NominaIncapacidadInput.cs b/Models/Inputs/NominaIncapacidadInput.cs new file mode 100644 index 0000000..afd190c --- /dev/null +++ b/Models/Inputs/NominaIncapacidadInput.cs @@ -0,0 +1,61 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Incapacidad + /// + public class NominaIncapacidadInput : Dictionary + { + /// + /// Crea NominaIncapacidadInput. + /// + /// Número de días enteros que el trabajador se incapacitó en el periodo. Requerido. + /// Clave del catálogo [Tipo de Incapacidad](https://docs.facturapi.io/api/#tipo-de-incapacidad). Requerido. + public NominaIncapacidadInput(int @diasIncapacidad, string @tipoIncapacidad) + { + this["dias_incapacidad"] = @diasIncapacidad; + this["tipo_incapacidad"] = @tipoIncapacidad; + } + + /// + /// Número de días enteros que el trabajador se incapacitó en el periodo. + /// Requerido. + /// + [JsonIgnore] + public int DiasIncapacidad + { + get => TryGetValue("dias_incapacidad", out var value) ? (int)value! : default!; + set => this["dias_incapacidad"] = value; + } + + /// + /// Clave del catálogo [Tipo de Incapacidad](https://docs.facturapi.io/api/#tipo-de-incapacidad). + /// Requerido. + /// + [JsonIgnore] + public string TipoIncapacidad + { + get => TryGetValue("tipo_incapacidad", out var value) ? (string)value! : default!; + set => this["tipo_incapacidad"] = value; + } + + /// + /// Monto del importe monetario de la incapacidad. + /// Opcional. + /// + [JsonIgnore] + public decimal? ImporteMonetario + { + get => TryGetValue("importe_monetario", out var value) ? (decimal?)value! : default!; + set => this["importe_monetario"] = value; + } + + } +} diff --git a/Models/Inputs/NominaJubilacionInput.cs b/Models/Inputs/NominaJubilacionInput.cs new file mode 100644 index 0000000..0c69322 --- /dev/null +++ b/Models/Inputs/NominaJubilacionInput.cs @@ -0,0 +1,83 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Jubilacion + /// + public class NominaJubilacionInput : Dictionary + { + /// + /// Crea NominaJubilacionInput. + /// + /// Ingresos acumulables percibidos por el trabajador. Requerido. + /// Ingresos no acumulables percibidos por el trabajador. Requerido. + public NominaJubilacionInput(decimal @ingresoAcumulable, decimal @ingresoNoAcumulable) + { + this["ingreso_acumulable"] = @ingresoAcumulable; + this["ingreso_no_acumulable"] = @ingresoNoAcumulable; + } + + /// + /// Monto total del pago entregado en una sola exhibición. + /// Opcional. + /// + [JsonIgnore] + public decimal? TotalUnaExhibicion + { + get => TryGetValue("total_una_exhibicion", out var value) ? (decimal?)value! : default!; + set => this["total_una_exhibicion"] = value; + } + + /// + /// Monto total del pago entregado en parcialidades. + /// Opcional. + /// + [JsonIgnore] + public decimal? TotalParcialidad + { + get => TryGetValue("total_parcialidad", out var value) ? (decimal?)value! : default!; + set => this["total_parcialidad"] = value; + } + + /// + /// Monto diario percibido por el trabajador cuando el pago se realiza en parcialidades. + /// Opcional. + /// + [JsonIgnore] + public decimal? MontoDiario + { + get => TryGetValue("monto_diario", out var value) ? (decimal?)value! : default!; + set => this["monto_diario"] = value; + } + + /// + /// Ingresos acumulables percibidos por el trabajador. + /// Requerido. + /// + [JsonIgnore] + public decimal IngresoAcumulable + { + get => TryGetValue("ingreso_acumulable", out var value) ? (decimal)value! : default!; + set => this["ingreso_acumulable"] = value; + } + + /// + /// Ingresos no acumulables percibidos por el trabajador. + /// Requerido. + /// + [JsonIgnore] + public decimal IngresoNoAcumulable + { + get => TryGetValue("ingreso_no_acumulable", out var value) ? (decimal)value! : default!; + set => this["ingreso_no_acumulable"] = value; + } + + } +} diff --git a/Models/Inputs/NominaOtroPagoInput.cs b/Models/Inputs/NominaOtroPagoInput.cs new file mode 100644 index 0000000..61dd4f3 --- /dev/null +++ b/Models/Inputs/NominaOtroPagoInput.cs @@ -0,0 +1,100 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OtroPago + /// + public class NominaOtroPagoInput : Dictionary + { + /// + /// Crea NominaOtroPagoInput. + /// + /// Clave del catálogo [Tipo de Otro Pago](https://docs.facturapi.io/api/#tipo-de-otro-pago). Requerido. + /// Clave de otro pago de nómina propia de la contabilidad de cada patrón. Requerido. + /// Importe por concepto de otro pago. Requerido. + public NominaOtroPagoInput(string @tipoOtroPago, string @clave, decimal @importe) + { + this["tipo_otro_pago"] = @tipoOtroPago; + this["clave"] = @clave; + this["importe"] = @importe; + } + + /// + /// Clave del catálogo [Tipo de Otro Pago](https://docs.facturapi.io/api/#tipo-de-otro-pago). + /// Requerido. + /// + [JsonIgnore] + public string TipoOtroPago + { + get => TryGetValue("tipo_otro_pago", out var value) ? (string)value! : default!; + set => this["tipo_otro_pago"] = value; + } + + /// + /// Clave de otro pago de nómina propia de la contabilidad de cada patrón. + /// Requerido. + /// + [JsonIgnore] + public string Clave + { + get => TryGetValue("clave", out var value) ? (string)value! : default!; + set => this["clave"] = value; + } + + /// + /// Descripción alternativa correspondiente a la clave utilizada. + /// Opcional. + /// + [JsonIgnore] + public string? Concepto + { + get => TryGetValue("concepto", out var value) ? (string?)value! : default!; + set => this["concepto"] = value; + } + + /// + /// Importe por concepto de otro pago. + /// Requerido. + /// + [JsonIgnore] + public decimal Importe + { + get => TryGetValue("importe", out var value) ? (decimal)value! : default!; + set => this["importe"] = value; + } + + /// + /// Subsidio causado conforme a la tabla del subsidio para el empleo + /// publicada en el Anexo 8 de la Resolución Miscelánea Fiscal vigente. + /// + /// Este valor será insertado dentro del nodo `SubsidioAlEmpleo`, y es + /// requerido cuando el valor de `tipo_otro_pago` es `"002"`. + /// Opcional. + /// + [JsonIgnore] + public decimal? SubsidioCausado + { + get => TryGetValue("subsidio_causado", out var value) ? (decimal?)value! : default!; + set => this["subsidio_causado"] = value; + } + + /// + /// compensacion_saldos_a_favor + /// Opcional. + /// + [JsonIgnore] + public NominaCompensacionInput? CompensacionSaldosAFavor + { + get => TryGetValue("compensacion_saldos_a_favor", out var value) ? (NominaCompensacionInput?)value! : default!; + set => this["compensacion_saldos_a_favor"] = value; + } + + } +} diff --git a/Models/Inputs/NominaPercepcionInput.cs b/Models/Inputs/NominaPercepcionInput.cs new file mode 100644 index 0000000..3a132aa --- /dev/null +++ b/Models/Inputs/NominaPercepcionInput.cs @@ -0,0 +1,110 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// La entrada utiliza las claves de percepción del catálogo publicado. La clave 019 requiere horas_extra. + /// + public class NominaPercepcionInput : Dictionary + { + /// + /// Crea NominaPercepcionInput. + /// + /// Clave del catálogo [Tipo de percepción](https://docs.facturapi.io/api/#tipo-de-percepcion). Valores: "019", "001", "002", "003", "004", "005", "006", "009", "010", "011", "012", "013", "014", "015", "020", "021", "022", "023", "024", "025", "026", "027", "028", "029", "030", "031", "032", "033", "034", "035", "036", "037", "038", "039", "044", "045", "046", "047", "048", "049", "050", "051", "052", "053", "054", "055", "056". Requerido. + /// Clave de control interno que asigna el patrón a cada percepción de nómina propia de su contabilidad. Requerido. + /// Importe gravado por el concepto indicado en el tipo de percepción. Requerido. + /// Importe exento por el concepto indicado en el tipo de percepción. Requerido. + public NominaPercepcionInput(string @tipoPercepcion, string @clave, decimal @importeGravado, decimal @importeExento) + { + this["tipo_percepcion"] = @tipoPercepcion; + this["clave"] = @clave; + this["importe_gravado"] = @importeGravado; + this["importe_exento"] = @importeExento; + } + + /// + /// Clave del catálogo [Tipo de percepción](https://docs.facturapi.io/api/#tipo-de-percepcion). + /// Valores: "019", "001", "002", "003", "004", "005", "006", "009", "010", "011", "012", "013", "014", "015", "020", "021", "022", "023", "024", "025", "026", "027", "028", "029", "030", "031", "032", "033", "034", "035", "036", "037", "038", "039", "044", "045", "046", "047", "048", "049", "050", "051", "052", "053", "054", "055", "056". + /// Requerido. + /// + [JsonIgnore] + public string TipoPercepcion + { + get => TryGetValue("tipo_percepcion", out var value) ? (string)value! : default!; + set => this["tipo_percepcion"] = value; + } + + /// + /// Concepto de la percepción. Si no se envía, se utilizará la descripción del catálogo del tipo de percepción. + /// Opcional. + /// + [JsonIgnore] + public string? Concepto + { + get => TryGetValue("concepto", out var value) ? (string?)value! : default!; + set => this["concepto"] = value; + } + + /// + /// Clave de control interno que asigna el patrón a cada percepción de nómina propia de su contabilidad. + /// Requerido. + /// + [JsonIgnore] + public string Clave + { + get => TryGetValue("clave", out var value) ? (string)value! : default!; + set => this["clave"] = value; + } + + /// + /// Importe gravado por el concepto indicado en el tipo de percepción. + /// Requerido. + /// + [JsonIgnore] + public decimal ImporteGravado + { + get => TryGetValue("importe_gravado", out var value) ? (decimal)value! : default!; + set => this["importe_gravado"] = value; + } + + /// + /// Importe exento por el concepto indicado en el tipo de percepción. + /// Requerido. + /// + [JsonIgnore] + public decimal ImporteExento + { + get => TryGetValue("importe_exento", out var value) ? (decimal)value! : default!; + set => this["importe_exento"] = value; + } + + /// + /// acciones_o_titulos + /// Opcional. + /// + [JsonIgnore] + public NominaAccionesInput? AccionesOTitulos + { + get => TryGetValue("acciones_o_titulos", out var value) ? (NominaAccionesInput?)value! : default!; + set => this["acciones_o_titulos"] = value; + } + + /// + /// Arreglo de objetos para expresar las horas extra aplicables. Requerido cuando el tipo de percepción es “019” (Horas extras). + /// Opcional. + /// + [JsonIgnore] + public List? HorasExtra + { + get => TryGetValue("horas_extra", out var value) ? (List?)value! : default!; + set => this["horas_extra"] = value; + } + + } +} diff --git a/Models/Inputs/NominaPercepcionNestedInput.cs b/Models/Inputs/NominaPercepcionNestedInput.cs new file mode 100644 index 0000000..719292f --- /dev/null +++ b/Models/Inputs/NominaPercepcionNestedInput.cs @@ -0,0 +1,39 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaPercepcionNestedInput + /// + public class NominaPercepcionNestedInput : Dictionary + { + /// + /// acciones_o_titulos + /// Opcional. + /// + [JsonIgnore] + public NominaAccionesInput? AccionesOTitulos + { + get => TryGetValue("acciones_o_titulos", out var value) ? (NominaAccionesInput?)value! : default!; + set => this["acciones_o_titulos"] = value; + } + + /// + /// Arreglo de objetos para expresar las horas extra aplicables. Requerido cuando el tipo de percepción es “019” (Horas extras). + /// Opcional. + /// + [JsonIgnore] + public List? HorasExtra + { + get => TryGetValue("horas_extra", out var value) ? (List?)value! : default!; + set => this["horas_extra"] = value; + } + + } +} diff --git a/Models/Inputs/NominaPercepcionesInput.cs b/Models/Inputs/NominaPercepcionesInput.cs new file mode 100644 index 0000000..fd9dcdb --- /dev/null +++ b/Models/Inputs/NominaPercepcionesInput.cs @@ -0,0 +1,59 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Objeto para indicar las percepciones aplicables. + /// + public class NominaPercepcionesInput : Dictionary + { + /// + /// Crea NominaPercepcionesInput. + /// + /// Objeto con información detallada de cada percepción. Requerido. + public NominaPercepcionesInput(List @percepcion) + { + this["percepcion"] = @percepcion; + } + + /// + /// Objeto con información detallada de cada percepción. + /// Requerido. + /// + [JsonIgnore] + public List Percepcion + { + get => TryGetValue("percepcion", out var value) ? (List)value! : default!; + set => this["percepcion"] = value; + } + + /// + /// jubilacion_pension_retiro + /// Opcional. + /// + [JsonIgnore] + public NominaJubilacionInput? JubilacionPensionRetiro + { + get => TryGetValue("jubilacion_pension_retiro", out var value) ? (NominaJubilacionInput?)value! : default!; + set => this["jubilacion_pension_retiro"] = value; + } + + /// + /// separacion_indemnizacion + /// Opcional. + /// + [JsonIgnore] + public NominaSeparacionInput? SeparacionIndemnizacion + { + get => TryGetValue("separacion_indemnizacion", out var value) ? (NominaSeparacionInput?)value! : default!; + set => this["separacion_indemnizacion"] = value; + } + + } +} diff --git a/Models/Inputs/NominaReceptorInput.cs b/Models/Inputs/NominaReceptorInput.cs new file mode 100644 index 0000000..ca3e0da --- /dev/null +++ b/Models/Inputs/NominaReceptorInput.cs @@ -0,0 +1,245 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Información del trabajador. + /// + public class NominaReceptorInput : Dictionary + { + /// + /// Crea NominaReceptorInput. + /// + /// CURP del trabajador. Requerido. + /// Clave del catálogo del SAT [Tipo de Contrato](https://docs.facturapi.io/api/#tipo-de-contrato). Requerido. + /// Clave del catálogo del SAT [Tipo de Régimen](https://docs.facturapi.io/api/#régimen-fiscal). Requerido. + /// Número interno de empleado, asignado por el empleador. Requerido. + /// Clave del catálogo del SAT [Periodicidad de Pago](https://docs.facturapi.io/api/#periodicidad-del-pago). Requerido. + /// Clave de la entidad federativa en donde el trabajador prestó sus servicios al empleador, que puedes consultar utilizando nuestra [herramienta de búsqueda](https://dashboard.facturapi.io/catalogs/state). Requerido. + public NominaReceptorInput(string @curp, string @tipoContrato, string @tipoRegimen, string @numEmpleado, string @periodicidadPago, string @claveEntFed) + { + this["curp"] = @curp; + this["tipo_contrato"] = @tipoContrato; + this["tipo_regimen"] = @tipoRegimen; + this["num_empleado"] = @numEmpleado; + this["periodicidad_pago"] = @periodicidadPago; + this["clave_ent_fed"] = @claveEntFed; + } + + /// + /// CURP del trabajador. + /// Requerido. + /// + [JsonIgnore] + public string Curp + { + get => TryGetValue("curp", out var value) ? (string)value! : default!; + set => this["curp"] = value; + } + + /// + /// Número de seguridad social. + /// Opcional. + /// + [JsonIgnore] + public string? NumSeguridadSocial + { + get => TryGetValue("num_seguridad_social", out var value) ? (string?)value! : default!; + set => this["num_seguridad_social"] = value; + } + + /// + /// Fecha de inicio de la relación laboral entre el empleador y el empleado. + /// Opcional. + /// + [JsonIgnore] + public OneOf? FechaInicioRelLaboral + { + get => TryGetValue("fecha_inicio_rel_laboral", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["fecha_inicio_rel_laboral"] = value?.Value; + } + + /// + /// Antigüedad del empleado en el formato especificado por el SAT. Si se envía un `string`, se espera que éste contenga la antigüedad en el formato que especifica el SAT. Si se envía el valor booleano `false`, este campo no se incluirá en la factura. Si se envía el valor booleano `true` y `fecha_inicio_rel_laboral` existe, este valor se calculará con la diferencia entre la fecha de inicio de relación laboral y la fecha de pago. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Antiguedad + { + get => TryGetValue("antiguedad", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["antiguedad"] = value?.Value; + } + + /// + /// Clave del catálogo del SAT [Tipo de Contrato](https://docs.facturapi.io/api/#tipo-de-contrato). + /// Requerido. + /// + [JsonIgnore] + public string TipoContrato + { + get => TryGetValue("tipo_contrato", out var value) ? (string)value! : default!; + set => this["tipo_contrato"] = value; + } + + /// + /// Indica si el trabajador está asociado a un sindicato. + /// Opcional. + /// + [JsonIgnore] + public bool? Sindicalizado + { + get => TryGetValue("sindicalizado", out var value) ? (bool?)value! : default!; + set => this["sindicalizado"] = value; + } + + /// + /// Clave del catálogo del SAT [Tipo de Jornada](https://docs.facturapi.io/api/#tipo-de-jornada). + /// Opcional. + /// + [JsonIgnore] + public string? TipoJornada + { + get => TryGetValue("tipo_jornada", out var value) ? (string?)value! : default!; + set => this["tipo_jornada"] = value; + } + + /// + /// Clave del catálogo del SAT [Tipo de Régimen](https://docs.facturapi.io/api/#régimen-fiscal). + /// Requerido. + /// + [JsonIgnore] + public string TipoRegimen + { + get => TryGetValue("tipo_regimen", out var value) ? (string)value! : default!; + set => this["tipo_regimen"] = value; + } + + /// + /// Número interno de empleado, asignado por el empleador. + /// Requerido. + /// + [JsonIgnore] + public string NumEmpleado + { + get => TryGetValue("num_empleado", out var value) ? (string)value! : default!; + set => this["num_empleado"] = value; + } + + /// + /// Nombre del departamento o área a la que pertenece el trabajador. + /// Opcional. + /// + [JsonIgnore] + public string? Departamento + { + get => TryGetValue("departamento", out var value) ? (string?)value! : default!; + set => this["departamento"] = value; + } + + /// + /// Nombre del puesto asignado al empleado o el nombre de la actividad que realiza. + /// Opcional. + /// + [JsonIgnore] + public string? Puesto + { + get => TryGetValue("puesto", out var value) ? (string?)value! : default!; + set => this["puesto"] = value; + } + + /// + /// Clave del catálogo del SAT [Riesgo del Puesto](https://docs.facturapi.io/api/#riesgo-del-puesto). + /// Opcional. + /// + [JsonIgnore] + public string? RiesgoPuesto + { + get => TryGetValue("riesgo_puesto", out var value) ? (string?)value! : default!; + set => this["riesgo_puesto"] = value; + } + + /// + /// Clave del catálogo del SAT [Periodicidad de Pago](https://docs.facturapi.io/api/#periodicidad-del-pago). + /// Requerido. + /// + [JsonIgnore] + public string PeriodicidadPago + { + get => TryGetValue("periodicidad_pago", out var value) ? (string)value! : default!; + set => this["periodicidad_pago"] = value; + } + + /// + /// Clave del banco de acuerdo al catálogo del SAT “Bancos” que puedes consultar utilizando nuestra [herramienta de búsqueda](https://dashboard.facturapi.io/catalogs/bank). + /// Opcional. + /// + [JsonIgnore] + public string? Banco + { + get => TryGetValue("banco", out var value) ? (string?)value! : default!; + set => this["banco"] = value; + } + + /// + /// Número de cuenta bancaria (11 caracteres) o número de teléfono celular (10 caracteres) o número de tarjeta (15 ó 16 caracteres) o la CLABE (18 caracteres) o número de monedero electrónico donde se realiza el depósito de nómina. + /// Opcional. + /// + [JsonIgnore] + public string? CuentaBancaria + { + get => TryGetValue("cuenta_bancaria", out var value) ? (string?)value! : default!; + set => this["cuenta_bancaria"] = value; + } + + /// + /// Importe de la retribución en efectivo por cuota diaria, gratificaciones, percepciones, alimentación, habitación, primas, comisiones, prestaciones en especie, etc. + /// Opcional. + /// + [JsonIgnore] + public decimal? SalarioBaseCotApor + { + get => TryGetValue("salario_base_cot_apor", out var value) ? (decimal?)value! : default!; + set => this["salario_base_cot_apor"] = value; + } + + /// + /// Salario que se integra con los pagos hechos en efectivo por cuota diaria, gratificaciones, percepciones, habitación, primas, comisiones, prestaciones en especie y cualquier otra cantidad o prestación que se entregue al trabajador por su trabajo. + /// Opcional. + /// + [JsonIgnore] + public decimal? SalarioDiarioIntegrado + { + get => TryGetValue("salario_diario_integrado", out var value) ? (decimal?)value! : default!; + set => this["salario_diario_integrado"] = value; + } + + /// + /// Clave de la entidad federativa en donde el trabajador prestó sus servicios al empleador, que puedes consultar utilizando nuestra [herramienta de búsqueda](https://dashboard.facturapi.io/catalogs/state). + /// Requerido. + /// + [JsonIgnore] + public string ClaveEntFed + { + get => TryGetValue("clave_ent_fed", out var value) ? (string)value! : default!; + set => this["clave_ent_fed"] = value; + } + + /// + /// Arreglo de objetos para expresar información sobre la empresa que se beneficia del trabajo del empleado, en casos donde el emisor preste servicios de subcontratación. + /// Opcional. + /// + [JsonIgnore] + public List? SubContratacion + { + get => TryGetValue("sub_contratacion", out var value) ? (List?)value! : default!; + set => this["sub_contratacion"] = value; + } + + } +} diff --git a/Models/Inputs/NominaReceptorNestedInput.cs b/Models/Inputs/NominaReceptorNestedInput.cs new file mode 100644 index 0000000..1b3e563 --- /dev/null +++ b/Models/Inputs/NominaReceptorNestedInput.cs @@ -0,0 +1,28 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaReceptorNestedInput + /// + public class NominaReceptorNestedInput : Dictionary + { + /// + /// Arreglo de objetos para expresar información sobre la empresa que se beneficia del trabajo del empleado, en casos donde el emisor preste servicios de subcontratación. + /// Opcional. + /// + [JsonIgnore] + public List? SubContratacion + { + get => TryGetValue("sub_contratacion", out var value) ? (List?)value! : default!; + set => this["sub_contratacion"] = value; + } + + } +} diff --git a/Models/Inputs/NominaSeparacionInput.cs b/Models/Inputs/NominaSeparacionInput.cs new file mode 100644 index 0000000..1f61e25 --- /dev/null +++ b/Models/Inputs/NominaSeparacionInput.cs @@ -0,0 +1,89 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Separacion + /// + public class NominaSeparacionInput : Dictionary + { + /// + /// Crea NominaSeparacionInput. + /// + /// Monto total pagado por concepto de separación o indemnización. Requerido. + /// Años de servicio que laboró el trabajador, redondeado al entero inmediato superior. Requerido. + /// Último sueldo mensual ordinario percibido por el trabajador. Requerido. + /// Monto por ingresos acumulables. Requerido. + /// Monto por ingresos no acumulables. Requerido. + public NominaSeparacionInput(decimal @totalPagado, int @numAnosServicio, decimal @ultimoSueldoMensOrd, decimal @ingresoAcumulable, decimal @ingresoNoAcumulable) + { + this["total_pagado"] = @totalPagado; + this["num_anos_servicio"] = @numAnosServicio; + this["ultimo_sueldo_mens_ord"] = @ultimoSueldoMensOrd; + this["ingreso_acumulable"] = @ingresoAcumulable; + this["ingreso_no_acumulable"] = @ingresoNoAcumulable; + } + + /// + /// Monto total pagado por concepto de separación o indemnización. + /// Requerido. + /// + [JsonIgnore] + public decimal TotalPagado + { + get => TryGetValue("total_pagado", out var value) ? (decimal)value! : default!; + set => this["total_pagado"] = value; + } + + /// + /// Años de servicio que laboró el trabajador, redondeado al entero inmediato superior. + /// Requerido. + /// + [JsonIgnore] + public int NumAnosServicio + { + get => TryGetValue("num_anos_servicio", out var value) ? (int)value! : default!; + set => this["num_anos_servicio"] = value; + } + + /// + /// Último sueldo mensual ordinario percibido por el trabajador. + /// Requerido. + /// + [JsonIgnore] + public decimal UltimoSueldoMensOrd + { + get => TryGetValue("ultimo_sueldo_mens_ord", out var value) ? (decimal)value! : default!; + set => this["ultimo_sueldo_mens_ord"] = value; + } + + /// + /// Monto por ingresos acumulables. + /// Requerido. + /// + [JsonIgnore] + public decimal IngresoAcumulable + { + get => TryGetValue("ingreso_acumulable", out var value) ? (decimal)value! : default!; + set => this["ingreso_acumulable"] = value; + } + + /// + /// Monto por ingresos no acumulables. + /// Requerido. + /// + [JsonIgnore] + public decimal IngresoNoAcumulable + { + get => TryGetValue("ingreso_no_acumulable", out var value) ? (decimal)value! : default!; + set => this["ingreso_no_acumulable"] = value; + } + + } +} diff --git a/Models/Inputs/NominaSubContratacionInput.cs b/Models/Inputs/NominaSubContratacionInput.cs new file mode 100644 index 0000000..0c16394 --- /dev/null +++ b/Models/Inputs/NominaSubContratacionInput.cs @@ -0,0 +1,50 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaSubContratacionInput + /// + public class NominaSubContratacionInput : Dictionary + { + /// + /// Crea NominaSubContratacionInput. + /// + /// RFC de la persona o empresa que subcontrata, es decir, de la persona o empresa en donde el trabajador prestó directamente sus servicios. Requerido. + /// Porcentaje de tiempo en que el trabajador prestó sus servicios a la persona o empresa que lo subcontrató. Requerido. + public NominaSubContratacionInput(string @rfcLabora, decimal @porcentajeTiempo) + { + this["rfc_labora"] = @rfcLabora; + this["porcentaje_tiempo"] = @porcentajeTiempo; + } + + /// + /// RFC de la persona o empresa que subcontrata, es decir, de la persona o empresa en donde el trabajador prestó directamente sus servicios. + /// Requerido. + /// + [JsonIgnore] + public string RfcLabora + { + get => TryGetValue("rfc_labora", out var value) ? (string)value! : default!; + set => this["rfc_labora"] = value; + } + + /// + /// Porcentaje de tiempo en que el trabajador prestó sus servicios a la persona o empresa que lo subcontrató. + /// Requerido. + /// + [JsonIgnore] + public decimal PorcentajeTiempo + { + get => TryGetValue("porcentaje_tiempo", out var value) ? (decimal)value! : default!; + set => this["porcentaje_tiempo"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationCertsInput.cs b/Models/Inputs/OrganizationCertsInput.cs new file mode 100644 index 0000000..f422f52 --- /dev/null +++ b/Models/Inputs/OrganizationCertsInput.cs @@ -0,0 +1,65 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationCertsInput + /// + public class OrganizationCertsInput : Dictionary + { + /// + /// Crea OrganizationCertsInput. + /// + /// Format: binary Contenido binario del archivo con extensión `.cer` del certificado CSD. Requerido. + /// Format: binary Contenido binario del archivo con extensión `.key` del certificado CSD. Requerido. + /// Contraseña de la llave del certificado. Requerido. + public OrganizationCertsInput(Stream @cer, Stream @key, string @password) + { + this["cer"] = @cer; + this["key"] = @key; + this["password"] = @password; + } + + /// + /// Format: binary + /// Contenido binario del archivo con extensión `.cer` del certificado CSD. + /// Requerido. + /// + [JsonIgnore] + public Stream Cer + { + get => TryGetValue("cer", out var value) ? (Stream)value! : default!; + set => this["cer"] = value; + } + + /// + /// Format: binary + /// Contenido binario del archivo con extensión `.key` del certificado CSD. + /// Requerido. + /// + [JsonIgnore] + public Stream Key + { + get => TryGetValue("key", out var value) ? (Stream)value! : default!; + set => this["key"] = value; + } + + /// + /// Contraseña de la llave del certificado. + /// Requerido. + /// + [JsonIgnore] + public string Password + { + get => TryGetValue("password", out var value) ? (string)value! : default!; + set => this["password"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationCheckDomainIsAvailableParams.cs b/Models/Inputs/OrganizationCheckDomainIsAvailableParams.cs new file mode 100644 index 0000000..6b8c730 --- /dev/null +++ b/Models/Inputs/OrganizationCheckDomainIsAvailableParams.cs @@ -0,0 +1,37 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationCheckDomainIsAvailableParams + /// + public class OrganizationCheckDomainIsAvailableParams : Dictionary + { + /// + /// Crea OrganizationCheckDomainIsAvailableParams. + /// + /// domain Requerido. + public OrganizationCheckDomainIsAvailableParams(string @domain) + { + this["domain"] = @domain; + } + + /// + /// domain + /// Requerido. + /// + [JsonIgnore] + public string Domain + { + get => TryGetValue("domain", out var value) ? (string)value! : default!; + set => this["domain"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationCreateInput.cs b/Models/Inputs/OrganizationCreateInput.cs new file mode 100644 index 0000000..4bde03a --- /dev/null +++ b/Models/Inputs/OrganizationCreateInput.cs @@ -0,0 +1,37 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationCreateInput + /// + public class OrganizationCreateInput : Dictionary + { + /// + /// Crea OrganizationCreateInput. + /// + /// Nombre comercial de la organización. Requerido. + public OrganizationCreateInput(string @name) + { + this["name"] = @name; + } + + /// + /// Nombre comercial de la organización. + /// Requerido. + /// + [JsonIgnore] + public string Name + { + get => TryGetValue("name", out var value) ? (string)value! : default!; + set => this["name"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationCustomizationInput.cs b/Models/Inputs/OrganizationCustomizationInput.cs new file mode 100644 index 0000000..b64f2e5 --- /dev/null +++ b/Models/Inputs/OrganizationCustomizationInput.cs @@ -0,0 +1,62 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationCustomizationInput + /// + public class OrganizationCustomizationInput : Dictionary + { + /// + /// Format: hex + /// Color distintivo de la marca en representación Hexadecimal RGB de 6 caracteres. + /// Opcional. + /// + [JsonIgnore] + public string? Color + { + get => TryGetValue("color", out var value) ? (string?)value! : default!; + set => this["color"] = value; + } + + /// + /// Número de folio que se asignará a la siguiente factura en ambiente Live (y que se incrementará automáticamente por cada nueva factura). + /// Opcional. + /// + [JsonIgnore] + public int? NextFolioNumber + { + get => TryGetValue("next_folio_number", out var value) ? (int?)value! : default!; + set => this["next_folio_number"] = value; + } + + /// + /// Número de folio que se asignará a la siguiente factura en ambiente Test (y que se incrementará automáticamente por cada nueva factura). + /// Opcional. + /// + [JsonIgnore] + public int? NextFolioNumberTest + { + get => TryGetValue("next_folio_number_test", out var value) ? (int?)value! : default!; + set => this["next_folio_number_test"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia de la organización. + /// Opcional. + /// + [JsonIgnore] + public OrganizationCustomizationInputPdfExtra? PdfExtra + { + get => TryGetValue("pdf_extra", out var value) ? (OrganizationCustomizationInputPdfExtra?)value! : default!; + set => this["pdf_extra"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationCustomizationInputPdfExtra.cs b/Models/Inputs/OrganizationCustomizationInputPdfExtra.cs new file mode 100644 index 0000000..a87b06b --- /dev/null +++ b/Models/Inputs/OrganizationCustomizationInputPdfExtra.cs @@ -0,0 +1,182 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationCustomizationInputPdfExtra + /// + public class OrganizationCustomizationInputPdfExtra : Dictionary + { + /// + /// Mostrar códigos de catálogos del SAT junto a sus descripciones. Ejemplo: “KGM Kilogramo”. + /// Opcional. + /// + [JsonIgnore] + public bool? Codes + { + get => TryGetValue("codes", out var value) ? (bool?)value! : default!; + set => this["codes"] = value; + } + + /// + /// Mostrar la clave de producto-servicio. + /// Opcional. + /// + [JsonIgnore] + public bool? ProductKey + { + get => TryGetValue("product_key", out var value) ? (bool?)value! : default!; + set => this["product_key"] = value; + } + + /// + /// Mostrar los códigos estandarizados de estado y de país en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? AddressCodes + { + get => TryGetValue("address_codes", out var value) ? (bool?)value! : default!; + set => this["address_codes"] = value; + } + + /// + /// Mostrar la clave de exportación en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? ExportKey + { + get => TryGetValue("export_key", out var value) ? (bool?)value! : default!; + set => this["export_key"] = value; + } + + /// + /// Redondear el precio unitario en el PDF a 2 decimales, pero conservar los 6 decimales en el XML. + /// Opcional. + /// + [JsonIgnore] + public bool? RoundUnitPrice + { + get => TryGetValue("round_unit_price", out var value) ? (bool?)value! : default!; + set => this["round_unit_price"] = value; + } + + /// + /// Mostrar el desglose de impuestos en el PDF. Si se desactiva, sólo se mostratán los impuestos en los totales, pero no en el detalle de cada concepto. + /// Opcional. + /// + [JsonIgnore] + public bool? TaxBreakdown + { + get => TryGetValue("tax_breakdown", out var value) ? (bool?)value! : default!; + set => this["tax_breakdown"] = value; + } + + /// + /// Mostrar el desglose de IEPS en el PDF. Si se desactiva, solo se mostrarán los impuestos relacionados al IVA en el subtotal. + /// Opcional. + /// + [JsonIgnore] + public bool? IepsBreakdown + { + get => TryGetValue("ieps_breakdown", out var value) ? (bool?)value! : default!; + set => this["ieps_breakdown"] = value; + } + + /// + /// Suma IEPS con subtotal sin desglosarlo en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? CombineIepsWithSubtotal + { + get => TryGetValue("combine_ieps_with_subtotal", out var value) ? (bool?)value! : default!; + set => this["combine_ieps_with_subtotal"] = value; + } + + /// + /// Renderizar el complemento de Carta Porte 3.1 en el PDF sólo si el complemento de carta porte está incluido en la factura. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderCartaPorte + { + get => TryGetValue("render_carta_porte", out var value) ? (bool?)value! : default!; + set => this["render_carta_porte"] = value; + } + + /// + /// Renderizar el complemento de Instituciones Educativas Privadas en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderIedu + { + get => TryGetValue("render_iedu", out var value) ? (bool?)value! : default!; + set => this["render_iedu"] = value; + } + + /// + /// Renderizar el complemento de hidrocarburos y petrolíferos en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderHypComplement + { + get => TryGetValue("render_hyp_complement", out var value) ? (bool?)value! : default!; + set => this["render_hyp_complement"] = value; + } + + /// + /// Renderizar el complemento de comercio exterior en el PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderComercioExterior + { + get => TryGetValue("render_comercio_exterior", out var value) ? (bool?)value! : default!; + set => this["render_comercio_exterior"] = value; + } + + /// + /// Repetir la firma electrónica en cada página del PDF. + /// Opcional. + /// + [JsonIgnore] + public bool? RepeatSignature + { + get => TryGetValue("repeat_signature", out var value) ? (bool?)value! : default!; + set => this["repeat_signature"] = value; + } + + /// + /// Mostrar el domicilio fiscal de la organización en vez del lugar de expedición de la factura. Solo se muestra una dirección. + /// Opcional. + /// + [JsonIgnore] + public bool? RenderOrganizationAddress + { + get => TryGetValue("render_organization_address", out var value) ? (bool?)value! : default!; + set => this["render_organization_address"] = value; + } + + /// + /// payroll_options + /// Opcional. + /// + [JsonIgnore] + public OrganizationCustomizationInputPdfExtraPayrollOptions? PayrollOptions + { + get => TryGetValue("payroll_options", out var value) ? (OrganizationCustomizationInputPdfExtraPayrollOptions?)value! : default!; + set => this["payroll_options"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationCustomizationInputPdfExtraPayrollOptions.cs b/Models/Inputs/OrganizationCustomizationInputPdfExtraPayrollOptions.cs new file mode 100644 index 0000000..1f2b564 --- /dev/null +++ b/Models/Inputs/OrganizationCustomizationInputPdfExtraPayrollOptions.cs @@ -0,0 +1,61 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationCustomizationInputPdfExtraPayrollOptions + /// + public class OrganizationCustomizationInputPdfExtraPayrollOptions : Dictionary + { + /// + /// tipo_contrato + /// Opcional. + /// + [JsonIgnore] + public bool? TipoContrato + { + get => TryGetValue("tipo_contrato", out var value) ? (bool?)value! : default!; + set => this["tipo_contrato"] = value; + } + + /// + /// puesto + /// Opcional. + /// + [JsonIgnore] + public bool? Puesto + { + get => TryGetValue("puesto", out var value) ? (bool?)value! : default!; + set => this["puesto"] = value; + } + + /// + /// riesgo_puesto + /// Opcional. + /// + [JsonIgnore] + public bool? RiesgoPuesto + { + get => TryGetValue("riesgo_puesto", out var value) ? (bool?)value! : default!; + set => this["riesgo_puesto"] = value; + } + + /// + /// antiguedad + /// Opcional. + /// + [JsonIgnore] + public bool? Antiguedad + { + get => TryGetValue("antiguedad", out var value) ? (bool?)value! : default!; + set => this["antiguedad"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationDomainInput.cs b/Models/Inputs/OrganizationDomainInput.cs new file mode 100644 index 0000000..82009af --- /dev/null +++ b/Models/Inputs/OrganizationDomainInput.cs @@ -0,0 +1,37 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationDomainInput + /// + public class OrganizationDomainInput : Dictionary + { + /// + /// Crea OrganizationDomainInput. + /// + /// domain Requerido. + public OrganizationDomainInput(string @domain) + { + this["domain"] = @domain; + } + + /// + /// domain + /// Requerido. + /// + [JsonIgnore] + public string Domain + { + get => TryGetValue("domain", out var value) ? (string)value! : default!; + set => this["domain"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationFielInput.cs b/Models/Inputs/OrganizationFielInput.cs new file mode 100644 index 0000000..4c47dc2 --- /dev/null +++ b/Models/Inputs/OrganizationFielInput.cs @@ -0,0 +1,65 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationFielInput + /// + public class OrganizationFielInput : Dictionary + { + /// + /// Crea OrganizationFielInput. + /// + /// Format: binary Contenido binario del archivo con extensión `.cer` de la e.firma (FIEL). Requerido. + /// Format: binary Contenido binario del archivo con extensión `.key` de la e.firma (FIEL). Requerido. + /// Contraseña de la llave privada de la e.firma (FIEL). Requerido. + public OrganizationFielInput(Stream @cer, Stream @key, string @password) + { + this["cer"] = @cer; + this["key"] = @key; + this["password"] = @password; + } + + /// + /// Format: binary + /// Contenido binario del archivo con extensión `.cer` de la e.firma (FIEL). + /// Requerido. + /// + [JsonIgnore] + public Stream Cer + { + get => TryGetValue("cer", out var value) ? (Stream)value! : default!; + set => this["cer"] = value; + } + + /// + /// Format: binary + /// Contenido binario del archivo con extensión `.key` de la e.firma (FIEL). + /// Requerido. + /// + [JsonIgnore] + public Stream Key + { + get => TryGetValue("key", out var value) ? (Stream)value! : default!; + set => this["key"] = value; + } + + /// + /// Contraseña de la llave privada de la e.firma (FIEL). + /// Requerido. + /// + [JsonIgnore] + public string Password + { + get => TryGetValue("password", out var value) ? (string)value! : default!; + set => this["password"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationInviteCreateInput.cs b/Models/Inputs/OrganizationInviteCreateInput.cs new file mode 100644 index 0000000..498eeba --- /dev/null +++ b/Models/Inputs/OrganizationInviteCreateInput.cs @@ -0,0 +1,49 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationInviteCreateInput + /// + public class OrganizationInviteCreateInput : Dictionary + { + /// + /// Crea OrganizationInviteCreateInput. + /// + /// Format: email Correo electrónico del usuario que será invitado. Requerido. + public OrganizationInviteCreateInput(string @email) + { + this["email"] = @email; + } + + /// + /// Format: email + /// Correo electrónico del usuario que será invitado. + /// Requerido. + /// + [JsonIgnore] + public string Email + { + get => TryGetValue("email", out var value) ? (string)value! : default!; + set => this["email"] = value; + } + + /// + /// ID de rol personalizado de la organización. + /// Opcional. + /// + [JsonIgnore] + public string? Role + { + get => TryGetValue("role", out var value) ? (string?)value! : default!; + set => this["role"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationInviteRespondInput.cs b/Models/Inputs/OrganizationInviteRespondInput.cs new file mode 100644 index 0000000..3016077 --- /dev/null +++ b/Models/Inputs/OrganizationInviteRespondInput.cs @@ -0,0 +1,37 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationInviteRespondInput + /// + public class OrganizationInviteRespondInput : Dictionary + { + /// + /// Crea OrganizationInviteRespondInput. + /// + /// Indica si la invitación debe aceptarse (`true`) o rechazarse (`false`). Requerido. + public OrganizationInviteRespondInput(bool @accept) + { + this["accept"] = @accept; + } + + /// + /// Indica si la invitación debe aceptarse (`true`) o rechazarse (`false`). + /// Requerido. + /// + [JsonIgnore] + public bool Accept + { + get => TryGetValue("accept", out var value) ? (bool)value! : default!; + set => this["accept"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationLegalInput.cs b/Models/Inputs/OrganizationLegalInput.cs new file mode 100644 index 0000000..d9e8930 --- /dev/null +++ b/Models/Inputs/OrganizationLegalInput.cs @@ -0,0 +1,109 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationLegalInput + /// + public class OrganizationLegalInput : Dictionary + { + /// + /// Crea OrganizationLegalInput. + /// + /// Nombre comercial de la organización. Requerido. + /// Nombre Fiscal o Razón Social de la organización, *sin* el régimen societario (ej.: S.A. de C.V.). Requerido. + /// Código del Régimen Fiscal, del [catálogo del SAT](https://docs.facturapi.io/api/#régimen-fiscal). Requerido. + /// address Requerido. + public OrganizationLegalInput(string @name, string @legalName, string @taxSystem, OrganizationLegalInputAddress @address) + { + this["name"] = @name; + this["legal_name"] = @legalName; + this["tax_system"] = @taxSystem; + this["address"] = @address; + } + + /// + /// Nombre comercial de la organización. + /// Requerido. + /// + [JsonIgnore] + public string Name + { + get => TryGetValue("name", out var value) ? (string)value! : default!; + set => this["name"] = value; + } + + /// + /// Nombre Fiscal o Razón Social de la organización, *sin* el régimen societario (ej.: S.A. de C.V.). + /// Requerido. + /// + [JsonIgnore] + public string LegalName + { + get => TryGetValue("legal_name", out var value) ? (string)value! : default!; + set => this["legal_name"] = value; + } + + /// + /// Código del Régimen Fiscal, del [catálogo del SAT](https://docs.facturapi.io/api/#régimen-fiscal). + /// Requerido. + /// + [JsonIgnore] + public string TaxSystem + { + get => TryGetValue("tax_system", out var value) ? (string)value! : default!; + set => this["tax_system"] = value; + } + + /// + /// Sitio web de la organización, que aparecerá en el PDF y correos de facturas y recibos. + /// Opcional. + /// + [JsonIgnore] + public string? Website + { + get => TryGetValue("website", out var value) ? (string?)value! : default!; + set => this["website"] = value; + } + + /// + /// Dirección de correo electrónico para aclaraciones. Aparecerá en el PDF y correos de facturas y recibos. + /// Opcional. + /// + [JsonIgnore] + public string? SupportEmail + { + get => TryGetValue("support_email", out var value) ? (string?)value! : default!; + set => this["support_email"] = value; + } + + /// + /// Teléfono de la organización, que aparecerá en el PDF y correos de facturas y recibos. + /// Opcional. + /// + [JsonIgnore] + public string? Phone + { + get => TryGetValue("phone", out var value) ? (string?)value! : default!; + set => this["phone"] = value; + } + + /// + /// address + /// Requerido. + /// + [JsonIgnore] + public OrganizationLegalInputAddress Address + { + get => TryGetValue("address", out var value) ? (OrganizationLegalInputAddress)value! : default!; + set => this["address"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationLegalInputAddress.cs b/Models/Inputs/OrganizationLegalInputAddress.cs new file mode 100644 index 0000000..e9f7b68 --- /dev/null +++ b/Models/Inputs/OrganizationLegalInputAddress.cs @@ -0,0 +1,116 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationLegalInputAddress + /// + public class OrganizationLegalInputAddress : Dictionary + { + /// + /// Nombre de la calle + /// Opcional. + /// + [JsonIgnore] + public string? Street + { + get => TryGetValue("street", out var value) ? (string?)value! : default!; + set => this["street"] = value; + } + + /// + /// Número exterior. + /// Opcional. + /// + [JsonIgnore] + public string? Exterior + { + get => TryGetValue("exterior", out var value) ? (string?)value! : default!; + set => this["exterior"] = value; + } + + /// + /// Número interior. + /// Opcional. + /// + [JsonIgnore] + public string? Interior + { + get => TryGetValue("interior", out var value) ? (string?)value! : default!; + set => this["interior"] = value; + } + + /// + /// Colonia + /// Opcional. + /// + [JsonIgnore] + public string? Neighborhood + { + get => TryGetValue("neighborhood", out var value) ? (string?)value! : default!; + set => this["neighborhood"] = value; + } + + /// + /// Ciudad + /// Opcional. + /// + [JsonIgnore] + public string? City + { + get => TryGetValue("city", out var value) ? (string?)value! : default!; + set => this["city"] = value; + } + + /// + /// Municipio o delegación + /// Opcional. + /// + [JsonIgnore] + public string? Municipality + { + get => TryGetValue("municipality", out var value) ? (string?)value! : default!; + set => this["municipality"] = value; + } + + /// + /// Código postal + /// Opcional. + /// + [JsonIgnore] + public string? Zip + { + get => TryGetValue("zip", out var value) ? (string?)value! : default!; + set => this["zip"] = value; + } + + /// + /// country + /// Opcional. + /// + [JsonIgnore] + public string? Country + { + get => TryGetValue("country", out var value) ? (string?)value! : default!; + set => this["country"] = value; + } + + /// + /// Nombre del Estado o Entidad Federativa. + /// Opcional. + /// + [JsonIgnore] + public string? State + { + get => TryGetValue("state", out var value) ? (string?)value! : default!; + set => this["state"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationListParams.cs b/Models/Inputs/OrganizationListParams.cs new file mode 100644 index 0000000..53344e9 --- /dev/null +++ b/Models/Inputs/OrganizationListParams.cs @@ -0,0 +1,95 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationListParams + /// + public class OrganizationListParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Consulta. Texto a buscar en `name` (nombre comercial), `legal_name` (nombre fiscal) o en `tax_id` (RFC). + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// Objeto con rango de fechas solicitado. + /// Opcional. + /// + [JsonIgnore] + public DateRangeInput? Date + { + get => TryGetValue("date", out var value) ? (DateRangeInput?)value! : default!; + set => this["date"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados (con el `limit` por defecto de 100, la página máxima es 30). + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationLogoInput.cs b/Models/Inputs/OrganizationLogoInput.cs new file mode 100644 index 0000000..5717d8b --- /dev/null +++ b/Models/Inputs/OrganizationLogoInput.cs @@ -0,0 +1,42 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationLogoInput + /// + public class OrganizationLogoInput : Dictionary + { + /// + /// Crea OrganizationLogoInput. + /// + /// Format: binary Contenido binario del archivo con la imagen que se usará como logotipo. Formatos soportados: - jpg - png - svg Requerido. + public OrganizationLogoInput(Stream @file) + { + this["file"] = @file; + } + + /// + /// Format: binary + /// Contenido binario del archivo con la imagen que se usará como + /// logotipo. Formatos soportados: + /// - jpg + /// - png + /// - svg + /// Requerido. + /// + [JsonIgnore] + public Stream File + { + get => TryGetValue("file", out var value) ? (Stream)value! : default!; + set => this["file"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationPermissionRoleCreateInput.cs b/Models/Inputs/OrganizationPermissionRoleCreateInput.cs new file mode 100644 index 0000000..adda298 --- /dev/null +++ b/Models/Inputs/OrganizationPermissionRoleCreateInput.cs @@ -0,0 +1,72 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationPermissionRoleCreateInput + /// + public class OrganizationPermissionRoleCreateInput : Dictionary + { + /// + /// Crea OrganizationPermissionRoleCreateInput. + /// + /// Nombre del rol. Requerido. + public OrganizationPermissionRoleCreateInput(string @name) + { + this["name"] = @name; + } + + /// + /// Nombre del rol. + /// Requerido. + /// + [JsonIgnore] + public string Name + { + get => TryGetValue("name", out var value) ? (string)value! : default!; + set => this["name"] = value; + } + + /// + /// Código de plantilla base para inicializar el rol, si aplica. + /// Valores: "org-admin", "org-readonly", "org-billing", "org-developer", "org-team-manager". + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? TemplateCode + { + get => TryGetValue("template_code", out var value) ? (string?)value! : default!; + set => this["template_code"] = value; + } + + /// + /// Operaciones adicionales que se agregarán al rol. + /// Opcional. + /// + [JsonIgnore] + public new List? Add + { + get => TryGetValue("add", out var value) ? (List?)value! : default!; + set => this["add"] = value; + } + + /// + /// Operaciones que se removerán del rol. + /// Opcional. + /// + [JsonIgnore] + public new List? Remove + { + get => TryGetValue("remove", out var value) ? (List?)value! : default!; + set => this["remove"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationPermissionRoleUpdateInput.cs b/Models/Inputs/OrganizationPermissionRoleUpdateInput.cs new file mode 100644 index 0000000..2552563 --- /dev/null +++ b/Models/Inputs/OrganizationPermissionRoleUpdateInput.cs @@ -0,0 +1,63 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationPermissionRoleUpdateInput + /// + public class OrganizationPermissionRoleUpdateInput : Dictionary + { + /// + /// Nuevo nombre del rol. + /// Opcional. + /// + [JsonIgnore] + public string? Name + { + get => TryGetValue("name", out var value) ? (string?)value! : default!; + set => this["name"] = value; + } + + /// + /// Nuevo código de plantilla base del rol, si aplica. + /// Valores: "org-admin", "org-readonly", "org-billing", "org-developer", "org-team-manager". + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? TemplateCode + { + get => TryGetValue("template_code", out var value) ? (string?)value! : default!; + set => this["template_code"] = value; + } + + /// + /// Lista completa de operaciones extra que debe conservar el rol. + /// Opcional. + /// + [JsonIgnore] + public new List? Add + { + get => TryGetValue("add", out var value) ? (List?)value! : default!; + set => this["add"] = value; + } + + /// + /// Lista completa de operaciones removidas que debe conservar el rol. + /// Opcional. + /// + [JsonIgnore] + public new List? Remove + { + get => TryGetValue("remove", out var value) ? (List?)value! : default!; + set => this["remove"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationReceiptsInput.cs b/Models/Inputs/OrganizationReceiptsInput.cs new file mode 100644 index 0000000..34ea52c --- /dev/null +++ b/Models/Inputs/OrganizationReceiptsInput.cs @@ -0,0 +1,93 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationReceiptsInput + /// + public class OrganizationReceiptsInput : Dictionary + { + /// + /// Periodicidad con la que la empresa decide realizar una factura global + /// (al público en general) por todos los recibos no facturados. Este + /// valor se utiliza como default al crear una factura global. + /// Valores: "day", "week", "fortnight", "month", "two_months". + /// Opcional. + /// + [JsonIgnore] + public string? Periodicity + { + get => TryGetValue("periodicity", out var value) ? (string?)value! : default!; + set => this["periodicity"] = value; + } + + /// + /// Días máximos para facturar por medio del portal de autofactura + /// después de emitido el recibo y antes del último día del periodo + /// definido por el atributo `periodicity`. El valor `0` desactiva esta + /// opción, haciendo que los recibos expiren siempre el último día del + /// periodo. + /// Opcional. + /// + [JsonIgnore] + public int? DurationDays + { + get => TryGetValue("duration_days", out var value) ? (int?)value! : default!; + set => this["duration_days"] = value; + } + + /// + /// Número de folio que se asignará al siguiente recibo creado en esta organización en ambiente Live. + /// Opcional. + /// + [JsonIgnore] + public int? NextFolioNumber + { + get => TryGetValue("next_folio_number", out var value) ? (int?)value! : default!; + set => this["next_folio_number"] = value; + } + + /// + /// Número de folio que se asignará al siguiente recibo creado en esta organización en ambiente Test. + /// Opcional. + /// + [JsonIgnore] + public int? NextFolioNumberTest + { + get => TryGetValue("next_folio_number_test", out var value) ? (int?)value! : default!; + set => this["next_folio_number_test"] = value; + } + + /// + /// Activa o desactiva la generación automática de una factura global después + /// de cerrar cada periodo configurado. Para activarla, la organización debe + /// tener contratado el feature de factura global. + /// Opcional. + /// + [JsonIgnore] + public bool? ActivateGlobalInvoice + { + get => TryGetValue("activate_global_invoice", out var value) ? (bool?)value! : default!; + set => this["activate_global_invoice"] = value; + } + + /// + /// Cuando es `true`, agrupa conceptos equivalentes al facturar varios recibos + /// seleccionados, incluyendo las autofacturas. No aplica a las facturas globales. + /// Opcional. + /// + [JsonIgnore] + public bool? GroupedItemsInvoice + { + get => TryGetValue("grouped_items_invoice", out var value) ? (bool?)value! : default!; + set => this["grouped_items_invoice"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationSelfInvoiceInput.cs b/Models/Inputs/OrganizationSelfInvoiceInput.cs new file mode 100644 index 0000000..f406f5a --- /dev/null +++ b/Models/Inputs/OrganizationSelfInvoiceInput.cs @@ -0,0 +1,52 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationSelfInvoiceInput + /// + public class OrganizationSelfInvoiceInput : Dictionary + { + /// + /// Lista de usos CFDI permitidos para la autofactura. Si este campo está vacío, se permitirán todos los usos CFDI. + /// Opcional. + /// + [JsonIgnore] + public List? AllowedCfdiUses + { + get => TryGetValue("allowed_cfdi_uses", out var value) ? (List?)value! : default!; + set => this["allowed_cfdi_uses"] = value; + } + + /// + /// Indica si la organización aplica el ISR bajo el régimen RESICO. Si es verdadero, el ISR se calculará de acuerdo con el régimen RESICO. + /// Si es falso, el ISR se calculará de acuerdo con el régimen general. + /// Opcional. + /// + [JsonIgnore] + public bool? ApplyResicoIsr + { + get => TryGetValue("apply_resico_isr", out var value) ? (bool?)value! : default!; + set => this["apply_resico_isr"] = value; + } + + /// + /// Dirección de correo electrónico para aclaraciones. Aparecerá en el portal de autofacturación. + /// Al modificarlo se enviará un correo de verificación a la nueva dirección. + /// Opcional. + /// + [JsonIgnore] + public string? SupportEmail + { + get => TryGetValue("support_email", out var value) ? (string?)value! : default!; + set => this["support_email"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationSeriesCreateInput.cs b/Models/Inputs/OrganizationSeriesCreateInput.cs new file mode 100644 index 0000000..400828f --- /dev/null +++ b/Models/Inputs/OrganizationSeriesCreateInput.cs @@ -0,0 +1,59 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationSeriesCreateInput + /// + public class OrganizationSeriesCreateInput : Dictionary + { + /// + /// Crea OrganizationSeriesCreateInput. + /// + /// Nombre de la serie. Requerido. + public OrganizationSeriesCreateInput(string @series) + { + this["series"] = @series; + } + + /// + /// Nombre de la serie. + /// Requerido. + /// + [JsonIgnore] + public string Series + { + get => TryGetValue("series", out var value) ? (string)value! : default!; + set => this["series"] = value; + } + + /// + /// Número de folio que se asignará a la siguiente factura en ambiente Live (y que se incrementará automáticamente por cada nueva factura). + /// Opcional. + /// + [JsonIgnore] + public int? NextFolio + { + get => TryGetValue("next_folio", out var value) ? (int?)value! : default!; + set => this["next_folio"] = value; + } + + /// + /// Número de folio que se asignará a la siguiente factura en ambiente Test (y que se incrementará automáticamente por cada nueva factura). + /// Opcional. + /// + [JsonIgnore] + public int? NextFolioTest + { + get => TryGetValue("next_folio_test", out var value) ? (int?)value! : default!; + set => this["next_folio_test"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationSeriesDefaultInput.cs b/Models/Inputs/OrganizationSeriesDefaultInput.cs new file mode 100644 index 0000000..b695a60 --- /dev/null +++ b/Models/Inputs/OrganizationSeriesDefaultInput.cs @@ -0,0 +1,52 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationSeriesDefaultInput + /// + public class OrganizationSeriesDefaultInput : Dictionary + { + /// + /// Crea OrganizationSeriesDefaultInput. + /// + /// Tipo de comprobante. Valores posibles: `I` (Ingreso), `E` (Egreso), `P` (Pago), `N` (Nómina), `T` (Traslado). Valores: "E", "I", "T", "N", "P". Requerido. + /// Nombre de la serie. Requerido. + public OrganizationSeriesDefaultInput(string @type, string @series) + { + this["type"] = @type; + this["series"] = @series; + } + + /// + /// Tipo de comprobante. Valores posibles: + /// `I` (Ingreso), `E` (Egreso), `P` (Pago), `N` (Nómina), `T` (Traslado). + /// Valores: "E", "I", "T", "N", "P". + /// Requerido. + /// + [JsonIgnore] + public string Type + { + get => TryGetValue("type", out var value) ? (string)value! : default!; + set => this["type"] = value; + } + + /// + /// Nombre de la serie. + /// Requerido. + /// + [JsonIgnore] + public string Series + { + get => TryGetValue("series", out var value) ? (string)value! : default!; + set => this["series"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationSeriesUpdateInput.cs b/Models/Inputs/OrganizationSeriesUpdateInput.cs new file mode 100644 index 0000000..d36a8a3 --- /dev/null +++ b/Models/Inputs/OrganizationSeriesUpdateInput.cs @@ -0,0 +1,39 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationSeriesUpdateInput + /// + public class OrganizationSeriesUpdateInput : Dictionary + { + /// + /// Número de folio que se asignará a la siguiente factura en ambiente Live (y que se incrementará automáticamente por cada nueva factura). + /// Opcional. + /// + [JsonIgnore] + public int? NextFolio + { + get => TryGetValue("next_folio", out var value) ? (int?)value! : default!; + set => this["next_folio"] = value; + } + + /// + /// Número de folio que se asignará a la siguiente factura en ambiente Test (y que se incrementará automáticamente por cada nueva factura). + /// Opcional. + /// + [JsonIgnore] + public int? NextFolioTest + { + get => TryGetValue("next_folio_test", out var value) ? (int?)value! : default!; + set => this["next_folio_test"] = value; + } + + } +} diff --git a/Models/Inputs/OrganizationUserAccessRoleUpdateInput.cs b/Models/Inputs/OrganizationUserAccessRoleUpdateInput.cs new file mode 100644 index 0000000..3480a21 --- /dev/null +++ b/Models/Inputs/OrganizationUserAccessRoleUpdateInput.cs @@ -0,0 +1,37 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationUserAccessRoleUpdateInput + /// + public class OrganizationUserAccessRoleUpdateInput : Dictionary + { + /// + /// Crea OrganizationUserAccessRoleUpdateInput. + /// + /// ID del rol que se asignará al usuario. Requerido. + public OrganizationUserAccessRoleUpdateInput(string @role) + { + this["role"] = @role; + } + + /// + /// ID del rol que se asignará al usuario. + /// Requerido. + /// + [JsonIgnore] + public string Role + { + get => TryGetValue("role", out var value) ? (string)value! : default!; + set => this["role"] = value; + } + + } +} diff --git a/Models/Inputs/PagoComplementInput.cs b/Models/Inputs/PagoComplementInput.cs new file mode 100644 index 0000000..8709c46 --- /dev/null +++ b/Models/Inputs/PagoComplementInput.cs @@ -0,0 +1,48 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// PagoComplementInput + /// + public class PagoComplementInput : InvoiceComplementInput + { + /// + /// Crea PagoComplementInput. + /// + public PagoComplementInput() : base("pago") + { + this["type"] = "pago"; + } + + /// + /// type + /// Valores: "pago". + /// Requerido. + /// + [JsonIgnore] + public new string Type + { + get => TryGetValue("type", out var value) ? (string)value! : default!; + set => this["type"] = value; + } + + /// + /// data + /// Opcional. + /// + [JsonIgnore] + public new OneOf>? Data + { + get => TryGetValue("data", out var value) && value != null ? OneOf>.FromValue(value) : default(OneOf>?); + set => this["data"] = value?.Value; + } + + } +} diff --git a/Models/Inputs/PartInput.cs b/Models/Inputs/PartInput.cs new file mode 100644 index 0000000..d32a201 --- /dev/null +++ b/Models/Inputs/PartInput.cs @@ -0,0 +1,105 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// PartInput + /// + public class PartInput : Dictionary + { + /// + /// Crea PartInput. + /// + /// Descripción del producto o servicio. Requerido. + /// Clave de producto/servicio, del catálogo del SAT. Nosotros te proporcionamos una manera más conveniente de encontrarlo utilizando nuestra herramienta de búsqueda de claves. Requerido. + public PartInput(string @description, string @productKey) + { + this["description"] = @description; + this["product_key"] = @productKey; + } + + /// + /// Descripción del producto o servicio. + /// Requerido. + /// + [JsonIgnore] + public string Description + { + get => TryGetValue("description", out var value) ? (string)value! : default!; + set => this["description"] = value; + } + + /// + /// Clave de producto/servicio, del catálogo del SAT. Nosotros te proporcionamos una manera más conveniente de encontrarlo utilizando nuestra herramienta de búsqueda de claves. + /// Requerido. + /// + [JsonIgnore] + public string ProductKey + { + get => TryGetValue("product_key", out var value) ? (string)value! : default!; + set => this["product_key"] = value; + } + + /// + /// Cantidad + /// Opcional. + /// + [JsonIgnore] + public decimal? Quantity + { + get => TryGetValue("quantity", out var value) ? (decimal?)value! : default!; + set => this["quantity"] = value; + } + + /// + /// Identificador de uso interno designado por la empresa. Puede tener cualquier valor. + /// Opcional. + /// + [JsonIgnore] + public string? Sku + { + get => TryGetValue("sku", out var value) ? (string?)value! : default!; + set => this["sku"] = value; + } + + /// + /// Precio unitario + /// Opcional. + /// + [JsonIgnore] + public decimal? UnitPrice + { + get => TryGetValue("unit_price", out var value) ? (decimal?)value! : default!; + set => this["unit_price"] = value; + } + + /// + /// Nombre de la unidad de medida que expresa la cantidad. + /// Opcional. + /// + [JsonIgnore] + public string? UnitName + { + get => TryGetValue("unit_name", out var value) ? (string?)value! : default!; + set => this["unit_name"] = value; + } + + /// + /// Números de pedimento aduanal asociados a esta parte. + /// Opcional. + /// + [JsonIgnore] + public List? CustomsKeys + { + get => TryGetValue("customs_keys", out var value) ? (List?)value! : default!; + set => this["customs_keys"] = value; + } + + } +} diff --git a/Models/Inputs/PaymentInput.cs b/Models/Inputs/PaymentInput.cs new file mode 100644 index 0000000..5a4e929 --- /dev/null +++ b/Models/Inputs/PaymentInput.cs @@ -0,0 +1,198 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Payment + /// + public class PaymentInput : Dictionary + { + /// + /// Crea PaymentInput. + /// + /// Código de la forma de pago según el [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). También puedes utilizar la constante `PaymentForm` incluida en nuestras librerías. Requerido. + /// Arreglo que incluye un elemento por cada comprobante de ingreso relacionado a este pago. Lo más común es que el pago esté relacionado a un sólo comprobante de ingreso. Un caso en el que se agrega más de un elemento es cuando se recibe (por ejemplo) un sólo depósito que ampara el pago de 2 facturas relacionadas. En lugar de expedir un comprobante de recepción de pago por cada factura, debes expedir sólo uno relacionando los 2 comprobantes. Requerido. + public PaymentInput(string @paymentForm, List @relatedDocuments) + { + this["payment_form"] = @paymentForm; + this["related_documents"] = @relatedDocuments; + } + + /// + /// Código de la forma de pago según el [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). También puedes utilizar la constante `PaymentForm` incluida en nuestras librerías. + /// Requerido. + /// + [JsonIgnore] + public string PaymentForm + { + get => TryGetValue("payment_form", out var value) ? (string)value! : default!; + set => this["payment_form"] = value; + } + + /// + /// Arreglo que incluye un elemento por cada comprobante de ingreso relacionado a este pago. Lo más común es que el pago esté relacionado a un sólo comprobante de ingreso. Un caso en el que se agrega más de un elemento es cuando se recibe (por ejemplo) un sólo depósito que ampara el pago de 2 facturas relacionadas. En lugar de expedir un comprobante de recepción de pago por cada factura, debes expedir sólo uno relacionando los 2 comprobantes. + /// Requerido. + /// + [JsonIgnore] + public List RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonIgnore] + public string? Currency + { + get => TryGetValue("currency", out var value) ? (string?)value! : default!; + set => this["currency"] = value; + } + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Opcional. + /// + [JsonIgnore] + public decimal? Exchange + { + get => TryGetValue("exchange", out var value) ? (decimal?)value! : default!; + set => this["exchange"] = value; + } + + /// + /// Format: date-time + /// Fecha en que se recibió el pago. Si se omite, se utiliza la fecha y hora actuales. Inclúyela cuando el pago sea anterior a la emisión del comprobante. No se permiten fechas futuras. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// Número de cheque, de autorización, de referencia, clave de rastreo SPEI, línea de captura o algún número de referencia que permita identificar la operación correspondiente al pago efectuado. + /// Opcional. + /// + [JsonIgnore] + public string? NumOperacion + { + get => TryGetValue("numOperacion", out var value) ? (string?)value! : default!; + set => this["numOperacion"] = value; + } + + /// + /// RFC de la entidad emisora de la cuenta de origen, es decir, la operadora, banco, institución financiera, emisor de monedero electrónico, etc. + /// Opcional. + /// + [JsonIgnore] + public string? RfcEmisorCtaOrd + { + get => TryGetValue("rfcEmisorCtaOrd", out var value) ? (string?)value! : default!; + set => this["rfcEmisorCtaOrd"] = value; + } + + /// + /// Nombre del banco ordenante. + /// Opcional. + /// + [JsonIgnore] + public string? NomBancoOrdExt + { + get => TryGetValue("nomBancoOrdExt", out var value) ? (string?)value! : default!; + set => this["nomBancoOrdExt"] = value; + } + + /// + /// Número de cuenta con la que se realizó el pago. + /// Opcional. + /// + [JsonIgnore] + public string? CtaOrdenante + { + get => TryGetValue("ctaOrdenante", out var value) ? (string?)value! : default!; + set => this["ctaOrdenante"] = value; + } + + /// + /// RFC de la entidad de la cuenta operadora destino, es decir, la operadora, banco, institución financiera, emisor de monedero electrónico, etc. + /// Opcional. + /// + [JsonIgnore] + public string? RfcEmisorCtaBen + { + get => TryGetValue("rfcEmisorCtaBen", out var value) ? (string?)value! : default!; + set => this["rfcEmisorCtaBen"] = value; + } + + /// + /// Número de cuenta donde se recibió el pago. + /// Opcional. + /// + [JsonIgnore] + public string? CtaBeneficiario + { + get => TryGetValue("ctaBeneficiario", out var value) ? (string?)value! : default!; + set => this["ctaBeneficiario"] = value; + } + + /// + /// Clave del tipo de cadena de pago que genera la entidad receptora del pago. + /// Si existe este campo, es obligatorio registrar los campos `certPago`, `cadPago` y `selloPago`. + /// Valores: "01". + /// Opcional. + /// + [JsonIgnore] + public string? TipoCadPago + { + get => TryGetValue("tipoCadPago", out var value) ? (string?)value! : default!; + set => this["tipoCadPago"] = value; + } + + /// + /// Format: base64 + /// Certificado que corresponde al pago, como una cadena de texto en formato base 64. + /// Opcional. + /// + [JsonIgnore] + public string? CertPago + { + get => TryGetValue("certPago", out var value) ? (string?)value! : default!; + set => this["certPago"] = value; + } + + /// + /// Cadena original del comprobante de pago generado por la entidad emisora de la cuenta beneficiaria. + /// Opcional. + /// + [JsonIgnore] + public string? CadPago + { + get => TryGetValue("cadPago", out var value) ? (string?)value! : default!; + set => this["cadPago"] = value; + } + + /// + /// Format: base64 + /// Sello digital que se asocie al pago expresado como una cadena de texto en formato base 64. + /// Opcional. + /// + [JsonIgnore] + public string? SelloPago + { + get => TryGetValue("selloPago", out var value) ? (string?)value! : default!; + set => this["selloPago"] = value; + } + + } +} diff --git a/Models/Inputs/PaymentInputRelatedDocumentsItem.cs b/Models/Inputs/PaymentInputRelatedDocumentsItem.cs new file mode 100644 index 0000000..5e4b9ec --- /dev/null +++ b/Models/Inputs/PaymentInputRelatedDocumentsItem.cs @@ -0,0 +1,161 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// PaymentInputRelatedDocumentsItem + /// + public class PaymentInputRelatedDocumentsItem : Dictionary + { + /// + /// Crea PaymentInputRelatedDocumentsItem. + /// + /// Format: uuid Folio fiscal ó UUID del comprobante de ingreso relacionado. Requerido. + /// Cantidad del pago correspondiente al comprobante relacionado, usando el método de pago indicado en este elemento del arreglo de pagos. Este valor debe ser expresado en la moneda definida en `related_documents[].currency`. Requerido. + /// Arreglo con impuestos del documento relacionado que aplican al pago realizado. Requerido. + /// Número de parcialidad del pago. Requerido. + /// Cantidad que estaba pendiente por pagar antes de recibir este pago. Este valor se expresa en la moneda definida en `related_documents[].currency`. Requerido. + public PaymentInputRelatedDocumentsItem(string @uuid, decimal @amount, List @taxes, int @installment, decimal @lastBalance) + { + this["uuid"] = @uuid; + this["amount"] = @amount; + this["taxes"] = @taxes; + this["installment"] = @installment; + this["last_balance"] = @lastBalance; + } + + /// + /// Format: uuid + /// Folio fiscal ó UUID del comprobante de ingreso relacionado. + /// Requerido. + /// + [JsonIgnore] + public string Uuid + { + get => TryGetValue("uuid", out var value) ? (string)value! : default!; + set => this["uuid"] = value; + } + + /// + /// Cantidad del pago correspondiente al comprobante relacionado, + /// usando el método de pago indicado en este elemento del arreglo + /// de pagos. Este valor debe ser expresado en la moneda definida + /// en `related_documents[].currency`. + /// Requerido. + /// + [JsonIgnore] + public decimal Amount + { + get => TryGetValue("amount", out var value) ? (decimal)value! : default!; + set => this["amount"] = value; + } + + /// + /// Arreglo con impuestos del documento relacionado que aplican al pago realizado. + /// Requerido. + /// + [JsonIgnore] + public List Taxes + { + get => TryGetValue("taxes", out var value) ? (List)value! : default!; + set => this["taxes"] = value; + } + + /// + /// Código que representa si el bien o servicio es objeto de impuesto o no. Este atributo corresponde al campo "ObjetoImp" en el CFDI. + /// + /// - `01`: No objeto de impuesto. + /// - `02`: Sí objeto de impuesto. + /// - `03`: Sí objeto de impuesto, pero no obligado a desglose. + /// - `04`: Sí objeto de impuesto, y no causa impuesto. + /// - `05`: Sí objeto de impuesto, IVA crédito PODEBI. + /// - `06`: Sí objeto de impuesto, no IVA trasladado. + /// - `07`: No traslado de IVA, pero desglose de IEPS. + /// - `08`: No traslado de IVA sin desglose de IEPS. + /// + /// Si se omite, se utiliza `01` cuando `taxes` está vacío y `02` cuando contiene al menos un impuesto. + /// Valores: "01", "04", "02", "03", "05", "06", "07", "08". + /// Opcional. + /// + [JsonIgnore] + public string? Taxability + { + get => TryGetValue("taxability", out var value) ? (string?)value! : default!; + set => this["taxability"] = value; + } + + /// + /// Número de parcialidad del pago. + /// Requerido. + /// + [JsonIgnore] + public int Installment + { + get => TryGetValue("installment", out var value) ? (int)value! : default!; + set => this["installment"] = value; + } + + /// + /// Cantidad que estaba pendiente por pagar antes de recibir este pago. Este valor se expresa en la moneda definida en `related_documents[].currency`. + /// Requerido. + /// + [JsonIgnore] + public decimal LastBalance + { + get => TryGetValue("last_balance", out var value) ? (decimal)value! : default!; + set => this["last_balance"] = value; + } + + /// + /// Si la moneda utilizada en la factura relacionada no es moneda nacional (MXN), debe especificarse su valor acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonIgnore] + public string? Currency + { + get => TryGetValue("currency", out var value) ? (string?)value! : default!; + set => this["currency"] = value; + } + + /// + /// Obligatorio cuando la moneda del documento relacionado es distinta a la moneda de pago. Tipo de cambio entre las dos monedas al momento del pago. Ejemplo: La factura de ingreso relacionada se registra en USD, mientras que el pago actual se realiza en MXN, este atributo debería registrarse como `0.45` (USD/MXN). + /// Opcional. + /// + [JsonIgnore] + public decimal? Exchange + { + get => TryGetValue("exchange", out var value) ? (decimal?)value! : default!; + set => this["exchange"] = value; + } + + /// + /// Opcionalmente se puede incluir el número de folio del documento relacionado. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Opcionalmente se puede incluir la serie del documento relacionado. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + } +} diff --git a/Models/Inputs/PaymentInputRelatedDocumentsItemTaxesItem.cs b/Models/Inputs/PaymentInputRelatedDocumentsItemTaxesItem.cs new file mode 100644 index 0000000..ff60bb1 --- /dev/null +++ b/Models/Inputs/PaymentInputRelatedDocumentsItemTaxesItem.cs @@ -0,0 +1,87 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// PaymentInputRelatedDocumentsItemTaxesItem + /// + public class PaymentInputRelatedDocumentsItemTaxesItem : Dictionary + { + /// + /// Crea PaymentInputRelatedDocumentsItemTaxesItem. + /// + /// Base utilizada para el cálculo del impuestos. Requerido. + /// Tipo de impuesto. Valores: "IVA", "ISR", "IEPS". Requerido. + /// Tasa o cuota del impuesto Requerido. + public PaymentInputRelatedDocumentsItemTaxesItem(decimal @base, string @type, decimal @rate) + { + this["base"] = @base; + this["type"] = @type; + this["rate"] = @rate; + } + + /// + /// Base utilizada para el cálculo del impuestos. + /// Requerido. + /// + [JsonIgnore] + public decimal Base + { + get => TryGetValue("base", out var value) ? (decimal)value! : default!; + set => this["base"] = value; + } + + /// + /// Tipo de impuesto. + /// Valores: "IVA", "ISR", "IEPS". + /// Requerido. + /// + [JsonIgnore] + public string Type + { + get => TryGetValue("type", out var value) ? (string)value! : default!; + set => this["type"] = value; + } + + /// + /// Tasa o cuota del impuesto + /// Requerido. + /// + [JsonIgnore] + public decimal Rate + { + get => TryGetValue("rate", out var value) ? (decimal)value! : default!; + set => this["rate"] = value; + } + + /// + /// Tipo factor. + /// Valores: "Tasa", "Cuota", "Exento". + /// Opcional. + /// + [JsonIgnore] + public string? Factor + { + get => TryGetValue("factor", out var value) ? (string?)value! : default!; + set => this["factor"] = value; + } + + /// + /// Indica si el impuesto es una retención (`true`) o un traslado (`false`). + /// Opcional. + /// + [JsonIgnore] + public bool? Withholding + { + get => TryGetValue("withholding", out var value) ? (bool?)value! : default!; + set => this["withholding"] = value; + } + + } +} diff --git a/Models/Inputs/ProductCreateInput.cs b/Models/Inputs/ProductCreateInput.cs new file mode 100644 index 0000000..ca1fc06 --- /dev/null +++ b/Models/Inputs/ProductCreateInput.cs @@ -0,0 +1,159 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ProductCreateInput + /// + public class ProductCreateInput : Dictionary + { + /// + /// Crea ProductCreateInput. + /// + /// Descripción del bien o servicio como aparecerá en la factura. Requerido. + /// Clave de producto/servicio, del catálogo del SAT. Nosotros te proporcionamos una manera más conveniente de encontrarlo utilizando nuestra [herramienta de búsqueda de claves](https://dashboard.facturapi.io/catalogs/productKey). Requerido. + /// Precio por unidad del bien o servicio. Este valor representará el precio con IVA incluido o sin él, dependiendo del valor de `tax_included`. Requerido. + public ProductCreateInput(string @description, string @productKey, decimal @price) + { + this["description"] = @description; + this["product_key"] = @productKey; + this["price"] = @price; + } + + /// + /// Palabra que representa la unidad de medida de tu producto. Debe estar relacionada con la clave de unidad `unit_key`. + /// Opcional. + /// + [JsonIgnore] + public string? UnitName + { + get => TryGetValue("unit_name", out var value) ? (string?)value! : default!; + set => this["unit_name"] = value; + } + + /// + /// Descripción del bien o servicio como aparecerá en la factura. + /// Requerido. + /// + [JsonIgnore] + public string Description + { + get => TryGetValue("description", out var value) ? (string)value! : default!; + set => this["description"] = value; + } + + /// + /// Clave de producto/servicio, del catálogo del SAT. Nosotros te proporcionamos una manera más conveniente de encontrarlo utilizando nuestra [herramienta de búsqueda de claves](https://dashboard.facturapi.io/catalogs/productKey). + /// Requerido. + /// + [JsonIgnore] + public string ProductKey + { + get => TryGetValue("product_key", out var value) ? (string)value! : default!; + set => this["product_key"] = value; + } + + /// + /// Precio por unidad del bien o servicio. Este valor representará el precio con IVA incluido o sin él, dependiendo del valor de `tax_included`. + /// Requerido. + /// + [JsonIgnore] + public decimal Price + { + get => TryGetValue("price", out var value) ? (decimal)value! : default!; + set => this["price"] = value; + } + + /// + /// - `true`: Indica que todos los impuestos aplicables están incluidos en el precio (atributo price) y se desglosarán automáticamente al emitir la factura. + /// - `false`: Indica que el atributo price no incluye impuestos, por lo que aquellos impuestos a aplicar se sumarán en el precio final. + /// Opcional. + /// + [JsonIgnore] + public bool? TaxIncluded + { + get => TryGetValue("tax_included", out var value) ? (bool?)value! : default!; + set => this["tax_included"] = value; + } + + /// + /// Código que representa si el bien o servicio es objeto de impuesto o no. Este atributo corresponde al campo "ObjetoImp" en el CFDI. + /// + /// - `01`: No objeto de impuesto. + /// - `02`: Sí objeto de impuesto. + /// - `03`: Sí objeto de impuesto, pero no obligado a desglose. + /// - `04`: Sí objeto de impuesto, y no causa impuesto. + /// - `05`: Sí objeto de impuesto, IVA crédito PODEBI. + /// - `06`: Sí objeto de impuesto, no IVA trasladado. + /// - `07`: No traslado de IVA, pero desglose de IEPS. + /// - `08`: No traslado de IVA sin desglose de IEPS. + /// Valores: "01", "04", "02", "03", "05", "06", "07", "08". + /// Opcional. + /// + [JsonIgnore] + public string? Taxability + { + get => TryGetValue("taxability", out var value) ? (string?)value! : default!; + set => this["taxability"] = value; + } + + /// + /// Lista de impuestos que deberán aplicarse a este producto. + /// + /// Resolución cuando `taxes` se omite o es `null`: + /// - `taxability` omitido o `"02"`: se agrega IVA trasladado 16%. + /// - `taxability` en `"01"`, `"03"`, `"04"`, `"05"`, `"06"` o `"08"`: se guarda `[]`. + /// - `taxability = "07"`: la solicitud es inválida; debes enviar al menos un IEPS de traslado y no incluir IVA. + /// + /// Si envías `taxes` explícitamente, se usa el arreglo enviado. + /// Opcional. + /// + [JsonIgnore] + public List? Taxes + { + get => TryGetValue("taxes", out var value) ? (List?)value! : default!; + set => this["taxes"] = value; + } + + /// + /// Arreglo de impuestos locales (estatales o municipales), en caso de haberlos. + /// Opcional. + /// + [JsonIgnore] + public List? LocalTaxes + { + get => TryGetValue("local_taxes", out var value) ? (List?)value! : default!; + set => this["local_taxes"] = value; + } + + /// + /// Clave de unidad de medida, del catálogo del SAT. El valor por default `"H87"` (elemento) es la clave para representar una pieza o unidad de venta (lápiz, cuaderno, televisión, etc). + /// Si la unidad de tu producto es kilogramos, litros, horas u otra unidad, puedes encontrar la clave utilizando nuestra [herramienta de búsqueda de claves](https://dashboard.facturapi.io/catalogs/unit). + /// Opcional. + /// + [JsonIgnore] + public string? UnitKey + { + get => TryGetValue("unit_key", out var value) ? (string?)value! : default!; + set => this["unit_key"] = value; + } + + /// + /// Identificador de uso interno designado por la empresa. Puede tener cualquier valor. + /// Opcional. + /// + [JsonIgnore] + public string? Sku + { + get => TryGetValue("sku", out var value) ? (string?)value! : default!; + set => this["sku"] = value; + } + + } +} diff --git a/Models/Inputs/ProductListParams.cs b/Models/Inputs/ProductListParams.cs new file mode 100644 index 0000000..f25b9b9 --- /dev/null +++ b/Models/Inputs/ProductListParams.cs @@ -0,0 +1,95 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ProductListParams + /// + public class ProductListParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Consulta. Texto a buscar en la descripción del producto o SKU. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// SKU del producto. + /// Opcional. + /// + [JsonIgnore] + public string? Sku + { + get => TryGetValue("sku", out var value) ? (string?)value! : default!; + set => this["sku"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados (con el `limit` por defecto de 100, la página máxima es 30). + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/ProductUpdateInput.cs b/Models/Inputs/ProductUpdateInput.cs new file mode 100644 index 0000000..138f9a1 --- /dev/null +++ b/Models/Inputs/ProductUpdateInput.cs @@ -0,0 +1,146 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ProductUpdateInput + /// + public class ProductUpdateInput : Dictionary + { + /// + /// Palabra que representa la unidad de medida de tu producto. Debe estar relacionada con la clave de unidad `unit_key`. + /// Opcional. + /// + [JsonIgnore] + public string? UnitName + { + get => TryGetValue("unit_name", out var value) ? (string?)value! : default!; + set => this["unit_name"] = value; + } + + /// + /// Descripción del bien o servicio como aparecerá en la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Description + { + get => TryGetValue("description", out var value) ? (string?)value! : default!; + set => this["description"] = value; + } + + /// + /// Clave de producto/servicio, del catálogo del SAT. Nosotros te proporcionamos una manera más conveniente de encontrarlo utilizando nuestra [herramienta de búsqueda de claves](https://dashboard.facturapi.io/catalogs/productKey). + /// Opcional. + /// + [JsonIgnore] + public string? ProductKey + { + get => TryGetValue("product_key", out var value) ? (string?)value! : default!; + set => this["product_key"] = value; + } + + /// + /// Precio por unidad del bien o servicio. Este valor representará el precio con IVA incluido o sin él, dependiendo del valor de `tax_included`. + /// Opcional. + /// + [JsonIgnore] + public decimal? Price + { + get => TryGetValue("price", out var value) ? (decimal?)value! : default!; + set => this["price"] = value; + } + + /// + /// - `true`: Indica que todos los impuestos aplicables están incluidos en el precio (atributo price) y se desglosarán automáticamente al emitir la factura. + /// - `false`: Indica que el atributo price no incluye impuestos, por lo que aquellos impuestos a aplicar se sumarán en el precio final. + /// Opcional. + /// + [JsonIgnore] + public bool? TaxIncluded + { + get => TryGetValue("tax_included", out var value) ? (bool?)value! : default!; + set => this["tax_included"] = value; + } + + /// + /// Código que representa si el bien o servicio es objeto de impuesto o no. Este atributo corresponde al campo "ObjetoImp" en el CFDI. + /// + /// - `01`: No objeto de impuesto. + /// - `02`: Sí objeto de impuesto. + /// - `03`: Sí objeto de impuesto, pero no obligado a desglose. + /// - `04`: Sí objeto de impuesto, y no causa impuesto. + /// - `05`: Sí objeto de impuesto, IVA crédito PODEBI. + /// - `06`: Sí objeto de impuesto, no IVA trasladado. + /// - `07`: No traslado de IVA, pero desglose de IEPS. + /// - `08`: No traslado de IVA sin desglose de IEPS. + /// Valores: "01", "04", "02", "03", "05", "06", "07", "08". + /// Opcional. + /// + [JsonIgnore] + public string? Taxability + { + get => TryGetValue("taxability", out var value) ? (string?)value! : default!; + set => this["taxability"] = value; + } + + /// + /// Lista de impuestos que deberán aplicarse a este producto. + /// + /// Resolución cuando `taxes` se omite o es `null`: + /// - `taxability` omitido o `"02"`: se agrega IVA trasladado 16%. + /// - `taxability` en `"01"`, `"03"`, `"04"`, `"05"`, `"06"` o `"08"`: se guarda `[]`. + /// - `taxability = "07"`: la solicitud es inválida; debes enviar al menos un IEPS de traslado y no incluir IVA. + /// + /// Si envías `taxes` explícitamente, se usa el arreglo enviado. + /// Opcional. + /// + [JsonIgnore] + public List? Taxes + { + get => TryGetValue("taxes", out var value) ? (List?)value! : default!; + set => this["taxes"] = value; + } + + /// + /// Arreglo de impuestos locales (estatales o municipales), en caso de haberlos. + /// Opcional. + /// + [JsonIgnore] + public List? LocalTaxes + { + get => TryGetValue("local_taxes", out var value) ? (List?)value! : default!; + set => this["local_taxes"] = value; + } + + /// + /// Clave de unidad de medida, del catálogo del SAT. El valor por default `"H87"` (elemento) es la clave para representar una pieza o unidad de venta (lápiz, cuaderno, televisión, etc). + /// Si la unidad de tu producto es kilogramos, litros, horas u otra unidad, puedes encontrar la clave utilizando nuestra [herramienta de búsqueda de claves](https://dashboard.facturapi.io/catalogs/unit). + /// Opcional. + /// + [JsonIgnore] + public string? UnitKey + { + get => TryGetValue("unit_key", out var value) ? (string?)value! : default!; + set => this["unit_key"] = value; + } + + /// + /// Identificador de uso interno designado por la empresa. Puede tener cualquier valor. + /// Opcional. + /// + [JsonIgnore] + public string? Sku + { + get => TryGetValue("sku", out var value) ? (string?)value! : default!; + set => this["sku"] = value; + } + + } +} diff --git a/Models/Inputs/ReceiptAssignCustomerInput.cs b/Models/Inputs/ReceiptAssignCustomerInput.cs new file mode 100644 index 0000000..66ce333 --- /dev/null +++ b/Models/Inputs/ReceiptAssignCustomerInput.cs @@ -0,0 +1,37 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ReceiptAssignCustomerInput + /// + public class ReceiptAssignCustomerInput : Dictionary + { + /// + /// Crea ReceiptAssignCustomerInput. + /// + /// Cliente a asignar o reasignar al recibo. Puedes enviar el ID de un cliente existente o un objeto de cliente para crearlo. Requerido. + public ReceiptAssignCustomerInput(OneOf @customer) + { + this["customer"] = @customer.Value; + } + + /// + /// Cliente a asignar o reasignar al recibo. Puedes enviar el ID de un cliente existente o un objeto de cliente para crearlo. + /// Requerido. + /// + [JsonIgnore] + public OneOf Customer + { + get => TryGetValue("customer", out var value) ? OneOf.FromValue(value) : default!; + set => this["customer"] = value.Value; + } + + } +} diff --git a/Models/Inputs/ReceiptInput.cs b/Models/Inputs/ReceiptInput.cs new file mode 100644 index 0000000..f913b64 --- /dev/null +++ b/Models/Inputs/ReceiptInput.cs @@ -0,0 +1,153 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ReceiptInput + /// + public class ReceiptInput : Dictionary + { + /// + /// Crea ReceiptInput. + /// + /// Conceptos a incluir en el recibo. El número máximo de elementos que puedes incluir en un recibo es de 5,000. Si necesitas emitir una recibo con más de 5,000 conceptos, prueba dividir la transacción en varios recibos. Requerido. + public ReceiptInput(List @items) + { + this["items"] = @items; + } + + /// + /// Cliente asociado al recibo. Puedes enviar el ID de un cliente existente o un objeto de cliente para crearlo. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public ReceiptInputAddress? Address + { + get => TryGetValue("address", out var value) ? (ReceiptInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Conceptos a incluir en el recibo. + /// + /// El número máximo de elementos que puedes incluir en un recibo es de 5,000. Si necesitas + /// emitir una recibo con más de 5,000 conceptos, prueba dividir la transacción en varios recibos. + /// Requerido. + /// + [JsonIgnore] + public List Items + { + get => TryGetValue("items", out var value) ? (List)value! : default!; + set => this["items"] = value; + } + + /// + /// Format: date-time + /// Fecha de emisión del recibo. Por defecto se utiliza la fecha actual. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// Código que representa la forma de pago, según el [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Opcional. + /// + [JsonIgnore] + public string? PaymentForm + { + get => TryGetValue("payment_form", out var value) ? (string?)value! : default!; + set => this["payment_form"] = value; + } + + /// + /// Autoincremental. Número de folio del recibo para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonIgnore] + public string? Currency + { + get => TryGetValue("currency", out var value) ? (string?)value! : default!; + set => this["currency"] = value; + } + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Opcional. + /// + [JsonIgnore] + public decimal? Exchange + { + get => TryGetValue("exchange", out var value) ? (decimal?)value! : default!; + set => this["exchange"] = value; + } + + /// + /// Nombre de la sucursal donde se expidió el recibo. + /// Opcional. + /// + [JsonIgnore] + public string? Branch + { + get => TryGetValue("branch", out var value) ? (string?)value! : default!; + set => this["branch"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar este recibo con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + } +} diff --git a/Models/Inputs/ReceiptInputAddress.cs b/Models/Inputs/ReceiptInputAddress.cs new file mode 100644 index 0000000..bc869bc --- /dev/null +++ b/Models/Inputs/ReceiptInputAddress.cs @@ -0,0 +1,105 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ReceiptInputAddress + /// + public class ReceiptInputAddress : Dictionary + { + /// + /// Nombre de la calle + /// Opcional. + /// + [JsonIgnore] + public string? Street + { + get => TryGetValue("street", out var value) ? (string?)value! : default!; + set => this["street"] = value; + } + + /// + /// Número exterior. + /// Opcional. + /// + [JsonIgnore] + public string? Exterior + { + get => TryGetValue("exterior", out var value) ? (string?)value! : default!; + set => this["exterior"] = value; + } + + /// + /// Número interior. + /// Opcional. + /// + [JsonIgnore] + public string? Interior + { + get => TryGetValue("interior", out var value) ? (string?)value! : default!; + set => this["interior"] = value; + } + + /// + /// Colonia + /// Opcional. + /// + [JsonIgnore] + public string? Neighborhood + { + get => TryGetValue("neighborhood", out var value) ? (string?)value! : default!; + set => this["neighborhood"] = value; + } + + /// + /// Ciudad + /// Opcional. + /// + [JsonIgnore] + public string? City + { + get => TryGetValue("city", out var value) ? (string?)value! : default!; + set => this["city"] = value; + } + + /// + /// Municipio o delegación + /// Opcional. + /// + [JsonIgnore] + public string? Municipality + { + get => TryGetValue("municipality", out var value) ? (string?)value! : default!; + set => this["municipality"] = value; + } + + /// + /// Código postal + /// Opcional. + /// + [JsonIgnore] + public string? Zip + { + get => TryGetValue("zip", out var value) ? (string?)value! : default!; + set => this["zip"] = value; + } + + /// + /// Nombre del Estado o Entidad Federativa. + /// Opcional. + /// + [JsonIgnore] + public string? State + { + get => TryGetValue("state", out var value) ? (string?)value! : default!; + set => this["state"] = value; + } + + } +} diff --git a/Models/Inputs/ReceiptListParams.cs b/Models/Inputs/ReceiptListParams.cs new file mode 100644 index 0000000..432d9d0 --- /dev/null +++ b/Models/Inputs/ReceiptListParams.cs @@ -0,0 +1,150 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ReceiptListParams + /// + public class ReceiptListParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Consulta. Texto a buscar en la descripción de los conceptos del recibo o el SKU. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// ID del cliente asociado al recibo. + /// Opcional. + /// + [JsonIgnore] + public string? Customer + { + get => TryGetValue("customer", out var value) ? (string?)value! : default!; + set => this["customer"] = value; + } + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). Si se incluye, los recibos se agruparán y se listarán de acuerdo a la forma de pago. + /// Opcional. + /// + [JsonIgnore] + public string? PaymentForm + { + get => TryGetValue("payment_form", out var value) ? (string?)value! : default!; + set => this["payment_form"] = value; + } + + /// + /// Fecha de creación mayor o igual a la especificada. + /// Opcional. + /// + [JsonIgnore] + public OneOf? DateGte_ + { + get => TryGetValue("date[gte]", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date[gte]"] = value?.Value; + } + + /// + /// Fecha de creación menor o igual a la especificada. + /// Opcional. + /// + [JsonIgnore] + public OneOf? DateLte_ + { + get => TryGetValue("date[lte]", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date[lte]"] = value?.Value; + } + + /// + /// ID de la factura relacionada al recibo. + /// Opcional. + /// + [JsonIgnore] + public string? Invoice + { + get => TryGetValue("invoice", out var value) ? (string?)value! : default!; + set => this["invoice"] = value; + } + + /// + /// Objeto con rango de fechas solicitado. + /// Opcional. + /// + [JsonIgnore] + public DateRangeInput? Date + { + get => TryGetValue("date", out var value) ? (DateRangeInput?)value! : default!; + set => this["date"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados (con el `limit` por defecto de 100, la página máxima es 30). + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/RelatedDocumentInput.cs b/Models/Inputs/RelatedDocumentInput.cs new file mode 100644 index 0000000..2bbbc78 --- /dev/null +++ b/Models/Inputs/RelatedDocumentInput.cs @@ -0,0 +1,48 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// RelatedDocumentInput + /// + public class RelatedDocumentInput : Dictionary + { + /// + /// Crea RelatedDocumentInput. + /// + /// Clave de relación del catálogo del SAT que puedes consultar en [esta tabla](https://docs.facturapi.io/api/#relacion-entre-facturas). Es requerido cuando se envíe el parámetro `related_documents`. Requerido. + public RelatedDocumentInput(string @relationship) + { + this["relationship"] = @relationship; + } + + /// + /// Clave de relación del catálogo del SAT que puedes consultar en [esta tabla](https://docs.facturapi.io/api/#relacion-entre-facturas). Es requerido cuando se envíe el parámetro `related_documents`. + /// Requerido. + /// + [JsonIgnore] + public string Relationship + { + get => TryGetValue("relationship", out var value) ? (string)value! : default!; + set => this["relationship"] = value; + } + + /// + /// Folios fiscales (UUID) de facturas relacionadas. + /// Opcional. + /// + [JsonIgnore] + public List? Documents + { + get => TryGetValue("documents", out var value) ? (List?)value! : default!; + set => this["documents"] = value; + } + + } +} diff --git a/Models/Inputs/RetentionInput.cs b/Models/Inputs/RetentionInput.cs new file mode 100644 index 0000000..60de8af --- /dev/null +++ b/Models/Inputs/RetentionInput.cs @@ -0,0 +1,191 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// RetentionInput + /// + public class RetentionInput : Dictionary + { + /// + /// Crea RetentionInput. + /// + public RetentionInput() + { + this["status"] = "draft"; + } + + /// + /// Estado inicial de la retención. Si se envía `draft`, la retención se + /// guardará como borrador y no se timbrará ni se enviará al SAT. También + /// al enviar `draft`, `customer`, `cve_retenc`, `periodo` y `totales` + /// pueden omitirse o enviarse como `null`. + /// Valores: "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Cliente receptor de la factura. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// Clave de la retención o información de pagos de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#clave-de-retencion). + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? CveRetenc + { + get => TryGetValue("cve_retenc", out var value) ? (string?)value! : default!; + set => this["cve_retenc"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). + /// Opcional. + /// + [JsonIgnore] + public OneOf? FechaExp + { + get => TryGetValue("fecha_exp", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["fecha_exp"] = value?.Value; + } + + /// + /// Si la clave de la retención es “25” (Otro tipo de retenciones), este campo se usa para registrar la descripción de la retención. + /// Opcional. + /// + [JsonIgnore] + public string? DescRetenc + { + get => TryGetValue("desc_retenc", out var value) ? (string?)value! : default!; + set => this["desc_retenc"] = value; + } + + /// + /// Identificador alfanumérico para control interno de la empresa y sin relevancia fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? FolioInt + { + get => TryGetValue("folio_int", out var value) ? (string?)value! : default!; + set => this["folio_int"] = value; + } + + /// + /// Información sobre el periodo de la retención. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public RetentionInputPeriodo? Periodo + { + get => TryGetValue("periodo", out var value) ? (RetentionInputPeriodo?)value! : default!; + set => this["periodo"] = value; + } + + /// + /// Información sobre el total de retenciones efectuadas en el periodo correspondiente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public RetentionInputTotales? Totales + { + get => TryGetValue("totales", out var value) ? (RetentionInputTotales?)value! : default!; + set => this["totales"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta retención con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Arreglo de complementos a incluir en la factura. Cada elemento del arreglo deberá contener + /// un `string` con el código XML de tu complemento tal cual como quieres que se inserte en el + /// XML del CFDI. Sólo se permite un nodo XML raíz por elemento del arreglo. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// Format: html + /// En caso de que necesites incluir más información en el PDF, este campo te permite insertar código HTML con tu propio contenido. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Lista de fragmentos XML que se incluirán como addendas en la retención. + /// Opcional. + /// + [JsonIgnore] + public List? Addenda + { + get => TryGetValue("addenda", out var value) ? (List?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Namespaces a insertar en el nodo raíz de la factura. Requerido en `addenda`. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + } +} diff --git a/Models/Inputs/RetentionInputPeriodo.cs b/Models/Inputs/RetentionInputPeriodo.cs new file mode 100644 index 0000000..fa2b58a --- /dev/null +++ b/Models/Inputs/RetentionInputPeriodo.cs @@ -0,0 +1,63 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// RetentionInputPeriodo + /// + public class RetentionInputPeriodo : Dictionary + { + /// + /// Crea RetentionInputPeriodo. + /// + /// Mes inicial del periodo de la retención. Requerido. + /// Mes final del periodo de la retención. Requerido. + /// Año o ejercicio fiscal en que se realizó la retención. Requerido. + public RetentionInputPeriodo(int @mesIni, int @mesFin, int @ejerc) + { + this["mes_ini"] = @mesIni; + this["mes_fin"] = @mesFin; + this["ejerc"] = @ejerc; + } + + /// + /// Mes inicial del periodo de la retención. + /// Requerido. + /// + [JsonIgnore] + public int MesIni + { + get => TryGetValue("mes_ini", out var value) ? (int)value! : default!; + set => this["mes_ini"] = value; + } + + /// + /// Mes final del periodo de la retención. + /// Requerido. + /// + [JsonIgnore] + public int MesFin + { + get => TryGetValue("mes_fin", out var value) ? (int)value! : default!; + set => this["mes_fin"] = value; + } + + /// + /// Año o ejercicio fiscal en que se realizó la retención. + /// Requerido. + /// + [JsonIgnore] + public int Ejerc + { + get => TryGetValue("ejerc", out var value) ? (int)value! : default!; + set => this["ejerc"] = value; + } + + } +} diff --git a/Models/Inputs/RetentionInputTotales.cs b/Models/Inputs/RetentionInputTotales.cs new file mode 100644 index 0000000..02e0d8b --- /dev/null +++ b/Models/Inputs/RetentionInputTotales.cs @@ -0,0 +1,85 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// RetentionInputTotales + /// + public class RetentionInputTotales : Dictionary + { + /// + /// Crea RetentionInputTotales. + /// + /// Monto total de la operación, con precisión de hasta 6 decimales. Requerido. + /// Monto total exento. Requerido. + /// Colección de impuestos retenidos. Requerido. + public RetentionInputTotales(decimal @montoTotOperacion, decimal @montoTotExent, List @impRetenidos) + { + this["monto_tot_operacion"] = @montoTotOperacion; + this["monto_tot_exent"] = @montoTotExent; + this["imp_retenidos"] = @impRetenidos; + } + + /// + /// Monto total de la operación, con precisión de hasta 6 decimales. + /// Requerido. + /// + [JsonIgnore] + public decimal MontoTotOperacion + { + get => TryGetValue("monto_tot_operacion", out var value) ? (decimal)value! : default!; + set => this["monto_tot_operacion"] = value; + } + + /// + /// Monto total gravado. + /// Opcional. + /// + [JsonIgnore] + public decimal? MontoTotGrav + { + get => TryGetValue("monto_tot_grav", out var value) ? (decimal?)value! : default!; + set => this["monto_tot_grav"] = value; + } + + /// + /// Monto total exento. + /// Requerido. + /// + [JsonIgnore] + public decimal MontoTotExent + { + get => TryGetValue("monto_tot_exent", out var value) ? (decimal)value! : default!; + set => this["monto_tot_exent"] = value; + } + + /// + /// Suma de los montos de impuestos retenidos. + /// Opcional. + /// + [JsonIgnore] + public decimal? MontoTotRet + { + get => TryGetValue("monto_tot_ret", out var value) ? (decimal?)value! : default!; + set => this["monto_tot_ret"] = value; + } + + /// + /// Colección de impuestos retenidos. + /// Requerido. + /// + [JsonIgnore] + public List ImpRetenidos + { + get => TryGetValue("imp_retenidos", out var value) ? (List)value! : default!; + set => this["imp_retenidos"] = value; + } + + } +} diff --git a/Models/Inputs/RetentionInputTotalesImpRetenidosItem.cs b/Models/Inputs/RetentionInputTotalesImpRetenidosItem.cs new file mode 100644 index 0000000..6369bc4 --- /dev/null +++ b/Models/Inputs/RetentionInputTotalesImpRetenidosItem.cs @@ -0,0 +1,77 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// RetentionInputTotalesImpRetenidosItem + /// + public class RetentionInputTotalesImpRetenidosItem : Dictionary + { + /// + /// Crea RetentionInputTotalesImpRetenidosItem. + /// + /// Importe del impuesto retenido Requerido. + /// - `01`: Pago definitivo IVA - `02`: Pago definitivo IEPS - `03`: Pago definitivo ISR Plataformas - `04`: Pago provisional ISR Valores: "01", "04", "02", "03". Requerido. + public RetentionInputTotalesImpRetenidosItem(decimal @montoRet, string @tipoPagoRet) + { + this["monto_ret"] = @montoRet; + this["tipo_pago_ret"] = @tipoPagoRet; + } + + /// + /// Base del impuesto retenido. + /// Opcional. + /// + [JsonIgnore] + public decimal? BaseRet + { + get => TryGetValue("base_ret", out var value) ? (decimal?)value! : default!; + set => this["base_ret"] = value; + } + + /// + /// Clave del tipo de impuesto retenido, del catálogo del SAT. + /// Valores: "IVA", "ISR". + /// Opcional. + /// + [JsonIgnore] + public string? Impuesto + { + get => TryGetValue("impuesto", out var value) ? (string?)value! : default!; + set => this["impuesto"] = value; + } + + /// + /// Importe del impuesto retenido + /// Requerido. + /// + [JsonIgnore] + public decimal MontoRet + { + get => TryGetValue("monto_ret", out var value) ? (decimal)value! : default!; + set => this["monto_ret"] = value; + } + + /// + /// - `01`: Pago definitivo IVA + /// - `02`: Pago definitivo IEPS + /// - `03`: Pago definitivo ISR Plataformas + /// - `04`: Pago provisional ISR + /// Valores: "01", "04", "02", "03". + /// Requerido. + /// + [JsonIgnore] + public string TipoPagoRet + { + get => TryGetValue("tipo_pago_ret", out var value) ? (string)value! : default!; + set => this["tipo_pago_ret"] = value; + } + + } +} diff --git a/Models/Inputs/RetentionListParams.cs b/Models/Inputs/RetentionListParams.cs new file mode 100644 index 0000000..a6c10f4 --- /dev/null +++ b/Models/Inputs/RetentionListParams.cs @@ -0,0 +1,117 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// RetentionListParams + /// + public class RetentionListParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Consulta. Texto a buscar en el nombre fiscal del cliente o su RFC. + /// Opcional. + /// + [JsonIgnore] + public string? Q + { + get => TryGetValue("q", out var value) ? (string?)value! : default!; + set => this["q"] = value; + } + + /// + /// Identificador del cliente. Útil para obtener las retenciones emitidas a un sólo cliente. + /// Opcional. + /// + [JsonIgnore] + public string? Customer + { + get => TryGetValue("customer", out var value) ? (string?)value! : default!; + set => this["customer"] = value; + } + + /// + /// Filtrar por uno o más estados de retención. Si se omite, no se filtra por estado, equivalente a `all`. Enviar `all` también desactiva este filtro. + /// Opcional. + /// + [JsonIgnore] + public List? Status + { + get => TryGetValue("status", out var value) ? (List?)value! : default!; + set => this["status"] = value; + } + + /// + /// Objeto con rango de fechas solicitado. + /// Opcional. + /// + [JsonIgnore] + public DateRangeInput? Date + { + get => TryGetValue("date", out var value) ? (DateRangeInput?)value! : default!; + set => this["date"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados (con el `limit` por defecto de 100, la página máxima es 30). + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/RetentionUpdateInput.cs b/Models/Inputs/RetentionUpdateInput.cs new file mode 100644 index 0000000..cc91896 --- /dev/null +++ b/Models/Inputs/RetentionUpdateInput.cs @@ -0,0 +1,191 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// RetentionUpdateInput + /// + public class RetentionUpdateInput : Dictionary + { + /// + /// Crea RetentionUpdateInput. + /// + public RetentionUpdateInput() + { + this["status"] = "draft"; + } + + /// + /// Estado inicial de la retención. Si se envía `draft`, la retención se + /// guardará como borrador y no se timbrará ni se enviará al SAT. También + /// al enviar `draft`, `customer`, `cve_retenc`, `periodo` y `totales` + /// pueden omitirse o enviarse como `null`. + /// Valores: "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Cliente receptor de la factura. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// Clave de la retención o información de pagos de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#clave-de-retencion). + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? CveRetenc + { + get => TryGetValue("cve_retenc", out var value) ? (string?)value! : default!; + set => this["cve_retenc"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). + /// Opcional. + /// + [JsonIgnore] + public OneOf? FechaExp + { + get => TryGetValue("fecha_exp", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["fecha_exp"] = value?.Value; + } + + /// + /// Si la clave de la retención es “25” (Otro tipo de retenciones), este campo se usa para registrar la descripción de la retención. + /// Opcional. + /// + [JsonIgnore] + public string? DescRetenc + { + get => TryGetValue("desc_retenc", out var value) ? (string?)value! : default!; + set => this["desc_retenc"] = value; + } + + /// + /// Identificador alfanumérico para control interno de la empresa y sin relevancia fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? FolioInt + { + get => TryGetValue("folio_int", out var value) ? (string?)value! : default!; + set => this["folio_int"] = value; + } + + /// + /// Información sobre el periodo de la retención. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public RetentionInputPeriodo? Periodo + { + get => TryGetValue("periodo", out var value) ? (RetentionInputPeriodo?)value! : default!; + set => this["periodo"] = value; + } + + /// + /// Información sobre el total de retenciones efectuadas en el periodo correspondiente. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public RetentionInputTotales? Totales + { + get => TryGetValue("totales", out var value) ? (RetentionInputTotales?)value! : default!; + set => this["totales"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta retención con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Arreglo de complementos a incluir en la factura. Cada elemento del arreglo deberá contener + /// un `string` con el código XML de tu complemento tal cual como quieres que se inserte en el + /// XML del CFDI. Sólo se permite un nodo XML raíz por elemento del arreglo. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// Format: html + /// En caso de que necesites incluir más información en el PDF, este campo te permite insertar código HTML con tu propio contenido. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Lista de fragmentos XML que se incluirán como addendas en la retención. + /// Opcional. + /// + [JsonIgnore] + public List? Addenda + { + get => TryGetValue("addenda", out var value) ? (List?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Namespaces a insertar en el nodo raíz de la factura. Requerido en `addenda`. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + } +} diff --git a/Models/Inputs/CustomerEditLinkEmailInput.cs b/Models/Inputs/SendEditLinkByEmailInput.cs similarity index 71% rename from Models/Inputs/CustomerEditLinkEmailInput.cs rename to Models/Inputs/SendEditLinkByEmailInput.cs index 765f485..bcf23ba 100644 --- a/Models/Inputs/CustomerEditLinkEmailInput.cs +++ b/Models/Inputs/SendEditLinkByEmailInput.cs @@ -1,14 +1,17 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// - /// CustomerEditLinkEmailInput + /// SendEditLinkByEmailInput /// - public class CustomerEditLinkEmailInput : Dictionary + public class SendEditLinkByEmailInput : Dictionary { /// /// Correo electrónico de destino. Si se omite o es null, se usa el correo electrónico del cliente. @@ -16,9 +19,9 @@ public class CustomerEditLinkEmailInput : Dictionary /// Admite null. /// [JsonIgnore] - public string Email + public string? Email { - get => TryGetValue("email", out var value) ? (string)value : default; + get => TryGetValue("email", out var value) ? (string?)value! : default!; set => this["email"] = value; } diff --git a/Models/Inputs/SendInvoiceByEmailInput.cs b/Models/Inputs/SendInvoiceByEmailInput.cs new file mode 100644 index 0000000..a92b844 --- /dev/null +++ b/Models/Inputs/SendInvoiceByEmailInput.cs @@ -0,0 +1,28 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// SendInvoiceByEmailInput + /// + public class SendInvoiceByEmailInput : Dictionary + { + /// + /// Dirección de correo electrónico a enviar la factura. Si no se envía este parámetro, la factura será enviada al correo que el cliente tenga registrado. + /// Opcional. + /// + [JsonIgnore] + public OneOf>? Email + { + get => TryGetValue("email", out var value) && value != null ? OneOf>.FromValue(value) : default(OneOf>?); + set => this["email"] = value?.Value; + } + + } +} diff --git a/Models/Inputs/SendReceiptByEmailInput.cs b/Models/Inputs/SendReceiptByEmailInput.cs new file mode 100644 index 0000000..50f68a6 --- /dev/null +++ b/Models/Inputs/SendReceiptByEmailInput.cs @@ -0,0 +1,37 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// SendReceiptByEmailInput + /// + public class SendReceiptByEmailInput : Dictionary + { + /// + /// Crea SendReceiptByEmailInput. + /// + /// Dirección de correo electrónico a enviar el recibo digital. Requerido. + public SendReceiptByEmailInput(OneOf> @email) + { + this["email"] = @email.Value; + } + + /// + /// Dirección de correo electrónico a enviar el recibo digital. + /// Requerido. + /// + [JsonIgnore] + public OneOf> Email + { + get => TryGetValue("email", out var value) ? OneOf>.FromValue(value) : default!; + set => this["email"] = value.Value; + } + + } +} diff --git a/Models/Inputs/SendRetentionByEmailInput.cs b/Models/Inputs/SendRetentionByEmailInput.cs new file mode 100644 index 0000000..0a372c1 --- /dev/null +++ b/Models/Inputs/SendRetentionByEmailInput.cs @@ -0,0 +1,28 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// SendRetentionByEmailInput + /// + public class SendRetentionByEmailInput : Dictionary + { + /// + /// Dirección de correo electrónico a enviar la retención. Si no se envía este parámetro, la retención será enviada al correo que el cliente tenga registrado. + /// Opcional. + /// + [JsonIgnore] + public OneOf>? Email + { + get => TryGetValue("email", out var value) && value != null ? OneOf>.FromValue(value) : default(OneOf>?); + set => this["email"] = value?.Value; + } + + } +} diff --git a/Models/Inputs/TaxInput.cs b/Models/Inputs/TaxInput.cs new file mode 100644 index 0000000..cc132b9 --- /dev/null +++ b/Models/Inputs/TaxInput.cs @@ -0,0 +1,96 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// TaxInput + /// + public class TaxInput : Dictionary + { + /// + /// Crea TaxInput. + /// + /// Tasa del impuesto en fracción decimal. Requerido. + public TaxInput(decimal @rate) + { + this["rate"] = @rate; + } + + /// + /// Tasa del impuesto en fracción decimal. + /// Requerido. + /// + [JsonIgnore] + public decimal Rate + { + get => TryGetValue("rate", out var value) ? (decimal)value! : default!; + set => this["rate"] = value; + } + + /// + /// Base del impuesto. Si se omite, se calcula a partir del subtotal del concepto y el factor del impuesto. Para el factor Cuota, se utiliza la cantidad de unidades. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public decimal? Base + { + get => TryGetValue("base", out var value) ? (decimal?)value! : default!; + set => this["base"] = value; + } + + /// + /// Tipo de impuesto. + /// Valores: "IVA", "ISR", "IEPS". + /// Opcional. + /// + [JsonIgnore] + public string? Type + { + get => TryGetValue("type", out var value) ? (string?)value! : default!; + set => this["type"] = value; + } + + /// + /// ieps_mode + /// Valores: "sum_before_taxes", "break_down", "unit", "subtract_before_break_down". + /// Opcional. + /// + [JsonIgnore] + public string? IepsMode + { + get => TryGetValue("ieps_mode", out var value) ? (string?)value! : default!; + set => this["ieps_mode"] = value; + } + + /// + /// Tipo factor + /// Valores: "Tasa", "Cuota", "Exento". + /// Opcional. + /// + [JsonIgnore] + public string? Factor + { + get => TryGetValue("factor", out var value) ? (string?)value! : default!; + set => this["factor"] = value; + } + + /// + /// Indica si se trata de un impuesto retenido (`true`), o un impuesto trasladado (`false`) + /// Opcional. + /// + [JsonIgnore] + public bool? Withholding + { + get => TryGetValue("withholding", out var value) ? (bool?)value! : default!; + set => this["withholding"] = value; + } + + } +} diff --git a/Models/Inputs/ToInvoiceInput.cs b/Models/Inputs/ToInvoiceInput.cs new file mode 100644 index 0000000..501d3ad --- /dev/null +++ b/Models/Inputs/ToInvoiceInput.cs @@ -0,0 +1,85 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ToInvoiceInput + /// + public class ToInvoiceInput : Dictionary + { + /// + /// Crea ToInvoiceInput. + /// + /// Lista de keys de recibos que se incluirán en la factura. Requerido. + public ToInvoiceInput(List @keys) + { + this["keys"] = @keys; + } + + /// + /// Lista de keys de recibos que se incluirán en la factura. + /// Requerido. + /// + [JsonIgnore] + public new List Keys + { + get => TryGetValue("keys", out var value) ? (List)value! : default!; + set => this["keys"] = value; + } + + /// + /// Cliente receptor de la factura. Si lo envías, sobrescribe el cliente + /// asignado a los recibos incluidos. Si lo omites, todos los recibos deben + /// tener asignado el mismo cliente. Esta regla también aplica cuando + /// `dry_run` es `true`. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// Código de Uso CFDI según catálogo del SAT. + /// Opcional. + /// + [JsonIgnore] + public string? Use + { + get => TryGetValue("use", out var value) ? (string?)value! : default!; + set => this["use"] = value; + } + + /// + /// Si es `true`, sólo valida y regresa un resumen sin crear la factura. + /// Opcional. + /// + [JsonIgnore] + public bool? DryRun + { + get => TryGetValue("dry_run", out var value) ? (bool?)value! : default!; + set => this["dry_run"] = value; + } + + /// + /// Código de forma de pago según el [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? PaymentForm + { + get => TryGetValue("payment_form", out var value) ? (string?)value! : default!; + set => this["payment_form"] = value; + } + + } +} diff --git a/Models/Inputs/ToInvoicePreviewInput.cs b/Models/Inputs/ToInvoicePreviewInput.cs new file mode 100644 index 0000000..3fbb1d3 --- /dev/null +++ b/Models/Inputs/ToInvoicePreviewInput.cs @@ -0,0 +1,60 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ToInvoicePreviewInput + /// + public class ToInvoicePreviewInput : Dictionary + { + /// + /// Crea ToInvoicePreviewInput. + /// + /// Lista de keys de recibos que se incluirán en la vista previa. Requerido. + public ToInvoicePreviewInput(List @keys) + { + this["keys"] = @keys; + } + + /// + /// Lista de keys de recibos que se incluirán en la vista previa. + /// Requerido. + /// + [JsonIgnore] + public new List Keys + { + get => TryGetValue("keys", out var value) ? (List)value! : default!; + set => this["keys"] = value; + } + + /// + /// Cliente opcional para renderizar la vista previa. Si lo omites, + /// todos los recibos deben tener asignado el mismo cliente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// Código de Uso CFDI según catálogo del SAT. + /// Opcional. + /// + [JsonIgnore] + public string? Use + { + get => TryGetValue("use", out var value) ? (string?)value! : default!; + set => this["use"] = value; + } + + } +} diff --git a/Models/Inputs/ToolValidateTaxIdParams.cs b/Models/Inputs/ToolValidateTaxIdParams.cs new file mode 100644 index 0000000..53b2685 --- /dev/null +++ b/Models/Inputs/ToolValidateTaxIdParams.cs @@ -0,0 +1,37 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ToolValidateTaxIdParams + /// + public class ToolValidateTaxIdParams : Dictionary + { + /// + /// Crea ToolValidateTaxIdParams. + /// + /// tax_id Requerido. + public ToolValidateTaxIdParams(string @taxId) + { + this["tax_id"] = @taxId; + } + + /// + /// tax_id + /// Requerido. + /// + [JsonIgnore] + public string TaxId + { + get => TryGetValue("tax_id", out var value) ? (string)value! : default!; + set => this["tax_id"] = value; + } + + } +} diff --git a/Models/Inputs/UpdateDraftInvoiceInput.cs b/Models/Inputs/UpdateDraftInvoiceInput.cs new file mode 100644 index 0000000..645bc23 --- /dev/null +++ b/Models/Inputs/UpdateDraftInvoiceInput.cs @@ -0,0 +1,360 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// UpdateDraftInvoiceInput + /// + public class UpdateDraftInvoiceInput : Dictionary + { + /// + /// Crea UpdateDraftInvoiceInput. + /// + public UpdateDraftInvoiceInput() + { + this["status"] = "draft"; + } + + /// + /// Tipo de comprobante de esta variante de entrada. + /// Valores: "I", "E", "P", "N", "T". + /// Opcional. + /// + [JsonIgnore] + public string? Type + { + get => TryGetValue("type", out var value) ? (string?)value! : default!; + set => this["type"] = value; + } + + /// + /// Conceptos a incluir en la factura. + /// + /// El número máximo de elementos que puedes incluir en una factura es de 5,000. Si necesitas + /// emitir una factura con más de 5,000 conceptos, puedes dividir la transacción en varias facturas. + /// Conceptos a incluir en la nota de crédito. + /// + /// El número máximo de elementos que puedes incluir en el comprobante es de 5,000. Si necesitas + /// emitir un comprobante con más de 5,000 conceptos, puedes dividir la transacción en varios comprobantes. + /// Conceptos a incluir en el comprobante de Traslado. + /// + /// El número máximo de elementos que puedes incluir en un comprobante es de 5,000. Si necesitas + /// emitir un comprobante con más de 5,000 conceptos, puedes dividir la transacción en varios comprobantes. + /// Opcional. + /// + [JsonIgnore] + public List>? Items + { + get => TryGetValue("items", out var value) ? (List>?)value! : default!; + set => this["items"] = value; + } + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? PaymentForm + { + get => TryGetValue("payment_form", out var value) ? (string?)value! : default!; + set => this["payment_form"] = value; + } + + /// + /// Código del método de pago según el catálogo del SAT. + /// + /// - `PUE`: Pago en Una sola Exhibición + /// - `PPD`: Pago en Parcialidades o Diferido + /// Código del método de pago según el catálogo del SAT. Para facturas de Egreso, + /// este campo es opcional y el único valor permitido es `PUE` (Pago en Una sola Exhibición). + /// Valores: "PUE", "PPD". + /// Opcional. + /// + [JsonIgnore] + public string? PaymentMethod + { + get => TryGetValue("payment_method", out var value) ? (string?)value! : default!; + set => this["payment_method"] = value; + } + + /// + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos + /// en [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en + /// nuestras librerías. + /// + /// Para factura global debe ingresarse la clave `S01`. + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos en [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en nuestras librerías. + /// Código de Uso CFDI según el catálogo del SAT. Puedes ver los códigos en + /// [esta tabla](https://docs.facturapi.io/api/#uso-cfdi), o utilizar las constantes incluidas en nuestras librerías. + /// Opcional. + /// Admite null. + /// + [JsonIgnore] + public string? Use + { + get => TryGetValue("use", out var value) ? (string?)value! : default!; + set => this["use"] = value; + } + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonIgnore] + public string? Currency + { + get => TryGetValue("currency", out var value) ? (string?)value! : default!; + set => this["currency"] = value; + } + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos + /// mexicanos (MXN) que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos (MXN) que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos + /// (MXN) que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Opcional. + /// + [JsonIgnore] + public decimal? Exchange + { + get => TryGetValue("exchange", out var value) ? (decimal?)value! : default!; + set => this["exchange"] = value; + } + + /// + /// Condiciones de pago + /// Opcional. + /// + [JsonIgnore] + public string? Conditions + { + get => TryGetValue("conditions", out var value) ? (string?)value! : default!; + set => this["conditions"] = value; + } + + /// + /// Documentos relacionados con la factura. + /// Documentos relacionados con la nota de crédito. + /// Documentos relacionados con el comprobante. + /// Opcional. + /// + [JsonIgnore] + public List? RelatedDocuments + { + get => TryGetValue("related_documents", out var value) ? (List?)value! : default!; + set => this["related_documents"] = value; + } + + /// + /// Información del periodo que abarca una factura global. En una factura de ingreso, este objeto es obligatorio cuando el receptor tiene `tax_id=XAXX010101000` y `legal_name=PUBLICO EN GENERAL`. Incluye periodicity, months y year. + /// Opcional. + /// + [JsonIgnore] + public InvoiceCreateInputGlobal? Global + { + get => TryGetValue("global", out var value) ? (InvoiceCreateInputGlobal?)value! : default!; + set => this["global"] = value; + } + + /// + /// Indica si el comprobante ampara una operación de exportación. + /// + /// - `01`: No aplica + /// - `02`: Definitiva con clave A1 + /// - `03`: Temporal + /// - `04`: Definitiva con clave distinta a A1 o cuando no existe enajenación en términos del CFF + /// Valores: "01", "04", "02", "03". + /// Opcional. + /// + [JsonIgnore] + public string? Export + { + get => TryGetValue("export", out var value) ? (string?)value! : default!; + set => this["export"] = value; + } + + /// + /// Complementos a incluir en la factura. Puedes incluir cualquier complemento en la + /// factura si tú mismo construyes el nodo XML del complemento y usas el tipo `custom`. + /// Es necesario agregar la información del complemento al PDF por separado usando el + /// parámetro `pdf_custom_section`. + /// Complementos a incluir en el comprobante. Puedes incluir cualquier + /// complemento en el comprobante si tú mismo construyes el nodo XML del + /// complemento y usas el tipo `custom`. Es necesario agregar la información + /// del complemento al PDF por separado usando el parámetro `pdf_custom_section`. + /// Complementos a incluir en la factura. + /// Complementos a incluir en el comprobante. Puedes incluir cualquier complemento en + /// el comprobante si tú mismo construyes el nodo XML del complemento y usas el tipo + /// `custom`. Es necesario agregar la información del complemento al PDF por separado + /// usando el parámetro `pdf_custom_section`. + /// Opcional. + /// + [JsonIgnore] + public List? Complements + { + get => TryGetValue("complements", out var value) ? (List?)value! : default!; + set => this["complements"] = value; + } + + /// + /// Estado de la factura. El valor `draft` identifica un borrador que no se ha timbrado ni enviado al SAT. + /// Sólo es posible editar facturas con este estado; al editarlas, no se puede cambiar `status`. + /// Valores: "draft". + /// Opcional. + /// + [JsonIgnore] + public string? Status + { + get => TryGetValue("status", out var value) ? (string?)value! : default!; + set => this["status"] = value; + } + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). No puede ser anterior a 72 horas en el pasado, ni posterior al presente. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Date + { + get => TryGetValue("date", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["date"] = value?.Value; + } + + /// + /// address + /// Opcional. + /// + [JsonIgnore] + public InvoiceCommonEditInputAddress? Address + { + get => TryGetValue("address", out var value) ? (InvoiceCommonEditInputAddress?)value! : default!; + set => this["address"] = value; + } + + /// + /// Identificador opcional que puedes usar para relacionar esta factura con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonIgnore] + public string? ExternalId + { + get => TryGetValue("external_id", out var value) ? (string?)value! : default!; + set => this["external_id"] = value; + } + + /// + /// Clave que identifica una operación para evitar recursos duplicados al repetir o enviar solicitudes en paralelo. Debe ser única dentro de la misma organización, ambiente y tipo de recurso. + /// Si otra solicitud está procesando la clave o si ya está asociada a un recurso, la API responde HTTP `409` con `code: idempotency_key_in_use`; no reproduce la respuesta original. + /// Si se deja en blanco, no se toma en cuenta. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonIgnore] + public string? IdempotencyKey + { + get => TryGetValue("idempotency_key", out var value) ? (string?)value! : default!; + set => this["idempotency_key"] = value; + } + + /// + /// Número de folio asignado por la empresa para control interno. Si se omite, se asignará el valor autoincremental de la organización. + /// Opcional. + /// + [JsonIgnore] + public int? FolioNumber + { + get => TryGetValue("folio_number", out var value) ? (int?)value! : default!; + set => this["folio_number"] = value; + } + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonIgnore] + public string? Series + { + get => TryGetValue("series", out var value) ? (string?)value! : default!; + set => this["series"] = value; + } + + /// + /// Format: xml + /// En caso de que necesites incluir más información en el PDF, este campo te permite enviar código HTML con tu propio contenido. + /// + /// Por seguridad, el código que puedes enviar está limitado a las siguientes etiquetas: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `div`, `p`, `span`, `small`, `br`, `b`, `i`, `ul`, `ol`, `li`, `strong`, `table`, `thead`, `tbody`, `tfoot`, `tr`, `th` y `td`. No se permiten atributos ni estilos. + /// Opcional. + /// + [JsonIgnore] + public string? PdfCustomSection + { + get => TryGetValue("pdf_custom_section", out var value) ? (string?)value! : default!; + set => this["pdf_custom_section"] = value; + } + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonIgnore] + public string? Addenda + { + get => TryGetValue("addenda", out var value) ? (string?)value! : default!; + set => this["addenda"] = value; + } + + /// + /// Si incluiste el parámetro `complements`, este campo es opcional; en cambio si incluiste el parámetro `addenda`, debes enviar la información necesaria para incluir estos namespaces en el documento XML. + /// Opcional. + /// + [JsonIgnore] + public List? Namespaces + { + get => TryGetValue("namespaces", out var value) ? (List?)value! : default!; + set => this["namespaces"] = value; + } + + /// + /// Configura qué campos opcionales se quieren mostrar en el PDF. El SAT no obliga a mostrar estos campos, pero pueden activarse según la preferencia del cliente para la factura en curso. Utiliza este campo para peticiones de generación de facturas en las cuales necesites utilizar una configuración distinta al campo pdf_extra de la organización. + /// Opcional. + /// + [JsonIgnore] + public InvoiceableCommonEditInputPdfOptions? PdfOptions + { + get => TryGetValue("pdf_options", out var value) ? (InvoiceableCommonEditInputPdfOptions?)value! : default!; + set => this["pdf_options"] = value; + } + + /// + /// Cliente receptor de la factura. + /// Opcional. + /// + [JsonIgnore] + public OneOf? Customer + { + get => TryGetValue("customer", out var value) && value != null ? OneOf.FromValue(value) : default(OneOf?); + set => this["customer"] = value?.Value; + } + + /// + /// third_party + /// Opcional. + /// + [JsonIgnore] + public InvoiceItemInputThirdParty? ThirdParty + { + get => TryGetValue("third_party", out var value) ? (InvoiceItemInputThirdParty?)value! : default!; + set => this["third_party"] = value; + } + + } +} diff --git a/Models/Inputs/ValidateWebhookSignatureInput.cs b/Models/Inputs/ValidateWebhookSignatureInput.cs new file mode 100644 index 0000000..93ccd5a --- /dev/null +++ b/Models/Inputs/ValidateWebhookSignatureInput.cs @@ -0,0 +1,63 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ValidateWebhookSignatureInput + /// + public class ValidateWebhookSignatureInput : Dictionary + { + /// + /// Crea ValidateWebhookSignatureInput. + /// + /// Llave secreta del webhook. Se obtiene al crear un webhook o desde el dashboard de Facturapi. Requerido. + /// Payload firmado. Prefiere el texto JSON original, conservando exactamente los bytes recibidos. También se aceptan objetos, pero la verificación utiliza su serialización JSON. Requerido. + /// Firma del webhook recibida en el header `Facturapi-Signature` Requerido. + public ValidateWebhookSignatureInput(string @secret, OneOf> @payload, string @signature) + { + this["secret"] = @secret; + this["payload"] = @payload.Value; + this["signature"] = @signature; + } + + /// + /// Llave secreta del webhook. Se obtiene al crear un webhook o desde el dashboard de Facturapi. + /// Requerido. + /// + [JsonIgnore] + public string Secret + { + get => TryGetValue("secret", out var value) ? (string)value! : default!; + set => this["secret"] = value; + } + + /// + /// Payload firmado. Prefiere el texto JSON original, conservando exactamente los bytes recibidos. También se aceptan objetos, pero la verificación utiliza su serialización JSON. + /// Requerido. + /// + [JsonIgnore] + public OneOf> Payload + { + get => TryGetValue("payload", out var value) ? OneOf>.FromValue(value) : default!; + set => this["payload"] = value.Value; + } + + /// + /// Firma del webhook recibida en el header `Facturapi-Signature` + /// Requerido. + /// + [JsonIgnore] + public string Signature + { + get => TryGetValue("signature", out var value) ? (string)value! : default!; + set => this["signature"] = value; + } + + } +} diff --git a/Models/Inputs/WebhookCreateInput.cs b/Models/Inputs/WebhookCreateInput.cs new file mode 100644 index 0000000..f7bc89a --- /dev/null +++ b/Models/Inputs/WebhookCreateInput.cs @@ -0,0 +1,51 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Webhook + /// + public class WebhookCreateInput : Dictionary + { + /// + /// Crea WebhookCreateInput. + /// + /// Format: uri URL del webhook a dar de alta para recibir notificaciones. Requerido. + /// Los eventos a los que el webhook se suscribirá. Requerido. + public WebhookCreateInput(string @url, List @enabledEvents) + { + this["url"] = @url; + this["enabled_events"] = @enabledEvents; + } + + /// + /// Format: uri + /// URL del webhook a dar de alta para recibir notificaciones. + /// Requerido. + /// + [JsonIgnore] + public string Url + { + get => TryGetValue("url", out var value) ? (string)value! : default!; + set => this["url"] = value; + } + + /// + /// Los eventos a los que el webhook se suscribirá. + /// Requerido. + /// + [JsonIgnore] + public List EnabledEvents + { + get => TryGetValue("enabled_events", out var value) ? (List)value! : default!; + set => this["enabled_events"] = value; + } + + } +} diff --git a/Models/Inputs/WebhookListParams.cs b/Models/Inputs/WebhookListParams.cs new file mode 100644 index 0000000..6935340 --- /dev/null +++ b/Models/Inputs/WebhookListParams.cs @@ -0,0 +1,73 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// WebhookListParams + /// + public class WebhookListParams : Dictionary + { + /// + /// Modo de paginación de la búsqueda. `page` (por defecto) o `cursor` (recomendado para listas grandes). + /// Valores: "page", "cursor". + /// Opcional. + /// + [JsonIgnore] + public string? Pagination + { + get => TryGetValue("pagination", out var value) ? (string?)value! : default!; + set => this["pagination"] = value; + } + + /// + /// Devuelve los resultados posteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `before`. + /// Opcional. + /// + [JsonIgnore] + public string? After + { + get => TryGetValue("after", out var value) ? (string?)value! : default!; + set => this["after"] = value; + } + + /// + /// Devuelve los resultados anteriores al cursor indicado. Solo con `pagination=cursor`; mutuamente excluyente con `after`. + /// Opcional. + /// + [JsonIgnore] + public string? Before + { + get => TryGetValue("before", out var value) ? (string?)value! : default!; + set => this["before"] = value; + } + + /// + /// Página de resultados a regresar, empezando desde la página 1. El máximo no es fijo; junto con `limit` debe caber dentro del tope de 3,000 resultados (con el `limit` por defecto de 100, la página máxima es 30). + /// Opcional. + /// + [JsonIgnore] + public int? Page + { + get => TryGetValue("page", out var value) ? (int?)value! : default!; + set => this["page"] = value; + } + + /// + /// Número del 1 al 100 que representa la cantidad máxima de resultados a regresar con motivos de paginación. + /// Opcional. + /// + [JsonIgnore] + public int? Limit + { + get => TryGetValue("limit", out var value) ? (int?)value! : default!; + set => this["limit"] = value; + } + + } +} diff --git a/Models/Inputs/WebhookUpdateInput.cs b/Models/Inputs/WebhookUpdateInput.cs new file mode 100644 index 0000000..2c9afd8 --- /dev/null +++ b/Models/Inputs/WebhookUpdateInput.cs @@ -0,0 +1,51 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Webhook + /// + public class WebhookUpdateInput : Dictionary + { + /// + /// Crea WebhookUpdateInput. + /// + /// Estatus del webhook Valores: "enabled", "disabled". Requerido. + /// Los eventos a los que el webhook se suscribirá. Requerido. + public WebhookUpdateInput(string @status, List @enabledEvents) + { + this["status"] = @status; + this["enabled_events"] = @enabledEvents; + } + + /// + /// Estatus del webhook + /// Valores: "enabled", "disabled". + /// Requerido. + /// + [JsonIgnore] + public string Status + { + get => TryGetValue("status", out var value) ? (string)value! : default!; + set => this["status"] = value; + } + + /// + /// Los eventos a los que el webhook se suscribirá. + /// Requerido. + /// + [JsonIgnore] + public List EnabledEvents + { + get => TryGetValue("enabled_events", out var value) ? (List)value! : default!; + set => this["enabled_events"] = value; + } + + } +} diff --git a/Models/Invoice.cs b/Models/Invoice.cs index 0fe818f..c9807f7 100644 --- a/Models/Invoice.cs +++ b/Models/Invoice.cs @@ -1,45 +1,368 @@ -using System; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// Invoice + /// public class Invoice { - public string Id { get; set; } - public string ExternalId { get; set; } - public DateTime CreatedAt { get; set; } - public bool Livemode { get; set; } - public string Status { get; set; } - public string Type { get; set; } - public string VerificationUrl { get; set; } - public string CancellationStatus { get; set; } - public DateTime Date { get; set; } - public Address Address { get; set; } - public Customer Customer { get; set; } - public decimal Total { get; set; } - public string Uuid { get; set; } - public string FolioNumber { get; set; } - public string Series { get; set; } - public string Use { get; set; } - public string PaymentForm { get; set; } - public string PaymentMethod { get; set; } - public string Currecy { get; set; } - public decimal Exchange { get; set; } - public string CancellationReceipt { get; set; } - public List Related { get; set; } - public string Relation { get; set; } - public string Conditions { get; set; } - public List Items { get; set; } - public List Payments { get; set; } - public List Namespaces { get; set; } - public Stamp Stamp { get; set; } - public Global Global { get; set; } - } + /// + /// ID del objeto + /// Requerido. + /// + [JsonProperty("id")] + public string Id { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de registro + /// Requerido. + /// + [JsonProperty("created_at")] + public DateTime CreatedAt { get; set; } = default!; + + /// + /// Si el valor es `true`, indica que el objeto fue creado en ambiente Live; o si es `false`, en ambiente Test. + /// Requerido. + /// + [JsonProperty("livemode")] + public bool Livemode { get; set; } = default!; + + /// + /// Estado actual de la factura. `failed` indica que el timbrado en segundo plano o la recuperación automática del CFDI terminó sin éxito. + /// Valores: "valid", "canceled", "draft", "pending", "failed". + /// Requerido. + /// + [JsonProperty("status")] + public string Status { get; set; } = default!; + + /// + /// cancellation + /// Opcional. + /// + [JsonProperty("cancellation")] + public InvoiceCancellation? Cancellation { get; set; } = default!; + + /// + /// cancellation_status + /// Valores: "none", "accepted", "pending", "rejected", "expired", "verifying". + /// Requerido. + /// + [JsonProperty("cancellation_status")] + public string CancellationStatus { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha en la que se canceló el CFDI con hora aproximada. + /// Opcional. + /// Admite null. + /// + [JsonProperty("canceled_at")] + public DateTime? CanceledAt { get; set; } = default!; + + /// + /// Format: uri + /// Dirección URL para verificar el estado del CFDI en el portal del SAT. Este link es el mismo que aparece en el código QR, en el PDF de la factura. + /// Opcional. + /// + [JsonProperty("verification_url")] + public string? VerificationUrl { get; set; } = default!; + + /// + /// address + /// Opcional. + /// + [JsonProperty("address")] + public Address? Address { get; set; } = default!; + + /// + /// Tipo de comprobante. Puede tener los valores `"I"`: Ingreso, `"P"`: Pago, `"E"`: Egreso, `"N"`: Nómina, `"T"`: Traslado. + /// Valores: "E", "I", "T", "N", "P". + /// Requerido. + /// + [JsonProperty("type")] + public string Type { get; set; } = default!; + + /// + /// customer + /// Opcional. + /// Admite null. + /// + [JsonProperty("customer")] + public CustomerInfo? Customer { get; set; } = default!; + + /// + /// Monto total facturado. + /// Requerido. + /// + [JsonProperty("total")] + public decimal Total { get; set; } = default!; + + /// + /// Número de folio autoincremental para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonProperty("folio_number")] + public int? FolioNumber { get; set; } = default!; + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. En el PDF se imprime junto al número de folio. + /// Opcional. + /// + [JsonProperty("series")] + public string? Series { get; set; } = default!; + + /// + /// Identificador que puedes usar para relacionar esta factura con tus registros para después buscar por este número. + /// Opcional. + /// + [JsonProperty("external_id")] + public string? ExternalId { get; set; } = default!; + + /// + /// Clave que identifica una operación para evitar recursos duplicados. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonProperty("idempotency_key")] + public string? IdempotencyKey { get; set; } = default!; + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Opcional. + /// Admite null. + /// + [JsonProperty("payment_form")] + public string? PaymentForm { get; set; } = default!; + + /// + /// Total del complemento de Pago cuando la factura es tipo P. + /// Opcional. + /// + [JsonProperty("total_payment_amount")] + public decimal? TotalPaymentAmount { get; set; } = default!; + + /// + /// Total del monto pagado convertido de la moneda de pago a Pesos Mexicanos. + /// Opcional. + /// + [JsonProperty("total_payment_amount_converted")] + public decimal? TotalPaymentAmountConverted { get; set; } = default!; + + /// + /// Este campo es asignado automáticamente por Facturapi. Indica si una factura + /// con status `draft` está completa y lista para intentar timbrarse. Si el valor es `true`, puedes + /// intentar timbrar la factura con el método [Timbrar Factura]('#/operation/stampInvoice'). + /// Si el valor es `false`, debes usar el método [Actualizar Factura]('#/operation/updateDraftInvoice') + /// para completar los campos faltantes. + /// + /// En una factura con status diferente a `draft`, este campo siempre será `false`. + /// Opcional. + /// + [JsonProperty("is_ready_to_stamp")] + public bool? IsReadyToStamp { get; set; } = default!; + + /// + /// Conceptos incluidos en el comprobante + /// Requerido. + /// + [JsonProperty("items")] + public List Items { get; set; } = default!; + + /// + /// Documentos relacionados con la factura. + /// Opcional. + /// + [JsonProperty("related_documents")] + public List? RelatedDocuments { get; set; } = default!; + + /// + /// En facturas con tipo I (Ingreso) y método de pago PPD, este campo lista los + /// IDs de los comprobantes de pago cuyo arreglo de documentos relacionados incluye el UUID + /// de esta factura. Este campo es llenado por Facturapi en el momento en que se crea o importa + /// el comprobante de pago (tipo P), siempre y cuando pertenezca a la misma organización. + /// Opcional. + /// + [JsonProperty("received_payment_ids")] + public List? ReceivedPaymentIds { get; set; } = default!; + + /// + /// En facturas con tipo P (Pago), este arreglo lista los IDs de los comprobantes de ingreso + /// listados en el arreglo de documentos relacionados. Este campo es llenado por Facturapi siempre + /// y cuando el comprobante relacionado también esté registrado en Facturapi y pertenezca a la misma organización. + /// Opcional. + /// + [JsonProperty("target_invoice_ids")] + public List? TargetInvoiceIds { get; set; } = default!; + + /// + /// Al recuperar el detalle de un CFDI de ingreso o egreso, este arreglo contiene los IDs de los + /// CFDI del tipo opuesto relacionados mediante `related_documents`. Para un ingreso incluye los + /// egresos que referencian su UUID; para un egreso incluye los ingresos cuyos UUID están en sus + /// documentos relacionados. Solo incluye CFDI registrados en la misma organización y ambiente. + /// Opcional. + /// + [JsonProperty("related_invoice_ids")] + public List? RelatedInvoiceIds { get; set; } = default!; + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Requerido. + /// + [JsonProperty("currency")] + public string Currency { get; set; } = default!; + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Requerido. + /// + [JsonProperty("exchange")] + public decimal Exchange { get; set; } = default!; + + /// + /// Complementos a incluir en la factura. + /// Opcional. + /// + [JsonProperty("complements")] + public List? Complements { get; set; } = default!; + + /// + /// Format: html + /// En caso de que necesites incluir más información en el PDF, este campo te permite insertar código HTML con tu propio contenido. + /// Opcional. + /// + [JsonProperty("pdf_custom_section")] + public string? PdfCustomSection { get; set; } = default!; + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonProperty("addenda")] + public string? Addenda { get; set; } = default!; + + /// + /// Namespaces a insertar en el nodo raíz de la factura. Requerido en `addenda`. + /// Opcional. + /// + [JsonProperty("namespaces")] + public List? Namespaces { get; set; } = default!; + + /// + /// ID de la organización a la que pertenece este recurso. + /// Opcional. + /// Admite null. + /// + [JsonProperty("organization")] + public string? Organization { get; set; } = default!; + + /// + /// issuer_type + /// Valores: "issuing", "receiving". + /// Opcional. + /// + [JsonProperty("issuer_type")] + public string? IssuerType { get; set; } = default!; + + /// + /// cfdi_version + /// Opcional. + /// + [JsonProperty("cfdi_version")] + public decimal? CfdiVersion { get; set; } = default!; + + /// + /// issuer_info + /// Opcional. + /// + [JsonProperty("issuer_info")] + public CustomerInfo? IssuerInfo { get; set; } = default!; + + /// + /// payment_method + /// Valores: "PUE", "PPD". + /// Opcional. + /// Admite null. + /// + [JsonProperty("payment_method")] + public string? PaymentMethod { get; set; } = default!; + + /// + /// use + /// Opcional. + /// + [JsonProperty("use")] + public string? Use { get; set; } = default!; + + /// + /// amount_due + /// Requerido. + /// + [JsonProperty("amount_due")] + public decimal AmountDue { get; set; } = default!; + + /// + /// Format: uri + /// Opcional. + /// + [JsonProperty("verification_carta_porte")] + public string? VerificationCartaPorte { get; set; } = default!; + + /// + /// conditions + /// Opcional. + /// + [JsonProperty("conditions")] + public string? Conditions { get; set; } = default!; + + /// + /// export + /// Opcional. + /// + [JsonProperty("export")] + public string? Export { get; set; } = default!; + + /// + /// global + /// Opcional. + /// + [JsonProperty("global")] + public Global? Global { get; set; } = default!; + + /// + /// Format: date-time + /// Format: date-time + /// Fecha de expedición en formato ISO8601. Puede ser null en borradores. + /// Requerido. + /// Admite null. + /// + [JsonProperty("date")] + public DateTime? Date { get; set; } = default!; + + /// + /// Format: uuid + /// Format: uuid + /// Folio fiscal de la factura, asignado por el SAT. En borradores sin timbrar puede ser null o estar omitido. + /// Opcional. + /// Admite null. + /// + [JsonProperty("uuid")] + public string? Uuid { get; set; } = default!; + + /// + /// stamp + /// Opcional. + /// Admite null. + /// + [JsonProperty("stamp")] + public Stamp? Stamp { get; set; } = default!; - public class Namespace - { - public string Prefix { get; set; } - public string Uri { get; set; } - public string SchemaLocation { get; set; } } } diff --git a/Models/InvoiceCancellation.cs b/Models/InvoiceCancellation.cs new file mode 100644 index 0000000..4247551 --- /dev/null +++ b/Models/InvoiceCancellation.cs @@ -0,0 +1,64 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Información de la solicitud de cancelación de la factura. + /// + public class InvoiceCancellation + { + /// + /// status + /// Valores: "none", "accepted", "pending", "rejected", "expired", "verifying". + /// Requerido. + /// + [JsonProperty("status")] + public string Status { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha y hora en que se solicitó la cancelación, cuando aplica. + /// Opcional. + /// + [JsonProperty("requested_at")] + public DateTime? RequestedAt { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha y hora de inicio de la última consulta del estado de cancelación. Se omite si nunca se ha iniciado una consulta. No garantiza que la consulta haya terminado correctamente. + /// Opcional. + /// + [JsonProperty("last_checked")] + public DateTime? LastChecked { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha y hora en que se completó la cancelación, cuando aplica. + /// Opcional. + /// + [JsonProperty("canceled_at")] + public DateTime? CanceledAt { get; set; } = default!; + + /// + /// Código del motivo de cancelación del SAT, si se ha enviado una solicitud. + /// Opcional. + /// + [JsonProperty("motive")] + public string? Motive { get; set; } = default!; + + /// + /// Format: uuid + /// UUID de la factura sustituta, cuando aplica. + /// Opcional. + /// + [JsonProperty("substitutionUUID")] + public string? SubstitutionUUID { get; set; } = default!; + + } +} diff --git a/Models/InvoiceComplementProperties.cs b/Models/InvoiceComplementProperties.cs new file mode 100644 index 0000000..5396898 --- /dev/null +++ b/Models/InvoiceComplementProperties.cs @@ -0,0 +1,32 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceComplementProperties + /// + public class InvoiceComplementProperties + { + /// + /// Tipo de complemento. + /// Valores: "custom", "pago", "nomina", "carta_porte", "comercio_exterior", "leyendas_fiscales". + /// Requerido. + /// + [JsonProperty("type")] + public string Type { get; set; } = default!; + + /// + /// data + /// Opcional. + /// + [JsonProperty("data")] + public OneOf, NominaComplementDataProperties, CartaPorteDataProperties, ComercioExteriorDataProperties, LeyendasFiscalesData>? Data { get; set; } = default!; + + } +} diff --git a/Models/InvoiceDraft.cs b/Models/InvoiceDraft.cs new file mode 100644 index 0000000..c9dc132 --- /dev/null +++ b/Models/InvoiceDraft.cs @@ -0,0 +1,365 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Objeto Invoice con status draft + /// + public class InvoiceDraft + { + /// + /// ID del objeto + /// Requerido. + /// + [JsonProperty("id")] + public string Id { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de registro + /// Requerido. + /// + [JsonProperty("created_at")] + public DateTime CreatedAt { get; set; } = default!; + + /// + /// Si el valor es `true`, indica que el objeto fue creado en ambiente Live; o si es `false`, en ambiente Test. + /// Requerido. + /// + [JsonProperty("livemode")] + public bool Livemode { get; set; } = default!; + + /// + /// Estado actual de la factura. `failed` indica que el timbrado en segundo plano o la recuperación automática del CFDI terminó sin éxito. + /// Valores: "draft". + /// Requerido. + /// + [JsonProperty("status")] + public string Status { get; set; } = default!; + + /// + /// cancellation + /// Opcional. + /// + [JsonProperty("cancellation")] + public InvoiceCancellation? Cancellation { get; set; } = default!; + + /// + /// cancellation_status + /// Valores: "none", "accepted", "pending", "rejected", "expired", "verifying". + /// Requerido. + /// + [JsonProperty("cancellation_status")] + public string CancellationStatus { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha en la que se canceló el CFDI con hora aproximada. + /// Opcional. + /// Admite null. + /// + [JsonProperty("canceled_at")] + public DateTime? CanceledAt { get; set; } = default!; + + /// + /// Format: uri + /// Dirección URL para verificar el estado del CFDI en el portal del SAT. Este link es el mismo que aparece en el código QR, en el PDF de la factura. + /// Opcional. + /// + [JsonProperty("verification_url")] + public string? VerificationUrl { get; set; } = default!; + + /// + /// address + /// Opcional. + /// + [JsonProperty("address")] + public Address? Address { get; set; } = default!; + + /// + /// Tipo de comprobante. Puede tener los valores `"I"`: Ingreso, `"P"`: Pago, `"E"`: Egreso, `"N"`: Nómina, `"T"`: Traslado. + /// Valores: "E", "I", "T", "N", "P". + /// Requerido. + /// + [JsonProperty("type")] + public string Type { get; set; } = default!; + + /// + /// customer + /// Opcional. + /// Admite null. + /// + [JsonProperty("customer")] + public CustomerInfo? Customer { get; set; } = default!; + + /// + /// Monto total facturado. + /// Requerido. + /// + [JsonProperty("total")] + public decimal Total { get; set; } = default!; + + /// + /// Número de folio autoincremental para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonProperty("folio_number")] + public int? FolioNumber { get; set; } = default!; + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. En el PDF se imprime junto al número de folio. + /// Opcional. + /// + [JsonProperty("series")] + public string? Series { get; set; } = default!; + + /// + /// Identificador que puedes usar para relacionar esta factura con tus registros para después buscar por este número. + /// Opcional. + /// + [JsonProperty("external_id")] + public string? ExternalId { get; set; } = default!; + + /// + /// Clave que identifica una operación para evitar recursos duplicados. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonProperty("idempotency_key")] + public string? IdempotencyKey { get; set; } = default!; + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Opcional. + /// Admite null. + /// + [JsonProperty("payment_form")] + public string? PaymentForm { get; set; } = default!; + + /// + /// Total del complemento de Pago cuando la factura es tipo P. + /// Opcional. + /// + [JsonProperty("total_payment_amount")] + public decimal? TotalPaymentAmount { get; set; } = default!; + + /// + /// Total del monto pagado convertido de la moneda de pago a Pesos Mexicanos. + /// Opcional. + /// + [JsonProperty("total_payment_amount_converted")] + public decimal? TotalPaymentAmountConverted { get; set; } = default!; + + /// + /// Este campo es asignado automáticamente por Facturapi. Indica si una factura + /// con status `draft` está completa y lista para intentar timbrarse. Si el valor es `true`, puedes + /// intentar timbrar la factura con el método [Timbrar Factura]('#/operation/stampInvoice'). + /// Si el valor es `false`, debes usar el método [Actualizar Factura]('#/operation/updateDraftInvoice') + /// para completar los campos faltantes. + /// + /// En una factura con status diferente a `draft`, este campo siempre será `false`. + /// Opcional. + /// + [JsonProperty("is_ready_to_stamp")] + public bool? IsReadyToStamp { get; set; } = default!; + + /// + /// Conceptos incluidos en el comprobante + /// Requerido. + /// + [JsonProperty("items")] + public List Items { get; set; } = default!; + + /// + /// Documentos relacionados con la factura. + /// Opcional. + /// + [JsonProperty("related_documents")] + public List? RelatedDocuments { get; set; } = default!; + + /// + /// En facturas con tipo I (Ingreso) y método de pago PPD, este campo lista los + /// IDs de los comprobantes de pago cuyo arreglo de documentos relacionados incluye el UUID + /// de esta factura. Este campo es llenado por Facturapi en el momento en que se crea o importa + /// el comprobante de pago (tipo P), siempre y cuando pertenezca a la misma organización. + /// Opcional. + /// + [JsonProperty("received_payment_ids")] + public List? ReceivedPaymentIds { get; set; } = default!; + + /// + /// En facturas con tipo P (Pago), este arreglo lista los IDs de los comprobantes de ingreso + /// listados en el arreglo de documentos relacionados. Este campo es llenado por Facturapi siempre + /// y cuando el comprobante relacionado también esté registrado en Facturapi y pertenezca a la misma organización. + /// Opcional. + /// + [JsonProperty("target_invoice_ids")] + public List? TargetInvoiceIds { get; set; } = default!; + + /// + /// Al recuperar el detalle de un CFDI de ingreso o egreso, este arreglo contiene los IDs de los + /// CFDI del tipo opuesto relacionados mediante `related_documents`. Para un ingreso incluye los + /// egresos que referencian su UUID; para un egreso incluye los ingresos cuyos UUID están en sus + /// documentos relacionados. Solo incluye CFDI registrados en la misma organización y ambiente. + /// Opcional. + /// + [JsonProperty("related_invoice_ids")] + public List? RelatedInvoiceIds { get; set; } = default!; + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Requerido. + /// + [JsonProperty("currency")] + public string Currency { get; set; } = default!; + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Requerido. + /// + [JsonProperty("exchange")] + public decimal Exchange { get; set; } = default!; + + /// + /// Complementos a incluir en la factura. + /// Opcional. + /// + [JsonProperty("complements")] + public List? Complements { get; set; } = default!; + + /// + /// Format: html + /// En caso de que necesites incluir más información en el PDF, este campo te permite insertar código HTML con tu propio contenido. + /// Opcional. + /// + [JsonProperty("pdf_custom_section")] + public string? PdfCustomSection { get; set; } = default!; + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonProperty("addenda")] + public string? Addenda { get; set; } = default!; + + /// + /// Namespaces a insertar en el nodo raíz de la factura. Requerido en `addenda`. + /// Opcional. + /// + [JsonProperty("namespaces")] + public List? Namespaces { get; set; } = default!; + + /// + /// ID de la organización a la que pertenece este recurso. + /// Opcional. + /// Admite null. + /// + [JsonProperty("organization")] + public string? Organization { get; set; } = default!; + + /// + /// issuer_type + /// Valores: "issuing", "receiving". + /// Opcional. + /// + [JsonProperty("issuer_type")] + public string? IssuerType { get; set; } = default!; + + /// + /// cfdi_version + /// Opcional. + /// + [JsonProperty("cfdi_version")] + public decimal? CfdiVersion { get; set; } = default!; + + /// + /// issuer_info + /// Opcional. + /// + [JsonProperty("issuer_info")] + public CustomerInfo? IssuerInfo { get; set; } = default!; + + /// + /// payment_method + /// Valores: "PUE", "PPD". + /// Opcional. + /// Admite null. + /// + [JsonProperty("payment_method")] + public string? PaymentMethod { get; set; } = default!; + + /// + /// use + /// Opcional. + /// + [JsonProperty("use")] + public string? Use { get; set; } = default!; + + /// + /// amount_due + /// Requerido. + /// + [JsonProperty("amount_due")] + public decimal AmountDue { get; set; } = default!; + + /// + /// Format: uri + /// Opcional. + /// + [JsonProperty("verification_carta_porte")] + public string? VerificationCartaPorte { get; set; } = default!; + + /// + /// conditions + /// Opcional. + /// + [JsonProperty("conditions")] + public string? Conditions { get; set; } = default!; + + /// + /// export + /// Opcional. + /// + [JsonProperty("export")] + public string? Export { get; set; } = default!; + + /// + /// global + /// Opcional. + /// + [JsonProperty("global")] + public Global? Global { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de expedición en formato ISO8601. Puede ser null en borradores. + /// Requerido. + /// Admite null. + /// + [JsonProperty("date")] + public DateTime? Date { get; set; } = default!; + + /// + /// uuid + /// Opcional. + /// Admite null. + /// + [JsonProperty("uuid")] + public object? Uuid { get; set; } = default!; + + /// + /// stamp + /// Opcional. + /// Admite null. + /// + [JsonProperty("stamp")] + public object? Stamp { get; set; } = default!; + + } +} diff --git a/Models/InvoiceFailed.cs b/Models/InvoiceFailed.cs new file mode 100644 index 0000000..46588c0 --- /dev/null +++ b/Models/InvoiceFailed.cs @@ -0,0 +1,366 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Fallida + /// + public class InvoiceFailed + { + /// + /// ID del objeto + /// Requerido. + /// + [JsonProperty("id")] + public string Id { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de registro + /// Requerido. + /// + [JsonProperty("created_at")] + public DateTime CreatedAt { get; set; } = default!; + + /// + /// Si el valor es `true`, indica que el objeto fue creado en ambiente Live; o si es `false`, en ambiente Test. + /// Requerido. + /// + [JsonProperty("livemode")] + public bool Livemode { get; set; } = default!; + + /// + /// Estado actual de la factura. `failed` indica que el timbrado en segundo plano o la recuperación automática del CFDI terminó sin éxito. + /// Valores: "failed". + /// Requerido. + /// + [JsonProperty("status")] + public string Status { get; set; } = default!; + + /// + /// cancellation + /// Opcional. + /// + [JsonProperty("cancellation")] + public InvoiceCancellation? Cancellation { get; set; } = default!; + + /// + /// cancellation_status + /// Valores: "none", "accepted", "pending", "rejected", "expired", "verifying". + /// Requerido. + /// + [JsonProperty("cancellation_status")] + public string CancellationStatus { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha en la que se canceló el CFDI con hora aproximada. + /// Opcional. + /// Admite null. + /// + [JsonProperty("canceled_at")] + public DateTime? CanceledAt { get; set; } = default!; + + /// + /// Format: uri + /// Dirección URL para verificar el estado del CFDI en el portal del SAT. Este link es el mismo que aparece en el código QR, en el PDF de la factura. + /// Opcional. + /// + [JsonProperty("verification_url")] + public string? VerificationUrl { get; set; } = default!; + + /// + /// address + /// Opcional. + /// + [JsonProperty("address")] + public Address? Address { get; set; } = default!; + + /// + /// Tipo de comprobante. Puede tener los valores `"I"`: Ingreso, `"P"`: Pago, `"E"`: Egreso, `"N"`: Nómina, `"T"`: Traslado. + /// Valores: "E", "I", "T", "N", "P". + /// Requerido. + /// + [JsonProperty("type")] + public string Type { get; set; } = default!; + + /// + /// customer + /// Opcional. + /// Admite null. + /// + [JsonProperty("customer")] + public CustomerInfo? Customer { get; set; } = default!; + + /// + /// Monto total facturado. + /// Requerido. + /// + [JsonProperty("total")] + public decimal Total { get; set; } = default!; + + /// + /// Número de folio autoincremental para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonProperty("folio_number")] + public int? FolioNumber { get; set; } = default!; + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. En el PDF se imprime junto al número de folio. + /// Opcional. + /// + [JsonProperty("series")] + public string? Series { get; set; } = default!; + + /// + /// Identificador que puedes usar para relacionar esta factura con tus registros para después buscar por este número. + /// Opcional. + /// + [JsonProperty("external_id")] + public string? ExternalId { get; set; } = default!; + + /// + /// Clave que identifica una operación para evitar recursos duplicados. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonProperty("idempotency_key")] + public string? IdempotencyKey { get; set; } = default!; + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Opcional. + /// Admite null. + /// + [JsonProperty("payment_form")] + public string? PaymentForm { get; set; } = default!; + + /// + /// Total del complemento de Pago cuando la factura es tipo P. + /// Opcional. + /// + [JsonProperty("total_payment_amount")] + public decimal? TotalPaymentAmount { get; set; } = default!; + + /// + /// Total del monto pagado convertido de la moneda de pago a Pesos Mexicanos. + /// Opcional. + /// + [JsonProperty("total_payment_amount_converted")] + public decimal? TotalPaymentAmountConverted { get; set; } = default!; + + /// + /// Este campo es asignado automáticamente por Facturapi. Indica si una factura + /// con status `draft` está completa y lista para intentar timbrarse. Si el valor es `true`, puedes + /// intentar timbrar la factura con el método [Timbrar Factura]('#/operation/stampInvoice'). + /// Si el valor es `false`, debes usar el método [Actualizar Factura]('#/operation/updateDraftInvoice') + /// para completar los campos faltantes. + /// + /// En una factura con status diferente a `draft`, este campo siempre será `false`. + /// Opcional. + /// + [JsonProperty("is_ready_to_stamp")] + public bool? IsReadyToStamp { get; set; } = default!; + + /// + /// Conceptos incluidos en el comprobante + /// Requerido. + /// + [JsonProperty("items")] + public List Items { get; set; } = default!; + + /// + /// Documentos relacionados con la factura. + /// Opcional. + /// + [JsonProperty("related_documents")] + public List? RelatedDocuments { get; set; } = default!; + + /// + /// En facturas con tipo I (Ingreso) y método de pago PPD, este campo lista los + /// IDs de los comprobantes de pago cuyo arreglo de documentos relacionados incluye el UUID + /// de esta factura. Este campo es llenado por Facturapi en el momento en que se crea o importa + /// el comprobante de pago (tipo P), siempre y cuando pertenezca a la misma organización. + /// Opcional. + /// + [JsonProperty("received_payment_ids")] + public List? ReceivedPaymentIds { get; set; } = default!; + + /// + /// En facturas con tipo P (Pago), este arreglo lista los IDs de los comprobantes de ingreso + /// listados en el arreglo de documentos relacionados. Este campo es llenado por Facturapi siempre + /// y cuando el comprobante relacionado también esté registrado en Facturapi y pertenezca a la misma organización. + /// Opcional. + /// + [JsonProperty("target_invoice_ids")] + public List? TargetInvoiceIds { get; set; } = default!; + + /// + /// Al recuperar el detalle de un CFDI de ingreso o egreso, este arreglo contiene los IDs de los + /// CFDI del tipo opuesto relacionados mediante `related_documents`. Para un ingreso incluye los + /// egresos que referencian su UUID; para un egreso incluye los ingresos cuyos UUID están en sus + /// documentos relacionados. Solo incluye CFDI registrados en la misma organización y ambiente. + /// Opcional. + /// + [JsonProperty("related_invoice_ids")] + public List? RelatedInvoiceIds { get; set; } = default!; + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Requerido. + /// + [JsonProperty("currency")] + public string Currency { get; set; } = default!; + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Requerido. + /// + [JsonProperty("exchange")] + public decimal Exchange { get; set; } = default!; + + /// + /// Complementos a incluir en la factura. + /// Opcional. + /// + [JsonProperty("complements")] + public List? Complements { get; set; } = default!; + + /// + /// Format: html + /// En caso de que necesites incluir más información en el PDF, este campo te permite insertar código HTML con tu propio contenido. + /// Opcional. + /// + [JsonProperty("pdf_custom_section")] + public string? PdfCustomSection { get; set; } = default!; + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonProperty("addenda")] + public string? Addenda { get; set; } = default!; + + /// + /// Namespaces a insertar en el nodo raíz de la factura. Requerido en `addenda`. + /// Opcional. + /// + [JsonProperty("namespaces")] + public List? Namespaces { get; set; } = default!; + + /// + /// ID de la organización a la que pertenece este recurso. + /// Opcional. + /// Admite null. + /// + [JsonProperty("organization")] + public string? Organization { get; set; } = default!; + + /// + /// issuer_type + /// Valores: "issuing", "receiving". + /// Opcional. + /// + [JsonProperty("issuer_type")] + public string? IssuerType { get; set; } = default!; + + /// + /// cfdi_version + /// Opcional. + /// + [JsonProperty("cfdi_version")] + public decimal? CfdiVersion { get; set; } = default!; + + /// + /// issuer_info + /// Opcional. + /// + [JsonProperty("issuer_info")] + public CustomerInfo? IssuerInfo { get; set; } = default!; + + /// + /// payment_method + /// Valores: "PUE", "PPD". + /// Opcional. + /// Admite null. + /// + [JsonProperty("payment_method")] + public string? PaymentMethod { get; set; } = default!; + + /// + /// use + /// Opcional. + /// + [JsonProperty("use")] + public string? Use { get; set; } = default!; + + /// + /// amount_due + /// Requerido. + /// + [JsonProperty("amount_due")] + public decimal AmountDue { get; set; } = default!; + + /// + /// Format: uri + /// Opcional. + /// + [JsonProperty("verification_carta_porte")] + public string? VerificationCartaPorte { get; set; } = default!; + + /// + /// conditions + /// Opcional. + /// + [JsonProperty("conditions")] + public string? Conditions { get; set; } = default!; + + /// + /// export + /// Opcional. + /// + [JsonProperty("export")] + public string? Export { get; set; } = default!; + + /// + /// global + /// Opcional. + /// + [JsonProperty("global")] + public Global? Global { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de expedición en formato ISO8601. Puede ser null en borradores. + /// Requerido. + /// Admite null. + /// + [JsonProperty("date")] + public DateTime? Date { get; set; } = default!; + + /// + /// Format: uuid + /// Folio fiscal de la factura, asignado por el SAT. En borradores sin timbrar puede ser null o estar omitido. + /// Opcional. + /// Admite null. + /// + [JsonProperty("uuid")] + public string? Uuid { get; set; } = default!; + + /// + /// stamp + /// Opcional. + /// Admite null. + /// + [JsonProperty("stamp")] + public Stamp? Stamp { get; set; } = default!; + + } +} diff --git a/Models/InvoiceItem.cs b/Models/InvoiceItem.cs index 0f048b6..7aa1201 100644 --- a/Models/InvoiceItem.cs +++ b/Models/InvoiceItem.cs @@ -1,15 +1,73 @@ -using System; - +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// InvoiceItem + /// public class InvoiceItem { - public Decimal Quantity { get; set; } - public Decimal Discount { get; set; } - public string Description { get; set; } - public Product Product { get; set; } - public List PropertyTaxAccount { get; set; } + /// + /// Cuentas prediales de este concepto. + /// Opcional. + /// + [JsonProperty("property_tax_account")] + public List? PropertyTaxAccount { get; set; } = default!; + + /// + /// Cantidad de unidades incluidas del mismo concepto. + /// Requerido. + /// + [JsonProperty("quantity")] + public decimal Quantity { get; set; } = default!; + + /// + /// Monto total de descuento aplicado a este concepto. + /// Requerido. + /// + [JsonProperty("discount")] + public decimal Discount { get; set; } = default!; + + /// + /// Objeto con información del producto o servicio facturado. + /// Requerido. + /// + [JsonProperty("product")] + public ProductInfo Product { get; set; } = default!; + + /// + /// Números de pedimento asociados a este concepto. Se omite cuando no existen. + /// Opcional. + /// + [JsonProperty("customs_keys")] + public List? CustomsKeys { get; set; } = default!; + + /// + /// third_party + /// Opcional. + /// + [JsonProperty("third_party")] + public InvoiceItemThirdParty? ThirdParty { get; set; } = default!; + + /// + /// complement + /// Opcional. + /// + [JsonProperty("complement")] + public OneOf? Complement { get; set; } = default!; + + /// + /// Objeto con información de las partes de la factura. + /// Opcional. + /// + [JsonProperty("parts")] + public List? Parts { get; set; } = default!; + } } diff --git a/Models/InvoiceItemPart.cs b/Models/InvoiceItemPart.cs new file mode 100644 index 0000000..e45aaf8 --- /dev/null +++ b/Models/InvoiceItemPart.cs @@ -0,0 +1,66 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceItemPart + /// + public class InvoiceItemPart + { + /// + /// Descripción del producto o servicio. + /// Opcional. + /// + [JsonProperty("description")] + public string? Description { get; set; } = default!; + + /// + /// Clave de producto/servicio, del catálogo del SAT. Nosotros te proporcionamos una manera más conveniente de encontrarlo utilizando nuestra herramienta de búsqueda de claves. + /// Opcional. + /// + [JsonProperty("product_key")] + public string? ProductKey { get; set; } = default!; + + /// + /// Cantidad + /// Opcional. + /// + [JsonProperty("quantity")] + public decimal? Quantity { get; set; } = default!; + + /// + /// Identificador de uso interno designado por la empresa. Puede tener cualquier valor. + /// Opcional. + /// + [JsonProperty("sku")] + public string? Sku { get; set; } = default!; + + /// + /// Precio unitario + /// Opcional. + /// + [JsonProperty("unit_price")] + public decimal? UnitPrice { get; set; } = default!; + + /// + /// Nombre de la unidad de medida que expresa la cantidad. + /// Opcional. + /// + [JsonProperty("unit_name")] + public string? UnitName { get; set; } = default!; + + /// + /// Números de pedimento aduanal asociados a esta parte. + /// Opcional. + /// + [JsonProperty("customs_keys")] + public List? CustomsKeys { get; set; } = default!; + + } +} diff --git a/Models/InvoiceItemThirdParty.cs b/Models/InvoiceItemThirdParty.cs new file mode 100644 index 0000000..954cee3 --- /dev/null +++ b/Models/InvoiceItemThirdParty.cs @@ -0,0 +1,45 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// InvoiceItemThirdParty + /// + public class InvoiceItemThirdParty + { + /// + /// Nombre o razón social del tercero. + /// Opcional. + /// + [JsonProperty("legal_name")] + public string? LegalName { get; set; } = default!; + + /// + /// RFC del tercero. + /// Opcional. + /// + [JsonProperty("tax_id")] + public string? TaxId { get; set; } = default!; + + /// + /// Régimen fiscal del tercero. + /// Opcional. + /// + [JsonProperty("tax_system")] + public string? TaxSystem { get; set; } = default!; + + /// + /// Código postal del tercero. + /// Opcional. + /// + [JsonProperty("zip")] + public string? Zip { get; set; } = default!; + + } +} diff --git a/Models/InvoicePending.cs b/Models/InvoicePending.cs new file mode 100644 index 0000000..c9fe674 --- /dev/null +++ b/Models/InvoicePending.cs @@ -0,0 +1,366 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Pendiente + /// + public class InvoicePending + { + /// + /// ID del objeto + /// Requerido. + /// + [JsonProperty("id")] + public string Id { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de registro + /// Requerido. + /// + [JsonProperty("created_at")] + public DateTime CreatedAt { get; set; } = default!; + + /// + /// Si el valor es `true`, indica que el objeto fue creado en ambiente Live; o si es `false`, en ambiente Test. + /// Requerido. + /// + [JsonProperty("livemode")] + public bool Livemode { get; set; } = default!; + + /// + /// Estado actual de la factura. `failed` indica que el timbrado en segundo plano o la recuperación automática del CFDI terminó sin éxito. + /// Valores: "pending". + /// Requerido. + /// + [JsonProperty("status")] + public string Status { get; set; } = default!; + + /// + /// cancellation + /// Opcional. + /// + [JsonProperty("cancellation")] + public InvoiceCancellation? Cancellation { get; set; } = default!; + + /// + /// cancellation_status + /// Valores: "none", "accepted", "pending", "rejected", "expired", "verifying". + /// Requerido. + /// + [JsonProperty("cancellation_status")] + public string CancellationStatus { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha en la que se canceló el CFDI con hora aproximada. + /// Opcional. + /// Admite null. + /// + [JsonProperty("canceled_at")] + public DateTime? CanceledAt { get; set; } = default!; + + /// + /// Format: uri + /// Dirección URL para verificar el estado del CFDI en el portal del SAT. Este link es el mismo que aparece en el código QR, en el PDF de la factura. + /// Opcional. + /// + [JsonProperty("verification_url")] + public string? VerificationUrl { get; set; } = default!; + + /// + /// address + /// Opcional. + /// + [JsonProperty("address")] + public Address? Address { get; set; } = default!; + + /// + /// Tipo de comprobante. Puede tener los valores `"I"`: Ingreso, `"P"`: Pago, `"E"`: Egreso, `"N"`: Nómina, `"T"`: Traslado. + /// Valores: "E", "I", "T", "N", "P". + /// Requerido. + /// + [JsonProperty("type")] + public string Type { get; set; } = default!; + + /// + /// customer + /// Opcional. + /// Admite null. + /// + [JsonProperty("customer")] + public CustomerInfo? Customer { get; set; } = default!; + + /// + /// Monto total facturado. + /// Requerido. + /// + [JsonProperty("total")] + public decimal Total { get; set; } = default!; + + /// + /// Número de folio autoincremental para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonProperty("folio_number")] + public int? FolioNumber { get; set; } = default!; + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. En el PDF se imprime junto al número de folio. + /// Opcional. + /// + [JsonProperty("series")] + public string? Series { get; set; } = default!; + + /// + /// Identificador que puedes usar para relacionar esta factura con tus registros para después buscar por este número. + /// Opcional. + /// + [JsonProperty("external_id")] + public string? ExternalId { get; set; } = default!; + + /// + /// Clave que identifica una operación para evitar recursos duplicados. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonProperty("idempotency_key")] + public string? IdempotencyKey { get; set; } = default!; + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Opcional. + /// Admite null. + /// + [JsonProperty("payment_form")] + public string? PaymentForm { get; set; } = default!; + + /// + /// Total del complemento de Pago cuando la factura es tipo P. + /// Opcional. + /// + [JsonProperty("total_payment_amount")] + public decimal? TotalPaymentAmount { get; set; } = default!; + + /// + /// Total del monto pagado convertido de la moneda de pago a Pesos Mexicanos. + /// Opcional. + /// + [JsonProperty("total_payment_amount_converted")] + public decimal? TotalPaymentAmountConverted { get; set; } = default!; + + /// + /// Este campo es asignado automáticamente por Facturapi. Indica si una factura + /// con status `draft` está completa y lista para intentar timbrarse. Si el valor es `true`, puedes + /// intentar timbrar la factura con el método [Timbrar Factura]('#/operation/stampInvoice'). + /// Si el valor es `false`, debes usar el método [Actualizar Factura]('#/operation/updateDraftInvoice') + /// para completar los campos faltantes. + /// + /// En una factura con status diferente a `draft`, este campo siempre será `false`. + /// Opcional. + /// + [JsonProperty("is_ready_to_stamp")] + public bool? IsReadyToStamp { get; set; } = default!; + + /// + /// Conceptos incluidos en el comprobante + /// Requerido. + /// + [JsonProperty("items")] + public List Items { get; set; } = default!; + + /// + /// Documentos relacionados con la factura. + /// Opcional. + /// + [JsonProperty("related_documents")] + public List? RelatedDocuments { get; set; } = default!; + + /// + /// En facturas con tipo I (Ingreso) y método de pago PPD, este campo lista los + /// IDs de los comprobantes de pago cuyo arreglo de documentos relacionados incluye el UUID + /// de esta factura. Este campo es llenado por Facturapi en el momento en que se crea o importa + /// el comprobante de pago (tipo P), siempre y cuando pertenezca a la misma organización. + /// Opcional. + /// + [JsonProperty("received_payment_ids")] + public List? ReceivedPaymentIds { get; set; } = default!; + + /// + /// En facturas con tipo P (Pago), este arreglo lista los IDs de los comprobantes de ingreso + /// listados en el arreglo de documentos relacionados. Este campo es llenado por Facturapi siempre + /// y cuando el comprobante relacionado también esté registrado en Facturapi y pertenezca a la misma organización. + /// Opcional. + /// + [JsonProperty("target_invoice_ids")] + public List? TargetInvoiceIds { get; set; } = default!; + + /// + /// Al recuperar el detalle de un CFDI de ingreso o egreso, este arreglo contiene los IDs de los + /// CFDI del tipo opuesto relacionados mediante `related_documents`. Para un ingreso incluye los + /// egresos que referencian su UUID; para un egreso incluye los ingresos cuyos UUID están en sus + /// documentos relacionados. Solo incluye CFDI registrados en la misma organización y ambiente. + /// Opcional. + /// + [JsonProperty("related_invoice_ids")] + public List? RelatedInvoiceIds { get; set; } = default!; + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Requerido. + /// + [JsonProperty("currency")] + public string Currency { get; set; } = default!; + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Requerido. + /// + [JsonProperty("exchange")] + public decimal Exchange { get; set; } = default!; + + /// + /// Complementos a incluir en la factura. + /// Opcional. + /// + [JsonProperty("complements")] + public List? Complements { get; set; } = default!; + + /// + /// Format: html + /// En caso de que necesites incluir más información en el PDF, este campo te permite insertar código HTML con tu propio contenido. + /// Opcional. + /// + [JsonProperty("pdf_custom_section")] + public string? PdfCustomSection { get; set; } = default!; + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonProperty("addenda")] + public string? Addenda { get; set; } = default!; + + /// + /// Namespaces a insertar en el nodo raíz de la factura. Requerido en `addenda`. + /// Opcional. + /// + [JsonProperty("namespaces")] + public List? Namespaces { get; set; } = default!; + + /// + /// ID de la organización a la que pertenece este recurso. + /// Opcional. + /// Admite null. + /// + [JsonProperty("organization")] + public string? Organization { get; set; } = default!; + + /// + /// issuer_type + /// Valores: "issuing", "receiving". + /// Opcional. + /// + [JsonProperty("issuer_type")] + public string? IssuerType { get; set; } = default!; + + /// + /// cfdi_version + /// Opcional. + /// + [JsonProperty("cfdi_version")] + public decimal? CfdiVersion { get; set; } = default!; + + /// + /// issuer_info + /// Opcional. + /// + [JsonProperty("issuer_info")] + public CustomerInfo? IssuerInfo { get; set; } = default!; + + /// + /// payment_method + /// Valores: "PUE", "PPD". + /// Opcional. + /// Admite null. + /// + [JsonProperty("payment_method")] + public string? PaymentMethod { get; set; } = default!; + + /// + /// use + /// Opcional. + /// + [JsonProperty("use")] + public string? Use { get; set; } = default!; + + /// + /// amount_due + /// Requerido. + /// + [JsonProperty("amount_due")] + public decimal AmountDue { get; set; } = default!; + + /// + /// Format: uri + /// Opcional. + /// + [JsonProperty("verification_carta_porte")] + public string? VerificationCartaPorte { get; set; } = default!; + + /// + /// conditions + /// Opcional. + /// + [JsonProperty("conditions")] + public string? Conditions { get; set; } = default!; + + /// + /// export + /// Opcional. + /// + [JsonProperty("export")] + public string? Export { get; set; } = default!; + + /// + /// global + /// Opcional. + /// + [JsonProperty("global")] + public Global? Global { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de expedición en formato ISO8601. Puede ser null en borradores. + /// Requerido. + /// Admite null. + /// + [JsonProperty("date")] + public DateTime? Date { get; set; } = default!; + + /// + /// Format: uuid + /// Folio fiscal de la factura, asignado por el SAT. En borradores sin timbrar puede ser null o estar omitido. + /// Opcional. + /// Admite null. + /// + [JsonProperty("uuid")] + public string? Uuid { get; set; } = default!; + + /// + /// stamp + /// Opcional. + /// Admite null. + /// + [JsonProperty("stamp")] + public Stamp? Stamp { get; set; } = default!; + + } +} diff --git a/Models/InvoiceStamped.cs b/Models/InvoiceStamped.cs new file mode 100644 index 0000000..f03808a --- /dev/null +++ b/Models/InvoiceStamped.cs @@ -0,0 +1,361 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Timbrada + /// + public class InvoiceStamped + { + /// + /// ID del objeto + /// Requerido. + /// + [JsonProperty("id")] + public string Id { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de registro + /// Requerido. + /// + [JsonProperty("created_at")] + public DateTime CreatedAt { get; set; } = default!; + + /// + /// Si el valor es `true`, indica que el objeto fue creado en ambiente Live; o si es `false`, en ambiente Test. + /// Requerido. + /// + [JsonProperty("livemode")] + public bool Livemode { get; set; } = default!; + + /// + /// Estado actual de la factura. `failed` indica que el timbrado en segundo plano o la recuperación automática del CFDI terminó sin éxito. + /// Valores: "valid", "canceled". + /// Requerido. + /// + [JsonProperty("status")] + public string Status { get; set; } = default!; + + /// + /// cancellation + /// Opcional. + /// + [JsonProperty("cancellation")] + public InvoiceCancellation? Cancellation { get; set; } = default!; + + /// + /// cancellation_status + /// Valores: "none", "accepted", "pending", "rejected", "expired", "verifying". + /// Requerido. + /// + [JsonProperty("cancellation_status")] + public string CancellationStatus { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha en la que se canceló el CFDI con hora aproximada. + /// Opcional. + /// Admite null. + /// + [JsonProperty("canceled_at")] + public DateTime? CanceledAt { get; set; } = default!; + + /// + /// Format: uri + /// Dirección URL para verificar el estado del CFDI en el portal del SAT. Este link es el mismo que aparece en el código QR, en el PDF de la factura. + /// Opcional. + /// + [JsonProperty("verification_url")] + public string? VerificationUrl { get; set; } = default!; + + /// + /// address + /// Opcional. + /// + [JsonProperty("address")] + public Address? Address { get; set; } = default!; + + /// + /// Tipo de comprobante. Puede tener los valores `"I"`: Ingreso, `"P"`: Pago, `"E"`: Egreso, `"N"`: Nómina, `"T"`: Traslado. + /// Valores: "E", "I", "T", "N", "P". + /// Requerido. + /// + [JsonProperty("type")] + public string Type { get; set; } = default!; + + /// + /// customer + /// Opcional. + /// Admite null. + /// + [JsonProperty("customer")] + public CustomerInfo? Customer { get; set; } = default!; + + /// + /// Monto total facturado. + /// Requerido. + /// + [JsonProperty("total")] + public decimal Total { get; set; } = default!; + + /// + /// Número de folio autoincremental para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonProperty("folio_number")] + public int? FolioNumber { get; set; } = default!; + + /// + /// Serie. Caracteres designados por la empresa para control interno y sin validez fiscal. En el PDF se imprime junto al número de folio. + /// Opcional. + /// + [JsonProperty("series")] + public string? Series { get; set; } = default!; + + /// + /// Identificador que puedes usar para relacionar esta factura con tus registros para después buscar por este número. + /// Opcional. + /// + [JsonProperty("external_id")] + public string? ExternalId { get; set; } = default!; + + /// + /// Clave que identifica una operación para evitar recursos duplicados. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonProperty("idempotency_key")] + public string? IdempotencyKey { get; set; } = default!; + + /// + /// Código que representa la forma de pago, de acuerdo al [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Opcional. + /// Admite null. + /// + [JsonProperty("payment_form")] + public string? PaymentForm { get; set; } = default!; + + /// + /// Total del complemento de Pago cuando la factura es tipo P. + /// Opcional. + /// + [JsonProperty("total_payment_amount")] + public decimal? TotalPaymentAmount { get; set; } = default!; + + /// + /// Total del monto pagado convertido de la moneda de pago a Pesos Mexicanos. + /// Opcional. + /// + [JsonProperty("total_payment_amount_converted")] + public decimal? TotalPaymentAmountConverted { get; set; } = default!; + + /// + /// Este campo es asignado automáticamente por Facturapi. Indica si una factura + /// con status `draft` está completa y lista para intentar timbrarse. Si el valor es `true`, puedes + /// intentar timbrar la factura con el método [Timbrar Factura]('#/operation/stampInvoice'). + /// Si el valor es `false`, debes usar el método [Actualizar Factura]('#/operation/updateDraftInvoice') + /// para completar los campos faltantes. + /// + /// En una factura con status diferente a `draft`, este campo siempre será `false`. + /// Opcional. + /// + [JsonProperty("is_ready_to_stamp")] + public bool? IsReadyToStamp { get; set; } = default!; + + /// + /// Conceptos incluidos en el comprobante + /// Requerido. + /// + [JsonProperty("items")] + public List Items { get; set; } = default!; + + /// + /// Documentos relacionados con la factura. + /// Opcional. + /// + [JsonProperty("related_documents")] + public List? RelatedDocuments { get; set; } = default!; + + /// + /// En facturas con tipo I (Ingreso) y método de pago PPD, este campo lista los + /// IDs de los comprobantes de pago cuyo arreglo de documentos relacionados incluye el UUID + /// de esta factura. Este campo es llenado por Facturapi en el momento en que se crea o importa + /// el comprobante de pago (tipo P), siempre y cuando pertenezca a la misma organización. + /// Opcional. + /// + [JsonProperty("received_payment_ids")] + public List? ReceivedPaymentIds { get; set; } = default!; + + /// + /// En facturas con tipo P (Pago), este arreglo lista los IDs de los comprobantes de ingreso + /// listados en el arreglo de documentos relacionados. Este campo es llenado por Facturapi siempre + /// y cuando el comprobante relacionado también esté registrado en Facturapi y pertenezca a la misma organización. + /// Opcional. + /// + [JsonProperty("target_invoice_ids")] + public List? TargetInvoiceIds { get; set; } = default!; + + /// + /// Al recuperar el detalle de un CFDI de ingreso o egreso, este arreglo contiene los IDs de los + /// CFDI del tipo opuesto relacionados mediante `related_documents`. Para un ingreso incluye los + /// egresos que referencian su UUID; para un egreso incluye los ingresos cuyos UUID están en sus + /// documentos relacionados. Solo incluye CFDI registrados en la misma organización y ambiente. + /// Opcional. + /// + [JsonProperty("related_invoice_ids")] + public List? RelatedInvoiceIds { get; set; } = default!; + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Requerido. + /// + [JsonProperty("currency")] + public string Currency { get; set; } = default!; + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Requerido. + /// + [JsonProperty("exchange")] + public decimal Exchange { get; set; } = default!; + + /// + /// Complementos a incluir en la factura. + /// Opcional. + /// + [JsonProperty("complements")] + public List? Complements { get; set; } = default!; + + /// + /// Format: html + /// En caso de que necesites incluir más información en el PDF, este campo te permite insertar código HTML con tu propio contenido. + /// Opcional. + /// + [JsonProperty("pdf_custom_section")] + public string? PdfCustomSection { get; set; } = default!; + + /// + /// Format: xml + /// Código XML con la Addenda que se necesite agregar a la factura. + /// Opcional. + /// + [JsonProperty("addenda")] + public string? Addenda { get; set; } = default!; + + /// + /// Namespaces a insertar en el nodo raíz de la factura. Requerido en `addenda`. + /// Opcional. + /// + [JsonProperty("namespaces")] + public List? Namespaces { get; set; } = default!; + + /// + /// ID de la organización a la que pertenece este recurso. + /// Opcional. + /// Admite null. + /// + [JsonProperty("organization")] + public string? Organization { get; set; } = default!; + + /// + /// issuer_type + /// Valores: "issuing", "receiving". + /// Opcional. + /// + [JsonProperty("issuer_type")] + public string? IssuerType { get; set; } = default!; + + /// + /// cfdi_version + /// Opcional. + /// + [JsonProperty("cfdi_version")] + public decimal? CfdiVersion { get; set; } = default!; + + /// + /// issuer_info + /// Opcional. + /// + [JsonProperty("issuer_info")] + public CustomerInfo? IssuerInfo { get; set; } = default!; + + /// + /// payment_method + /// Valores: "PUE", "PPD". + /// Opcional. + /// Admite null. + /// + [JsonProperty("payment_method")] + public string? PaymentMethod { get; set; } = default!; + + /// + /// use + /// Opcional. + /// + [JsonProperty("use")] + public string? Use { get; set; } = default!; + + /// + /// amount_due + /// Requerido. + /// + [JsonProperty("amount_due")] + public decimal AmountDue { get; set; } = default!; + + /// + /// Format: uri + /// Opcional. + /// + [JsonProperty("verification_carta_porte")] + public string? VerificationCartaPorte { get; set; } = default!; + + /// + /// conditions + /// Opcional. + /// + [JsonProperty("conditions")] + public string? Conditions { get; set; } = default!; + + /// + /// export + /// Opcional. + /// + [JsonProperty("export")] + public string? Export { get; set; } = default!; + + /// + /// global + /// Opcional. + /// + [JsonProperty("global")] + public Global? Global { get; set; } = default!; + + /// + /// Format: date-time + /// Requerido. + /// + [JsonProperty("date")] + public DateTime Date { get; set; } = default!; + + /// + /// Format: uuid + /// Requerido. + /// + [JsonProperty("uuid")] + public string Uuid { get; set; } = default!; + + /// + /// stamp + /// Requerido. + /// + [JsonProperty("stamp")] + public Stamp Stamp { get; set; } = default!; + + } +} diff --git a/Models/InvoiceZipRequest.cs b/Models/InvoiceZipRequest.cs new file mode 100644 index 0000000..c37fac2 --- /dev/null +++ b/Models/InvoiceZipRequest.cs @@ -0,0 +1,153 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Objeto InvoiceZipRequest + /// + public class InvoiceZipRequest + { + /// + /// ID del objeto + /// Requerido. + /// + [JsonProperty("id")] + public string Id { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de registro + /// Requerido. + /// + [JsonProperty("created_at")] + public DateTime CreatedAt { get; set; } = default!; + + /// + /// Si el valor es `true`, indica que el objeto fue creado en ambiente Live; o si es `false`, en ambiente Test. + /// Siempre es `true` para este flujo. + /// Requerido. + /// + [JsonProperty("livemode")] + public bool Livemode { get; set; } = default!; + + /// + /// Es true cuando el paquete terminado no tiene documentos fallidos ni cambios registrados en facturas desde su preparación. Las generaciones anteriores siguen descargables. + /// Opcional. + /// + [JsonProperty("is_current")] + public bool? IsCurrent { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha en que terminó la generación. Ausente en paquetes legados. + /// Opcional. + /// + [JsonProperty("generated_at")] + public DateTime? GeneratedAt { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de inicio de preparación. Los cambios en facturas durante la preparación pueden dejar el paquete desactualizado; consulta is_current. + /// Opcional. + /// + [JsonProperty("content_as_of")] + public DateTime? ContentAsOf { get; set; } = default!; + + /// + /// Identificador de la organización. + /// Requerido. + /// + [JsonProperty("organization")] + public string Organization { get; set; } = default!; + + /// + /// issuer_type + /// Valores: "issuing", "receiving". + /// Requerido. + /// + [JsonProperty("issuer_type")] + public string IssuerType { get; set; } = default!; + + /// + /// Filtra por procedencia: `true` para CFDIs importados del SAT, `false` para CFDIs sin importación del SAT. Omitido incluye ambas procedencias. + /// Opcional. + /// + [JsonProperty("sat_imported")] + public bool? SatImported { get; set; } = default!; + + /// + /// Tipos normalizados de las facturas incluidas. + /// Requerido. + /// + [JsonProperty("invoice_types")] + public List InvoiceTypes { get; set; } = default!; + + /// + /// Format: date-time + /// Inicio inclusivo del mes solicitado. + /// Requerido. + /// + [JsonProperty("start_date")] + public DateTime StartDate { get; set; } = default!; + + /// + /// Format: date-time + /// Fin inclusivo del mes solicitado. + /// Requerido. + /// + [JsonProperty("end_date")] + public DateTime EndDate { get; set; } = default!; + + /// + /// status + /// Valores: "none", "created", "processing", "finished", "failed". + /// Requerido. + /// + [JsonProperty("status")] + public string Status { get; set; } = default!; + + /// + /// Número total de facturas por procesar. + /// Requerido. + /// + [JsonProperty("document_count")] + public int DocumentCount { get; set; } = default!; + + /// + /// Número de facturas procesadas. + /// Requerido. + /// + [JsonProperty("processed_document")] + public int ProcessedDocument { get; set; } = default!; + + /// + /// Facturas que no pudieron agregarse al ZIP. + /// Requerido. + /// + [JsonProperty("failed_documents")] + public List FailedDocuments { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha en que se programó el procesamiento. + /// Opcional. + /// + [JsonProperty("scheduled_at")] + public DateTime? ScheduledAt { get; set; } = default!; + + /// + /// Format: date-time + /// Momento en que comenzó el procesamiento, si existe. + /// Opcional. + /// + [JsonProperty("processing_started_at")] + public DateTime? ProcessingStartedAt { get; set; } = default!; + + } +} diff --git a/Models/Legal.cs b/Models/Legal.cs index b6df128..23d569e 100644 --- a/Models/Legal.cs +++ b/Models/Legal.cs @@ -1,12 +1,80 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + namespace Facturapi { - public class Legal { - public string Name { get; set; } - public string LegalName { get; set; } - public string TaxId { get; set; } - public string TaxSystem { get; set; } - public string Website { get; set; } - public string Phone { get; set; } - public Address Address { get; set; } + /// + /// Legal + /// + public class Legal + { + /// + /// Nombre comercial de la organización. + /// Opcional. + /// + [JsonProperty("name")] + public string? Name { get; set; } = default!; + + /// + /// Nombre Fiscal o Razón Social de la organización, *sin* el régimen societario (ej.: S.A. de C.V.). + /// Opcional. + /// + [JsonProperty("legal_name")] + public string? LegalName { get; set; } = default!; + + /// + /// tax_id + /// Opcional. + /// + [JsonProperty("tax_id")] + public string? TaxId { get; set; } = default!; + + /// + /// Format: email + /// Opcional. + /// + [JsonProperty("support_email")] + public string? SupportEmail { get; set; } = default!; + + /// + /// curp + /// Opcional. + /// + [JsonProperty("curp")] + public string? Curp { get; set; } = default!; + + /// + /// Código de Régimen Fiscal, del [catálogo del SAT](https://docs.facturapi.io/api/#régimen-fiscal). + /// Opcional. + /// + [JsonProperty("tax_system")] + public string? TaxSystem { get; set; } = default!; + + /// + /// Sitio web de la organización, que se utilizará al enviar la factura por correo electrónico. + /// Opcional. + /// + [JsonProperty("website")] + public string? Website { get; set; } = default!; + + /// + /// Teléfono de la organización, que aparecerá en el PDF de la factura. + /// Opcional. + /// + [JsonProperty("phone")] + public string? Phone { get; set; } = default!; + + /// + /// address + /// Opcional. + /// + [JsonProperty("address")] + public LegalAddress? Address { get; set; } = default!; + } -} \ No newline at end of file +} diff --git a/Models/LegalAddress.cs b/Models/LegalAddress.cs new file mode 100644 index 0000000..56893b8 --- /dev/null +++ b/Models/LegalAddress.cs @@ -0,0 +1,85 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// LegalAddress + /// + public class LegalAddress + { + /// + /// Nombre de la calle + /// Opcional. + /// + [JsonProperty("street")] + public string? Street { get; set; } = default!; + + /// + /// Número exterior. + /// Opcional. + /// + [JsonProperty("exterior")] + public string? Exterior { get; set; } = default!; + + /// + /// Número interior. + /// Opcional. + /// + [JsonProperty("interior")] + public string? Interior { get; set; } = default!; + + /// + /// Colonia + /// Opcional. + /// + [JsonProperty("neighborhood")] + public string? Neighborhood { get; set; } = default!; + + /// + /// Ciudad + /// Opcional. + /// + [JsonProperty("city")] + public string? City { get; set; } = default!; + + /// + /// Municipio o delegación + /// Opcional. + /// + [JsonProperty("municipality")] + public string? Municipality { get; set; } = default!; + + /// + /// Código postal + /// Opcional. + /// + [JsonProperty("zip")] + public string? Zip { get; set; } = default!; + + /// + /// country + /// Opcional. + /// + [JsonProperty("country")] + public string? Country { get; set; } = default!; + + /// + /// Nombre del Estado o Entidad Federativa. + /// Opcional. + /// + [JsonProperty("state")] + public string? State { get; set; } = default!; + + /// + /// Propiedades adicionales del objeto JSON. + /// + [JsonExtensionData] + public IDictionary? AdditionalProperties { get; set; } + } +} diff --git a/Models/LeyendasFiscalesData.cs b/Models/LeyendasFiscalesData.cs new file mode 100644 index 0000000..37e0c9c --- /dev/null +++ b/Models/LeyendasFiscalesData.cs @@ -0,0 +1,24 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Complemento de Leyendas Fiscales versión 1.0. + /// + public class LeyendasFiscalesData + { + /// + /// Leyendas fiscales a incluir en el comprobante. + /// Requerido. + /// + [JsonProperty("leyendas")] + public List Leyendas { get; set; } = default!; + + } +} diff --git a/Models/LeyendasFiscalesDataLeyendasItem.cs b/Models/LeyendasFiscalesDataLeyendasItem.cs new file mode 100644 index 0000000..8db6e44 --- /dev/null +++ b/Models/LeyendasFiscalesDataLeyendasItem.cs @@ -0,0 +1,38 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// LeyendasFiscalesDataLeyendasItem + /// + public class LeyendasFiscalesDataLeyendasItem + { + /// + /// Disposición fiscal aplicable a la leyenda. + /// Opcional. + /// + [JsonProperty("disposicion_fiscal")] + public string? DisposicionFiscal { get; set; } = default!; + + /// + /// Norma que regula la leyenda. + /// Opcional. + /// + [JsonProperty("norma")] + public string? Norma { get; set; } = default!; + + /// + /// Texto de la leyenda fiscal. + /// Requerido. + /// + [JsonProperty("texto_leyenda")] + public string TextoLeyenda { get; set; } = default!; + + } +} diff --git a/Models/LiveApiKey.cs b/Models/LiveApiKey.cs index 68c60b7..09e9fc9 100644 --- a/Models/LiveApiKey.cs +++ b/Models/LiveApiKey.cs @@ -1,10 +1,39 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + namespace Facturapi { + /// + /// LiveApiKey + /// public class LiveApiKey { - public string First12 { get; set; } - public string CreatedAt { get; set; } + /// + /// Primeros 12 caracteres de la llave secreta + /// Opcional. + /// + [JsonProperty("first_12")] + public string? First12 { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de creación de la llave secreta + /// Opcional. + /// + [JsonProperty("created_at")] + public DateTime? CreatedAt { get; set; } = default!; + + /// + /// ID de la llave secreta + /// Opcional. + /// + [JsonProperty("id")] + public string? Id { get; set; } = default!; - public string Id { get; set; } } } diff --git a/Models/LocalTax.cs b/Models/LocalTax.cs new file mode 100644 index 0000000..9cbac51 --- /dev/null +++ b/Models/LocalTax.cs @@ -0,0 +1,54 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// LocalTax + /// + public class LocalTax + { + /// + /// Tasa del impuesto en fracción decimal. + /// Requerido. + /// + [JsonProperty("rate")] + public decimal Rate { get; set; } = default!; + + /// + /// Base del impuesto. Si se omite, se utiliza el subtotal completo del concepto. + /// Opcional. + /// Admite null. + /// + [JsonProperty("base")] + public decimal? Base { get; set; } = default!; + + /// + /// Nombre del impuesto. Texto libre. + /// Requerido. + /// + [JsonProperty("type")] + public string Type { get; set; } = default!; + + /// + /// Indica si se trata de un impuesto retenido (`true`), o un impuesto trasladado (`false`) + /// Opcional. + /// + [JsonProperty("withholding")] + public bool? Withholding { get; set; } = default!; + + /// + /// factor + /// Valores: "Tasa", "Cuota", "Exento". + /// Opcional. + /// + [JsonProperty("factor")] + public string? Factor { get; set; } = default!; + + } +} diff --git a/Models/Namespace.cs b/Models/Namespace.cs new file mode 100644 index 0000000..2c0d6db --- /dev/null +++ b/Models/Namespace.cs @@ -0,0 +1,40 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Namespace + /// + public class Namespace + { + /// + /// Prefijo o nombre del namespace. + /// Opcional. + /// + [JsonProperty("prefix")] + public string? Prefix { get; set; } = default!; + + /// + /// Format: url + /// Dirección URL asociada al namespace. + /// Opcional. + /// + [JsonProperty("uri")] + public string? Uri { get; set; } = default!; + + /// + /// Format: url + /// Dirección URL del esquema de validación XSD. + /// Opcional. + /// + [JsonProperty("schema_location")] + public string? SchemaLocation { get; set; } = default!; + + } +} diff --git a/Models/NominaAccionesProperties.cs b/Models/NominaAccionesProperties.cs new file mode 100644 index 0000000..d7e1935 --- /dev/null +++ b/Models/NominaAccionesProperties.cs @@ -0,0 +1,31 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Objeto para expresar ingresos por acciones o títulos valor que representan bienes. Es requerido cuando existan ingresos por sueldos derivados de adquisición de acciones o títulos. + /// + public class NominaAccionesProperties + { + /// + /// Valor de mercado de las Acciones o Títulos valor al ejercer la opción. + /// Opcional. + /// + [JsonProperty("valor_mercado")] + public decimal? ValorMercado { get; set; } = default!; + + /// + /// Precio establecido al otorgarse la opción de ingresos en acciones o títulos valor. + /// Opcional. + /// + [JsonProperty("precio_al_otorgarse")] + public decimal? PrecioAlOtorgarse { get; set; } = default!; + + } +} diff --git a/Models/NominaCompensacionProperties.cs b/Models/NominaCompensacionProperties.cs new file mode 100644 index 0000000..e1acc7d --- /dev/null +++ b/Models/NominaCompensacionProperties.cs @@ -0,0 +1,38 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Objeto con información referente a la compensación de saldos a favor de un trabajador. + /// + public class NominaCompensacionProperties + { + /// + /// Monto por saldo a favor determinado por el patrón al trabajador en periodos o ejercicios anteriores. + /// Opcional. + /// + [JsonProperty("saldo_a_favor")] + public decimal? SaldoAFavor { get; set; } = default!; + + /// + /// Año en que se determinó el saldo a favor del trabajador. + /// Opcional. + /// + [JsonProperty("ano")] + public int? Ano { get; set; } = default!; + + /// + /// Remanente del saldo a favor del trabajador. + /// Opcional. + /// + [JsonProperty("remanente_sal_fav")] + public decimal? RemanenteSalFav { get; set; } = default!; + + } +} diff --git a/Models/NominaComplementDataProperties.cs b/Models/NominaComplementDataProperties.cs new file mode 100644 index 0000000..2df81c3 --- /dev/null +++ b/Models/NominaComplementDataProperties.cs @@ -0,0 +1,97 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Complemento de Nómina. + /// + public class NominaComplementDataProperties + { + /// + /// Tipo de nómina. + /// - `“O”` (Ordinaria): Cuando corresponde a un pago que se realiza de manera habitual, como sueldos. + /// - `“E”` (Extraordinaria): Para pagos fuera de lo habitual, como liquidaciones, aguinaldos o bonos. + /// Valores: "O", "E". + /// Opcional. + /// + [JsonProperty("tipo_nomina")] + public string? TipoNomina { get; set; } = default!; + + /// + /// Fecha de pago de la nómina al trabajador. Si se omite, se utiliza la fecha y hora actuales. + /// Opcional. + /// + [JsonProperty("fecha_pago")] + public OneOf? FechaPago { get; set; } = default!; + + /// + /// Fecha inicial del periodo de pago. + /// Opcional. + /// + [JsonProperty("fecha_inicial_pago")] + public OneOf? FechaInicialPago { get; set; } = default!; + + /// + /// Fecha final del periodo de pago. + /// Opcional. + /// + [JsonProperty("fecha_final_pago")] + public OneOf? FechaFinalPago { get; set; } = default!; + + /// + /// Número de días pagados. Puede ser entero o fracción. + /// Opcional. + /// + [JsonProperty("num_dias_pagados")] + public decimal? NumDiasPagados { get; set; } = default!; + + /// + /// emisor + /// Opcional. + /// + [JsonProperty("emisor")] + public NominaEmisorProperties? Emisor { get; set; } = default!; + + /// + /// receptor + /// Opcional. + /// + [JsonProperty("receptor")] + public NominaReceptorProperties? Receptor { get; set; } = default!; + + /// + /// percepciones + /// Opcional. + /// + [JsonProperty("percepciones")] + public NominaPercepcionesProperties? Percepciones { get; set; } = default!; + + /// + /// Arreglo de objetos donde se expresan las deducciones aplicables. + /// Opcional. + /// + [JsonProperty("deducciones")] + public List? Deducciones { get; set; } = default!; + + /// + /// Arreglo de objetos para expresar otros pagos aplicables. + /// Opcional. + /// + [JsonProperty("otros_pagos")] + public List? OtrosPagos { get; set; } = default!; + + /// + /// Arreglo de objetos con información de incapacidades. + /// Opcional. + /// + [JsonProperty("incapacidades")] + public List? Incapacidades { get; set; } = default!; + + } +} diff --git a/Models/NominaComplementDataPropertiesOtrosPagosItem.cs b/Models/NominaComplementDataPropertiesOtrosPagosItem.cs new file mode 100644 index 0000000..c7e8c44 --- /dev/null +++ b/Models/NominaComplementDataPropertiesOtrosPagosItem.cs @@ -0,0 +1,63 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaComplementDataPropertiesOtrosPagosItem + /// + public class NominaComplementDataPropertiesOtrosPagosItem + { + /// + /// Clave del catálogo [Tipo de Otro Pago](https://docs.facturapi.io/api/#tipo-de-otro-pago). + /// Opcional. + /// + [JsonProperty("tipo_otro_pago")] + public string? TipoOtroPago { get; set; } = default!; + + /// + /// Clave de otro pago de nómina propia de la contabilidad de cada patrón. + /// Opcional. + /// + [JsonProperty("clave")] + public string? Clave { get; set; } = default!; + + /// + /// Descripción alternativa correspondiente a la clave utilizada. + /// Opcional. + /// + [JsonProperty("concepto")] + public string? Concepto { get; set; } = default!; + + /// + /// Importe por concepto de otro pago. + /// Opcional. + /// + [JsonProperty("importe")] + public decimal? Importe { get; set; } = default!; + + /// + /// Subsidio causado conforme a la tabla del subsidio para el empleo + /// publicada en el Anexo 8 de la Resolución Miscelánea Fiscal vigente. + /// + /// Este valor será insertado dentro del nodo `SubsidioAlEmpleo`, y es + /// requerido cuando el valor de `tipo_otro_pago` es `"002"`. + /// Opcional. + /// + [JsonProperty("subsidio_causado")] + public decimal? SubsidioCausado { get; set; } = default!; + + /// + /// compensacion_saldos_a_favor + /// Opcional. + /// + [JsonProperty("compensacion_saldos_a_favor")] + public NominaCompensacionProperties? CompensacionSaldosAFavor { get; set; } = default!; + + } +} diff --git a/Models/NominaDeduccionProperties.cs b/Models/NominaDeduccionProperties.cs new file mode 100644 index 0000000..a5ab3eb --- /dev/null +++ b/Models/NominaDeduccionProperties.cs @@ -0,0 +1,45 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaDeduccionProperties + /// + public class NominaDeduccionProperties + { + /// + /// Clave del catálogo [Tipo de deducción](https://docs.facturapi.io/api/#tipo-de-deducción). + /// Opcional. + /// + [JsonProperty("tipo_deduccion")] + public string? TipoDeduccion { get; set; } = default!; + + /// + /// Concepto de la deducción. Si no se envía, se utilizará la descripción del catálogo del tipo de deducción. + /// Opcional. + /// + [JsonProperty("concepto")] + public string? Concepto { get; set; } = default!; + + /// + /// Clave de control interno que asigna el patrón a cada deducción (descuento) de nómina propia de su contabilidad. + /// Opcional. + /// + [JsonProperty("clave")] + public string? Clave { get; set; } = default!; + + /// + /// Importe del concepto de deducción. + /// Opcional. + /// + [JsonProperty("importe")] + public decimal? Importe { get; set; } = default!; + + } +} diff --git a/Models/NominaEmisorProperties.cs b/Models/NominaEmisorProperties.cs new file mode 100644 index 0000000..9a871c0 --- /dev/null +++ b/Models/NominaEmisorProperties.cs @@ -0,0 +1,45 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Información del emisor, en caso de ser requerida. + /// + public class NominaEmisorProperties + { + /// + /// Requerido cuando el empleador es persona física. CURP del empleador. + /// Opcional. + /// + [JsonProperty("curp")] + public string? Curp { get; set; } = default!; + + /// + /// Clave de registro patronal asignada por la institución de seguridad social al patrón. + /// Opcional. + /// + [JsonProperty("registro_patronal")] + public string? RegistroPatronal { get; set; } = default!; + + /// + /// RFC de la persona que fungió como patrón. Se usa cuando el pago se realiza a través de un tercero. + /// Opcional. + /// + [JsonProperty("rfc_patron_origen")] + public string? RfcPatronOrigen { get; set; } = default!; + + /// + /// Información para que las entidades adheridas al Sistema Nacional de Coordinación Fiscal realicen la identificación del origen de los recursos. + /// Opcional. + /// + [JsonProperty("entidad_sncf")] + public NominaEmisorPropertiesEntidadSncf? EntidadSncf { get; set; } = default!; + + } +} diff --git a/Models/NominaEmisorPropertiesEntidadSncf.cs b/Models/NominaEmisorPropertiesEntidadSncf.cs new file mode 100644 index 0000000..31eb7d0 --- /dev/null +++ b/Models/NominaEmisorPropertiesEntidadSncf.cs @@ -0,0 +1,36 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaEmisorPropertiesEntidadSncf + /// + public class NominaEmisorPropertiesEntidadSncf + { + /// + /// Clave de origen de recurso. + /// + /// - `“IP”`: Ingresos Propios + /// - `“IF”`: Ingresos Federales + /// - `“IM”`: Ingresos mixtos. + /// Valores: "IP", "IF", "IM". + /// Opcional. + /// + [JsonProperty("origen_recurso")] + public string? OrigenRecurso { get; set; } = default!; + + /// + /// Importe de recursos propios. Requerido cuando el origen del recurso es por ingresos mixtos. + /// Opcional. + /// + [JsonProperty("monto_recurso_propio")] + public decimal? MontoRecursoPropio { get; set; } = default!; + + } +} diff --git a/Models/NominaHorasExtraProperties.cs b/Models/NominaHorasExtraProperties.cs new file mode 100644 index 0000000..365a599 --- /dev/null +++ b/Models/NominaHorasExtraProperties.cs @@ -0,0 +1,45 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// HorasExtra + /// + public class NominaHorasExtraProperties + { + /// + /// Número de días en que el trabajador laboró horas extra adicionales a su jornada normal de trabajo. + /// Opcional. + /// + [JsonProperty("dias")] + public int? Dias { get; set; } = default!; + + /// + /// Clave del catálogo [Tipo de Horas](https://docs.facturapi.io/api/#tipo-de-Horas). + /// Opcional. + /// + [JsonProperty("tipo_horas")] + public string? TipoHoras { get; set; } = default!; + + /// + /// Número de horas extra trabajadas en el periodo. + /// Opcional. + /// + [JsonProperty("horas_extra")] + public int? HorasExtra { get; set; } = default!; + + /// + /// Importe pagado por las horas extra. + /// Opcional. + /// + [JsonProperty("importe_pagado")] + public decimal? ImportePagado { get; set; } = default!; + + } +} diff --git a/Models/NominaIncapacidadProperties.cs b/Models/NominaIncapacidadProperties.cs new file mode 100644 index 0000000..fb33f2b --- /dev/null +++ b/Models/NominaIncapacidadProperties.cs @@ -0,0 +1,38 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaIncapacidadProperties + /// + public class NominaIncapacidadProperties + { + /// + /// Número de días enteros que el trabajador se incapacitó en el periodo. + /// Opcional. + /// + [JsonProperty("dias_incapacidad")] + public int? DiasIncapacidad { get; set; } = default!; + + /// + /// Clave del catálogo [Tipo de Incapacidad](https://docs.facturapi.io/api/#tipo-de-incapacidad). + /// Opcional. + /// + [JsonProperty("tipo_incapacidad")] + public string? TipoIncapacidad { get; set; } = default!; + + /// + /// Monto del importe monetario de la incapacidad. + /// Opcional. + /// + [JsonProperty("importe_monetario")] + public decimal? ImporteMonetario { get; set; } = default!; + + } +} diff --git a/Models/NominaJubilacionProperties.cs b/Models/NominaJubilacionProperties.cs new file mode 100644 index 0000000..7d7a54d --- /dev/null +++ b/Models/NominaJubilacionProperties.cs @@ -0,0 +1,52 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Objeto con información detallada de pagos por jubilación, pensiones o haberes de retiro. + /// + public class NominaJubilacionProperties + { + /// + /// Monto total del pago entregado en una sola exhibición. + /// Opcional. + /// + [JsonProperty("total_una_exhibicion")] + public decimal? TotalUnaExhibicion { get; set; } = default!; + + /// + /// Monto total del pago entregado en parcialidades. + /// Opcional. + /// + [JsonProperty("total_parcialidad")] + public decimal? TotalParcialidad { get; set; } = default!; + + /// + /// Monto diario percibido por el trabajador cuando el pago se realiza en parcialidades. + /// Opcional. + /// + [JsonProperty("monto_diario")] + public decimal? MontoDiario { get; set; } = default!; + + /// + /// Ingresos acumulables percibidos por el trabajador. + /// Opcional. + /// + [JsonProperty("ingreso_acumulable")] + public decimal? IngresoAcumulable { get; set; } = default!; + + /// + /// Ingresos no acumulables percibidos por el trabajador. + /// Opcional. + /// + [JsonProperty("ingreso_no_acumulable")] + public decimal? IngresoNoAcumulable { get; set; } = default!; + + } +} diff --git a/Models/NominaPercepcionProperties.cs b/Models/NominaPercepcionProperties.cs new file mode 100644 index 0000000..96f8e80 --- /dev/null +++ b/Models/NominaPercepcionProperties.cs @@ -0,0 +1,66 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Percepcion + /// + public class NominaPercepcionProperties + { + /// + /// Clave del catálogo [Tipo de percepción](https://docs.facturapi.io/api/#tipo-de-percepcion). + /// Opcional. + /// + [JsonProperty("tipo_percepcion")] + public string? TipoPercepcion { get; set; } = default!; + + /// + /// Concepto de la percepción. Si no se envía, se utilizará la descripción del catálogo del tipo de percepción. + /// Opcional. + /// + [JsonProperty("concepto")] + public string? Concepto { get; set; } = default!; + + /// + /// Clave de control interno que asigna el patrón a cada percepción de nómina propia de su contabilidad. + /// Opcional. + /// + [JsonProperty("clave")] + public string? Clave { get; set; } = default!; + + /// + /// Importe gravado por el concepto indicado en el tipo de percepción. + /// Opcional. + /// + [JsonProperty("importe_gravado")] + public decimal? ImporteGravado { get; set; } = default!; + + /// + /// Importe exento por el concepto indicado en el tipo de percepción. + /// Opcional. + /// + [JsonProperty("importe_exento")] + public decimal? ImporteExento { get; set; } = default!; + + /// + /// acciones_o_titulos + /// Opcional. + /// + [JsonProperty("acciones_o_titulos")] + public NominaAccionesProperties? AccionesOTitulos { get; set; } = default!; + + /// + /// Arreglo de objetos para expresar las horas extra aplicables. Requerido cuando el tipo de percepción es “019” (Horas extras). + /// Opcional. + /// + [JsonProperty("horas_extra")] + public List? HorasExtra { get; set; } = default!; + + } +} diff --git a/Models/NominaPercepcionesProperties.cs b/Models/NominaPercepcionesProperties.cs new file mode 100644 index 0000000..e111675 --- /dev/null +++ b/Models/NominaPercepcionesProperties.cs @@ -0,0 +1,38 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Objeto para indicar las percepciones aplicables. + /// + public class NominaPercepcionesProperties + { + /// + /// Objeto con información detallada de cada percepción. + /// Opcional. + /// + [JsonProperty("percepcion")] + public List? Percepcion { get; set; } = default!; + + /// + /// jubilacion_pension_retiro + /// Opcional. + /// + [JsonProperty("jubilacion_pension_retiro")] + public NominaJubilacionProperties? JubilacionPensionRetiro { get; set; } = default!; + + /// + /// separacion_indemnizacion + /// Opcional. + /// + [JsonProperty("separacion_indemnizacion")] + public NominaSeparacionProperties? SeparacionIndemnizacion { get; set; } = default!; + + } +} diff --git a/Models/NominaReceptorProperties.cs b/Models/NominaReceptorProperties.cs new file mode 100644 index 0000000..fddd988 --- /dev/null +++ b/Models/NominaReceptorProperties.cs @@ -0,0 +1,150 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Información del trabajador. + /// + public class NominaReceptorProperties + { + /// + /// CURP del trabajador. + /// Opcional. + /// + [JsonProperty("curp")] + public string? Curp { get; set; } = default!; + + /// + /// Número de seguridad social. + /// Opcional. + /// + [JsonProperty("num_seguridad_social")] + public string? NumSeguridadSocial { get; set; } = default!; + + /// + /// Fecha de inicio de la relación laboral entre el empleador y el empleado. + /// Opcional. + /// + [JsonProperty("fecha_inicio_rel_laboral")] + public OneOf? FechaInicioRelLaboral { get; set; } = default!; + + /// + /// Antigüedad del empleado en el formato especificado por el SAT. Si se envía un `string`, se espera que éste contenga la antigüedad en el formato que especifica el SAT. Si se envía el valor booleano `false`, este campo no se incluirá en la factura. Si se envía el valor booleano `true` y `fecha_inicio_rel_laboral` existe, este valor se calculará con la diferencia entre la fecha de inicio de relación laboral y la fecha de pago. + /// Opcional. + /// + [JsonProperty("antiguedad")] + public OneOf? Antiguedad { get; set; } = default!; + + /// + /// Clave del catálogo del SAT [Tipo de Contrato](https://docs.facturapi.io/api/#tipo-de-contrato). + /// Opcional. + /// + [JsonProperty("tipo_contrato")] + public string? TipoContrato { get; set; } = default!; + + /// + /// Indica si el trabajador está asociado a un sindicato. + /// Opcional. + /// + [JsonProperty("sindicalizado")] + public bool? Sindicalizado { get; set; } = default!; + + /// + /// Clave del catálogo del SAT [Tipo de Jornada](https://docs.facturapi.io/api/#tipo-de-jornada). + /// Opcional. + /// + [JsonProperty("tipo_jornada")] + public string? TipoJornada { get; set; } = default!; + + /// + /// Clave del catálogo del SAT [Tipo de Régimen](https://docs.facturapi.io/api/#régimen-fiscal). + /// Opcional. + /// + [JsonProperty("tipo_regimen")] + public string? TipoRegimen { get; set; } = default!; + + /// + /// Número interno de empleado, asignado por el empleador. + /// Opcional. + /// + [JsonProperty("num_empleado")] + public string? NumEmpleado { get; set; } = default!; + + /// + /// Nombre del departamento o área a la que pertenece el trabajador. + /// Opcional. + /// + [JsonProperty("departamento")] + public string? Departamento { get; set; } = default!; + + /// + /// Nombre del puesto asignado al empleado o el nombre de la actividad que realiza. + /// Opcional. + /// + [JsonProperty("puesto")] + public string? Puesto { get; set; } = default!; + + /// + /// Clave del catálogo del SAT [Riesgo del Puesto](https://docs.facturapi.io/api/#riesgo-del-puesto). + /// Opcional. + /// + [JsonProperty("riesgo_puesto")] + public string? RiesgoPuesto { get; set; } = default!; + + /// + /// Clave del catálogo del SAT [Periodicidad de Pago](https://docs.facturapi.io/api/#periodicidad-del-pago). + /// Opcional. + /// + [JsonProperty("periodicidad_pago")] + public string? PeriodicidadPago { get; set; } = default!; + + /// + /// Clave del banco de acuerdo al catálogo del SAT “Bancos” que puedes consultar utilizando nuestra [herramienta de búsqueda](https://dashboard.facturapi.io/catalogs/bank). + /// Opcional. + /// + [JsonProperty("banco")] + public string? Banco { get; set; } = default!; + + /// + /// Número de cuenta bancaria (11 caracteres) o número de teléfono celular (10 caracteres) o número de tarjeta (15 ó 16 caracteres) o la CLABE (18 caracteres) o número de monedero electrónico donde se realiza el depósito de nómina. + /// Opcional. + /// + [JsonProperty("cuenta_bancaria")] + public string? CuentaBancaria { get; set; } = default!; + + /// + /// Importe de la retribución en efectivo por cuota diaria, gratificaciones, percepciones, alimentación, habitación, primas, comisiones, prestaciones en especie, etc. + /// Opcional. + /// + [JsonProperty("salario_base_cot_apor")] + public decimal? SalarioBaseCotApor { get; set; } = default!; + + /// + /// Salario que se integra con los pagos hechos en efectivo por cuota diaria, gratificaciones, percepciones, habitación, primas, comisiones, prestaciones en especie y cualquier otra cantidad o prestación que se entregue al trabajador por su trabajo. + /// Opcional. + /// + [JsonProperty("salario_diario_integrado")] + public decimal? SalarioDiarioIntegrado { get; set; } = default!; + + /// + /// Clave de la entidad federativa en donde el trabajador prestó sus servicios al empleador, que puedes consultar utilizando nuestra [herramienta de búsqueda](https://dashboard.facturapi.io/catalogs/state). + /// Opcional. + /// + [JsonProperty("clave_ent_fed")] + public string? ClaveEntFed { get; set; } = default!; + + /// + /// Arreglo de objetos para expresar información sobre la empresa que se beneficia del trabajo del empleado, en casos donde el emisor preste servicios de subcontratación. + /// Opcional. + /// + [JsonProperty("sub_contratacion")] + public List? SubContratacion { get; set; } = default!; + + } +} diff --git a/Models/NominaSeparacionProperties.cs b/Models/NominaSeparacionProperties.cs new file mode 100644 index 0000000..7e16b7e --- /dev/null +++ b/Models/NominaSeparacionProperties.cs @@ -0,0 +1,52 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Objeto con información detallada de pagos por separación (despido) o indemnización. + /// + public class NominaSeparacionProperties + { + /// + /// Monto total pagado por concepto de separación o indemnización. + /// Opcional. + /// + [JsonProperty("total_pagado")] + public decimal? TotalPagado { get; set; } = default!; + + /// + /// Años de servicio que laboró el trabajador, redondeado al entero inmediato superior. + /// Opcional. + /// + [JsonProperty("num_anos_servicio")] + public int? NumAnosServicio { get; set; } = default!; + + /// + /// Último sueldo mensual ordinario percibido por el trabajador. + /// Opcional. + /// + [JsonProperty("ultimo_sueldo_mens_ord")] + public decimal? UltimoSueldoMensOrd { get; set; } = default!; + + /// + /// Monto por ingresos acumulables. + /// Opcional. + /// + [JsonProperty("ingreso_acumulable")] + public decimal? IngresoAcumulable { get; set; } = default!; + + /// + /// Monto por ingresos no acumulables. + /// Opcional. + /// + [JsonProperty("ingreso_no_acumulable")] + public decimal? IngresoNoAcumulable { get; set; } = default!; + + } +} diff --git a/Models/NominaSubContratacionProperties.cs b/Models/NominaSubContratacionProperties.cs new file mode 100644 index 0000000..6b60588 --- /dev/null +++ b/Models/NominaSubContratacionProperties.cs @@ -0,0 +1,31 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// NominaSubContratacionProperties + /// + public class NominaSubContratacionProperties + { + /// + /// RFC de la persona o empresa que subcontrata, es decir, de la persona o empresa en donde el trabajador prestó directamente sus servicios. + /// Opcional. + /// + [JsonProperty("rfc_labora")] + public string? RfcLabora { get; set; } = default!; + + /// + /// Porcentaje de tiempo en que el trabajador prestó sus servicios a la persona o empresa que lo subcontrató. + /// Opcional. + /// + [JsonProperty("porcentaje_tiempo")] + public decimal? PorcentajeTiempo { get; set; } = default!; + + } +} diff --git a/Models/OkResponse.cs b/Models/OkResponse.cs new file mode 100644 index 0000000..e5c705f --- /dev/null +++ b/Models/OkResponse.cs @@ -0,0 +1,24 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OkResponse + /// + public class OkResponse + { + /// + /// ok + /// Requerido. + /// + [JsonProperty("ok")] + public bool Ok { get; set; } = default!; + + } +} diff --git a/Models/OneOf2.cs b/Models/OneOf2.cs new file mode 100644 index 0000000..6955798 --- /dev/null +++ b/Models/OneOf2.cs @@ -0,0 +1,42 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// Una de las alternativas del contrato. Se serializa sin envoltura JSON. + /// + [JsonConverter(typeof(OneOfConverter))] + public readonly struct OneOf : IOneOfValue + { + /// + /// Valor de la alternativa seleccionada. + /// + public object? Value { get; } + private OneOf(object? value) { Value = value; } + internal static OneOf FromValue(object? value) => new OneOf(value); + /// + /// Selecciona la alternativa 1. + /// + public static implicit operator OneOf(T1 value) => new OneOf(value); + /// + /// Selecciona la alternativa 2. + /// + public static implicit operator OneOf(T2 value) => new OneOf(value); + /// + /// Obtiene el valor cuando coincide con el tipo solicitado. + /// + public bool TryGet(out T value) + { + if (Value is T match) { value = match; return true; } + value = default!; + return false; + } + /// + /// Representación del valor seleccionado. + /// + public override string ToString() => Value?.ToString() ?? string.Empty; + } +} diff --git a/Models/OneOf3.cs b/Models/OneOf3.cs new file mode 100644 index 0000000..e921895 --- /dev/null +++ b/Models/OneOf3.cs @@ -0,0 +1,46 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// Una de las alternativas del contrato. Se serializa sin envoltura JSON. + /// + [JsonConverter(typeof(OneOfConverter))] + public readonly struct OneOf : IOneOfValue + { + /// + /// Valor de la alternativa seleccionada. + /// + public object? Value { get; } + private OneOf(object? value) { Value = value; } + internal static OneOf FromValue(object? value) => new OneOf(value); + /// + /// Selecciona la alternativa 1. + /// + public static implicit operator OneOf(T1 value) => new OneOf(value); + /// + /// Selecciona la alternativa 2. + /// + public static implicit operator OneOf(T2 value) => new OneOf(value); + /// + /// Selecciona la alternativa 3. + /// + public static implicit operator OneOf(T3 value) => new OneOf(value); + /// + /// Obtiene el valor cuando coincide con el tipo solicitado. + /// + public bool TryGet(out T value) + { + if (Value is T match) { value = match; return true; } + value = default!; + return false; + } + /// + /// Representación del valor seleccionado. + /// + public override string ToString() => Value?.ToString() ?? string.Empty; + } +} diff --git a/Models/OneOf4.cs b/Models/OneOf4.cs new file mode 100644 index 0000000..0276e0a --- /dev/null +++ b/Models/OneOf4.cs @@ -0,0 +1,50 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// Una de las alternativas del contrato. Se serializa sin envoltura JSON. + /// + [JsonConverter(typeof(OneOfConverter))] + public readonly struct OneOf : IOneOfValue + { + /// + /// Valor de la alternativa seleccionada. + /// + public object? Value { get; } + private OneOf(object? value) { Value = value; } + internal static OneOf FromValue(object? value) => new OneOf(value); + /// + /// Selecciona la alternativa 1. + /// + public static implicit operator OneOf(T1 value) => new OneOf(value); + /// + /// Selecciona la alternativa 2. + /// + public static implicit operator OneOf(T2 value) => new OneOf(value); + /// + /// Selecciona la alternativa 3. + /// + public static implicit operator OneOf(T3 value) => new OneOf(value); + /// + /// Selecciona la alternativa 4. + /// + public static implicit operator OneOf(T4 value) => new OneOf(value); + /// + /// Obtiene el valor cuando coincide con el tipo solicitado. + /// + public bool TryGet(out T value) + { + if (Value is T match) { value = match; return true; } + value = default!; + return false; + } + /// + /// Representación del valor seleccionado. + /// + public override string ToString() => Value?.ToString() ?? string.Empty; + } +} diff --git a/Models/OneOf6.cs b/Models/OneOf6.cs new file mode 100644 index 0000000..4a011b3 --- /dev/null +++ b/Models/OneOf6.cs @@ -0,0 +1,58 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// Una de las alternativas del contrato. Se serializa sin envoltura JSON. + /// + [JsonConverter(typeof(OneOfConverter))] + public readonly struct OneOf : IOneOfValue + { + /// + /// Valor de la alternativa seleccionada. + /// + public object? Value { get; } + private OneOf(object? value) { Value = value; } + internal static OneOf FromValue(object? value) => new OneOf(value); + /// + /// Selecciona la alternativa 1. + /// + public static implicit operator OneOf(T1 value) => new OneOf(value); + /// + /// Selecciona la alternativa 2. + /// + public static implicit operator OneOf(T2 value) => new OneOf(value); + /// + /// Selecciona la alternativa 3. + /// + public static implicit operator OneOf(T3 value) => new OneOf(value); + /// + /// Selecciona la alternativa 4. + /// + public static implicit operator OneOf(T4 value) => new OneOf(value); + /// + /// Selecciona la alternativa 5. + /// + public static implicit operator OneOf(T5 value) => new OneOf(value); + /// + /// Selecciona la alternativa 6. + /// + public static implicit operator OneOf(T6 value) => new OneOf(value); + /// + /// Obtiene el valor cuando coincide con el tipo solicitado. + /// + public bool TryGet(out T value) + { + if (Value is T match) { value = match; return true; } + value = default!; + return false; + } + /// + /// Representación del valor seleccionado. + /// + public override string ToString() => Value?.ToString() ?? string.Empty; + } +} diff --git a/Models/OneOf7.cs b/Models/OneOf7.cs new file mode 100644 index 0000000..6d7d2b1 --- /dev/null +++ b/Models/OneOf7.cs @@ -0,0 +1,62 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using Newtonsoft.Json; + +namespace Facturapi +{ + /// + /// Una de las alternativas del contrato. Se serializa sin envoltura JSON. + /// + [JsonConverter(typeof(OneOfConverter))] + public readonly struct OneOf : IOneOfValue + { + /// + /// Valor de la alternativa seleccionada. + /// + public object? Value { get; } + private OneOf(object? value) { Value = value; } + internal static OneOf FromValue(object? value) => new OneOf(value); + /// + /// Selecciona la alternativa 1. + /// + public static implicit operator OneOf(T1 value) => new OneOf(value); + /// + /// Selecciona la alternativa 2. + /// + public static implicit operator OneOf(T2 value) => new OneOf(value); + /// + /// Selecciona la alternativa 3. + /// + public static implicit operator OneOf(T3 value) => new OneOf(value); + /// + /// Selecciona la alternativa 4. + /// + public static implicit operator OneOf(T4 value) => new OneOf(value); + /// + /// Selecciona la alternativa 5. + /// + public static implicit operator OneOf(T5 value) => new OneOf(value); + /// + /// Selecciona la alternativa 6. + /// + public static implicit operator OneOf(T6 value) => new OneOf(value); + /// + /// Selecciona la alternativa 7. + /// + public static implicit operator OneOf(T7 value) => new OneOf(value); + /// + /// Obtiene el valor cuando coincide con el tipo solicitado. + /// + public bool TryGet(out T value) + { + if (Value is T match) { value = match; return true; } + value = default!; + return false; + } + /// + /// Representación del valor seleccionado. + /// + public override string ToString() => Value?.ToString() ?? string.Empty; + } +} diff --git a/Models/Organization.cs b/Models/Organization.cs index cfab599..6a22606 100644 --- a/Models/Organization.cs +++ b/Models/Organization.cs @@ -1,19 +1,149 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// Objeto Organization + /// public class Organization { - public string Id { get; set; } - public DateTime CreatedAt { get; set; } - public bool IsProductionReady { get; set; } - public List PendingSteps { get; set; } - public Legal Legal { get; set; } - public Customization Customization { get; set; } - public SelfInvoiceSettings SelfInvoice { get; set; } - public Certificate Certificate { get; set; } - public List ApiKeys { get; set; } - public List AddOns { get; set; } + /// + /// ID del objeto + /// Requerido. + /// + [JsonProperty("id")] + public string Id { get; set; } = default!; + + /// + /// Format: uri + /// URL del logotipo de la organización. + /// Opcional. + /// + [JsonProperty("logo_url")] + public string? LogoUrl { get; set; } = default!; + + /// + /// Zona horaria de la organización, en formato IANA. + /// Opcional. + /// + [JsonProperty("timezone")] + public string? Timezone { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de registro + /// Requerido. + /// + [JsonProperty("created_at")] + public DateTime CreatedAt { get; set; } = default!; + + /// + /// Indica si la organización tiene información necesaria para facturar en ambiente Live. + /// Opcional. + /// + [JsonProperty("is_production_ready")] + public bool? IsProductionReady { get; set; } = default!; + + /// + /// Lista de pasos que se necesitan completar para que esta organización pueda emitir facturas válidas en ambiente Live. + /// Opcional. + /// + [JsonProperty("pending_steps")] + public List? PendingSteps { get; set; } = default!; + + /// + /// Datos fiscales de la empresa. + /// Opcional. + /// + [JsonProperty("legal")] + public Legal? Legal { get; set; } = default!; + + /// + /// Configuración de personalización de la organización, que se utilizarán para reflejar el branding y + /// las preferencias de PDFs de la organización. Estos datos se pueden actualizar en cualquier momento. + /// Opcional. + /// + [JsonProperty("customization")] + public Customization? Customization { get; set; } = default!; + + /// + /// Información útil sobre el certificado de sello digital (CSD) de la organización, que se utilizará para firmar las facturas. + /// Requerido. + /// + [JsonProperty("certificate")] + public Certificate Certificate { get; set; } = default!; + + /// + /// Información sobre el certificado FIEL de la organización, que se utiliza para el servicio de descarga masiva de CFDI. + /// Requerido. + /// + [JsonProperty("fiel")] + public FielCertificate Fiel { get; set; } = default!; + + /// + /// Configuración para recibos y la emisión de facturas globales a partir de recibos. + /// Opcional. + /// + [JsonProperty("receipts")] + public OrganizationReceipts? Receipts { get; set; } = default!; + + /// + /// Configuraciones para el portal de autofactura, que permite a los clientes facturar sus recibos a través de un micrositio. + /// Opcional. + /// + [JsonProperty("self_invoice")] + public SelfInvoiceSettings? SelfInvoice { get; set; } = default!; + + /// + /// Plan heredado de la organización. + /// Opcional. + /// Admite null. + /// + [JsonProperty("plan")] + public string? Plan { get; set; } = default!; + + /// + /// Funcionalidades adicionales contratadas por la organización. + /// Opcional. + /// + [JsonProperty("add_ons")] + public List? AddOns { get; set; } = default!; + + /// + /// Cambio de plan programado, si existe. + /// Opcional. + /// Admite null. + /// + [JsonProperty("pending_plan_update")] + public OrganizationPendingPlanUpdate? PendingPlanUpdate { get; set; } = default!; + + /// + /// Cambio programado de funcionalidades adicionales, si existe. + /// Opcional. + /// Admite null. + /// + [JsonProperty("pending_add_ons_update")] + public OrganizationPendingAddOnsUpdate? PendingAddOnsUpdate { get; set; } = default!; + + /// + /// domain + /// Opcional. + /// + [JsonProperty("domain")] + public string? Domain { get; set; } = default!; + + /// + /// custom_domain + /// Opcional. + /// + [JsonProperty("custom_domain")] + public string? CustomDomain { get; set; } = default!; + } } diff --git a/Models/OrganizationDeleteCerts.cs b/Models/OrganizationDeleteCerts.cs new file mode 100644 index 0000000..a9b55d4 --- /dev/null +++ b/Models/OrganizationDeleteCerts.cs @@ -0,0 +1,25 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationDeleteCerts + /// + public class OrganizationDeleteCerts + { + /// + /// Format: date-time + /// Fecha de eliminación del certificado CSD. + /// Opcional. + /// + [JsonProperty("updated_at")] + public DateTime? UpdatedAt { get; set; } = default!; + + } +} diff --git a/Models/OrganizationInvite.cs b/Models/OrganizationInvite.cs index aebd23d..c864635 100644 --- a/Models/OrganizationInvite.cs +++ b/Models/OrganizationInvite.cs @@ -1,17 +1,79 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// OrganizationInvite + /// public class OrganizationInvite { - public string Id { get; set; } - public DateTime? CreatedAt { get; set; } - public string Email { get; set; } - public string OrganizationName { get; set; } - public string Role { get; set; } - public string RoleName { get; set; } - public List Roles { get; set; } - public DateTime? ExpiresAt { get; set; } + /// + /// Identificador único de la invitación. + /// Opcional. + /// + [JsonProperty("id")] + public string? Id { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha y hora en que se creó la invitación. + /// Requerido. + /// + [JsonProperty("created_at")] + public DateTime CreatedAt { get; set; } = default!; + + /// + /// Format: email + /// Correo electrónico al que se envió la invitación. + /// Opcional. + /// + [JsonProperty("email")] + public string? Email { get; set; } = default!; + + /// + /// Nombre de la organización que envió la invitación. + /// Opcional. + /// + [JsonProperty("organization_name")] + public string? OrganizationName { get; set; } = default!; + + /// + /// ID del rol asignado en la invitación, si existe. + /// Opcional. + /// Admite null. + /// + [JsonProperty("role")] + public string? Role { get; set; } = default!; + + /// + /// Nombre del rol asignado en la invitación, si existe. + /// Opcional. + /// Admite null. + /// + [JsonProperty("role_name")] + public string? RoleName { get; set; } = default!; + + /// + /// Lista de roles visibles que describe el acceso otorgado por la invitación. + /// Opcional. + /// + [JsonProperty("roles")] + public List? Roles { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha y hora en que expira la invitación. + /// Requerido. + /// Admite null. + /// + [JsonProperty("expires_at")] + public DateTime? ExpiresAt { get; set; } = default!; + } } diff --git a/Models/OrganizationPendingAddOnsUpdate.cs b/Models/OrganizationPendingAddOnsUpdate.cs new file mode 100644 index 0000000..26f03e0 --- /dev/null +++ b/Models/OrganizationPendingAddOnsUpdate.cs @@ -0,0 +1,31 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationPendingAddOnsUpdate + /// + public class OrganizationPendingAddOnsUpdate + { + /// + /// add_ons + /// Opcional. + /// + [JsonProperty("add_ons")] + public List? AddOns { get; set; } = default!; + + /// + /// Format: date-time + /// Opcional. + /// + [JsonProperty("scheduled_for")] + public DateTime? ScheduledFor { get; set; } = default!; + + } +} diff --git a/Models/OrganizationPendingPlanUpdate.cs b/Models/OrganizationPendingPlanUpdate.cs new file mode 100644 index 0000000..558186a --- /dev/null +++ b/Models/OrganizationPendingPlanUpdate.cs @@ -0,0 +1,31 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationPendingPlanUpdate + /// + public class OrganizationPendingPlanUpdate + { + /// + /// plan + /// Opcional. + /// + [JsonProperty("plan")] + public string? Plan { get; set; } = default!; + + /// + /// Format: date-time + /// Opcional. + /// + [JsonProperty("scheduled_for")] + public DateTime? ScheduledFor { get; set; } = default!; + + } +} diff --git a/Models/OrganizationReceipts.cs b/Models/OrganizationReceipts.cs new file mode 100644 index 0000000..5e252ce --- /dev/null +++ b/Models/OrganizationReceipts.cs @@ -0,0 +1,68 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationReceipts + /// + public class OrganizationReceipts + { + /// + /// Periodicidad con la que la empresa decide emitir una factura global + /// (al público en general) por todos los recibos que no se hayan facturado. + /// Este valor se utiliza como el default al crear una factura global. + /// Valores: "day", "week", "fortnight", "month", "two_months". + /// Opcional. + /// + [JsonProperty("periodicity")] + public string? Periodicity { get; set; } = default!; + + /// + /// Número máximo de días para facturar a través del portal de autofactura + /// después de que se emite el recibo y antes del último día del periodo. + /// Opcional. + /// + [JsonProperty("duration_days")] + public int? DurationDays { get; set; } = default!; + + /// + /// Número de folio que se asignará al siguiente recibo en ambiente Live. + /// Se incrementará automáticamente por cada nuevo recibo. + /// Opcional. + /// + [JsonProperty("next_folio_number")] + public int? NextFolioNumber { get; set; } = default!; + + /// + /// Número de folio que se asignará al siguiente recibo en ambiente Test. + /// Se incrementará automáticamente por cada nuevo recibo. + /// Opcional. + /// + [JsonProperty("next_folio_number_test")] + public int? NextFolioNumberTest { get; set; } = default!; + + /// + /// Indica si la organización genera automáticamente una factura global + /// después de cerrar cada periodo configurado. Requiere tener contratado + /// el feature de factura global. + /// Opcional. + /// + [JsonProperty("activate_global_invoice")] + public bool? ActivateGlobalInvoice { get; set; } = default!; + + /// + /// Agrupa conceptos equivalentes al facturar varios recibos seleccionados, + /// incluyendo las autofacturas. No modifica la generación de facturas globales. + /// Opcional. + /// + [JsonProperty("grouped_items_invoice")] + public bool? GroupedItemsInvoice { get; set; } = default!; + + } +} diff --git a/Models/OrganizationSeriesDeletion.cs b/Models/OrganizationSeriesDeletion.cs new file mode 100644 index 0000000..31d9f1f --- /dev/null +++ b/Models/OrganizationSeriesDeletion.cs @@ -0,0 +1,52 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// OrganizationSeriesDeletion + /// + public class OrganizationSeriesDeletion + { + /// + /// series + /// Opcional. + /// + [JsonProperty("series")] + public string? Series { get; set; } = default!; + + /// + /// livemode + /// Opcional. + /// + [JsonProperty("livemode")] + public bool? Livemode { get; set; } = default!; + + /// + /// next_folio + /// Opcional. + /// + [JsonProperty("next_folio")] + public int? NextFolio { get; set; } = default!; + + /// + /// Format: date-time + /// Opcional. + /// + [JsonProperty("created_at")] + public DateTime? CreatedAt { get; set; } = default!; + + /// + /// Format: date-time + /// Opcional. + /// + [JsonProperty("updated_at")] + public DateTime? UpdatedAt { get; set; } = default!; + + } +} diff --git a/Models/OrganizationTeamRole.cs b/Models/OrganizationTeamRole.cs index 1f82574..69f0ab9 100644 --- a/Models/OrganizationTeamRole.cs +++ b/Models/OrganizationTeamRole.cs @@ -1,20 +1,93 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// OrganizationTeamRole + /// public class OrganizationTeamRole { - public string Id { get; set; } - public string Name { get; set; } - public string TemplateCode { get; set; } - public string Scope { get; set; } - public string Organization { get; set; } - public List Operations { get; set; } - public int UsedBy { get; set; } - public DateTime? CreatedAt { get; set; } - public DateTime? UpdatedAt { get; set; } - public Dictionary CreatedBy { get; set; } - public Dictionary UpdatedBy { get; set; } + /// + /// Identificador único del rol. + /// Opcional. + /// + [JsonProperty("id")] + public string? Id { get; set; } = default!; + + /// + /// Nombre del rol. + /// Opcional. + /// + [JsonProperty("name")] + public string? Name { get; set; } = default!; + + /// + /// Código de plantilla base del rol, si proviene de una plantilla del sistema. + /// Opcional. + /// Admite null. + /// + [JsonProperty("template_code")] + public string? TemplateCode { get; set; } = default!; + + /// + /// ID de la organización a la que pertenece el rol. + /// Opcional. + /// Admite null. + /// + [JsonProperty("organization")] + public string? Organization { get; set; } = default!; + + /// + /// Número de usuarios que actualmente usan este rol. + /// Opcional. + /// + [JsonProperty("used_by")] + public int? UsedBy { get; set; } = default!; + + /// + /// Operaciones agregadas al rol además de las definidas por su plantilla. + /// Opcional. + /// + [JsonProperty("overrides_add")] + public List? OverridesAdd { get; set; } = default!; + + /// + /// Operaciones removidas del rol respecto a su plantilla. + /// Opcional. + /// + [JsonProperty("overrides_remove")] + public List? OverridesRemove { get; set; } = default!; + + /// + /// Lista final de operaciones permitidas por este rol. + /// Opcional. + /// + [JsonProperty("operations")] + public List? Operations { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha y hora de creación del rol. + /// Requerido. + /// Admite null. + /// + [JsonProperty("created_at")] + public DateTime? CreatedAt { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha y hora de la última actualización del rol. + /// Requerido. + /// Admite null. + /// + [JsonProperty("updated_at")] + public DateTime? UpdatedAt { get; set; } = default!; + } } diff --git a/Models/OrganizationTeamRoleTemplate.cs b/Models/OrganizationTeamRoleTemplate.cs index 3b5a662..11ac405 100644 --- a/Models/OrganizationTeamRoleTemplate.cs +++ b/Models/OrganizationTeamRoleTemplate.cs @@ -1,12 +1,39 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// OrganizationTeamRoleTemplate + /// public class OrganizationTeamRoleTemplate { - public string Code { get; set; } - public string Name { get; set; } - public string Description { get; set; } - public List Operations { get; set; } + /// + /// Código interno de la plantilla de rol. + /// Valores: "org-admin", "org-readonly", "org-billing", "org-developer", "org-team-manager". + /// Opcional. + /// + [JsonProperty("code")] + public string? Code { get; set; } = default!; + + /// + /// Nombre visible de la plantilla de rol. + /// Opcional. + /// + [JsonProperty("label")] + public string? Label { get; set; } = default!; + + /// + /// Operaciones incluidas por defecto en la plantilla. + /// Opcional. + /// + [JsonProperty("operations")] + public List? Operations { get; set; } = default!; + } } diff --git a/Models/OrganizationUserAccess.cs b/Models/OrganizationUserAccess.cs index 539de74..7c7f461 100644 --- a/Models/OrganizationUserAccess.cs +++ b/Models/OrganizationUserAccess.cs @@ -1,18 +1,86 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// OrganizationUserAccess + /// public class OrganizationUserAccess { - public string Id { get; set; } - public string FullName { get; set; } - public string Email { get; set; } - public string Role { get; set; } - public string RoleName { get; set; } - public string Organization { get; set; } - public List Operations { get; set; } - public DateTime? CreatedAt { get; set; } - public DateTime? UpdatedAt { get; set; } + /// + /// Identificador del acceso del usuario dentro de la organización. Para el propietario, este valor es `owner` porque su acceso es implícito. + /// Opcional. + /// + [JsonProperty("id")] + public string? Id { get; set; } = default!; + + /// + /// Nombre completo del usuario. + /// Opcional. + /// + [JsonProperty("full_name")] + public string? FullName { get; set; } = default!; + + /// + /// Format: email + /// Correo electrónico del usuario. + /// Opcional. + /// + [JsonProperty("email")] + public string? Email { get; set; } = default!; + + /// + /// ID del rol asignado al usuario, si existe. Para el propietario, este valor es `null` porque su acceso es implícito. + /// Opcional. + /// Admite null. + /// + [JsonProperty("role")] + public string? Role { get; set; } = default!; + + /// + /// Nombre del rol asignado o del acceso implícito del usuario. Para el propietario, este valor es `owner`. + /// Opcional. + /// Admite null. + /// + [JsonProperty("role_name")] + public string? RoleName { get; set; } = default!; + + /// + /// ID de la organización a la que pertenece el acceso. + /// Opcional. + /// Admite null. + /// + [JsonProperty("organization")] + public string? Organization { get; set; } = default!; + + /// + /// Lista final de operaciones permitidas para el usuario. + /// Opcional. + /// + [JsonProperty("operations")] + public List? Operations { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha y hora en que se creó el acceso. Para el propietario, corresponde a la creación de la organización. + /// Requerido. + /// + [JsonProperty("created_at")] + public DateTime CreatedAt { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha y hora de la última actualización del acceso. Para el propietario, corresponde a la creación de la organización porque su acceso es implícito. + /// Requerido. + /// + [JsonProperty("updated_at")] + public DateTime UpdatedAt { get; set; } = default!; + } } diff --git a/Models/Payment.cs b/Models/Payment.cs index 7cf12db..5384053 100644 --- a/Models/Payment.cs +++ b/Models/Payment.cs @@ -1,24 +1,127 @@ -using System; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// Payment + /// public class Payment { - public string PaymentForm { get; set; } - public string Currency { get; set; } - public Decimal Exchange { get; set; } - public DateTime Date { get; set; } - public List Related {get;set;} - } + /// + /// Código de la forma de pago según el [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). También puedes utilizar la constante `PaymentForm` incluida en nuestras librerías. + /// Requerido. + /// + [JsonProperty("payment_form")] + public string PaymentForm { get; set; } = default!; + + /// + /// Arreglo que incluye un elemento por cada comprobante de ingreso relacionado a este pago. Lo más común es que el pago esté relacionado a un sólo comprobante de ingreso. Un caso en el que se agrega más de un elemento es cuando se recibe (por ejemplo) un sólo depósito que ampara el pago de 2 facturas relacionadas. En lugar de expedir un comprobante de recepción de pago por cada factura, debes expedir sólo uno relacionando los 2 comprobantes. + /// Requerido. + /// + [JsonProperty("related_documents")] + public List RelatedDocuments { get; set; } = default!; + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonProperty("currency")] + public string? Currency { get; set; } = default!; + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Opcional. + /// + [JsonProperty("exchange")] + public decimal? Exchange { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha en que se recibió el pago. Si se omite, se utiliza la fecha y hora actuales. Inclúyela cuando el pago sea anterior a la emisión del comprobante. No se permiten fechas futuras. + /// Requerido. + /// + [JsonProperty("date")] + public DateTime Date { get; set; } = default!; + + /// + /// Número de cheque, de autorización, de referencia, clave de rastreo SPEI, línea de captura o algún número de referencia que permita identificar la operación correspondiente al pago efectuado. + /// Opcional. + /// + [JsonProperty("numOperacion")] + public string? NumOperacion { get; set; } = default!; + + /// + /// RFC de la entidad emisora de la cuenta de origen, es decir, la operadora, banco, institución financiera, emisor de monedero electrónico, etc. + /// Opcional. + /// + [JsonProperty("rfcEmisorCtaOrd")] + public string? RfcEmisorCtaOrd { get; set; } = default!; + + /// + /// Nombre del banco ordenante. + /// Opcional. + /// + [JsonProperty("nomBancoOrdExt")] + public string? NomBancoOrdExt { get; set; } = default!; + + /// + /// Número de cuenta con la que se realizó el pago. + /// Opcional. + /// + [JsonProperty("ctaOrdenante")] + public string? CtaOrdenante { get; set; } = default!; + + /// + /// RFC de la entidad de la cuenta operadora destino, es decir, la operadora, banco, institución financiera, emisor de monedero electrónico, etc. + /// Opcional. + /// + [JsonProperty("rfcEmisorCtaBen")] + public string? RfcEmisorCtaBen { get; set; } = default!; + + /// + /// Número de cuenta donde se recibió el pago. + /// Opcional. + /// + [JsonProperty("ctaBeneficiario")] + public string? CtaBeneficiario { get; set; } = default!; + + /// + /// Clave del tipo de cadena de pago que genera la entidad receptora del pago. + /// Si existe este campo, es obligatorio registrar los campos `certPago`, `cadPago` y `selloPago`. + /// Valores: "01". + /// Opcional. + /// + [JsonProperty("tipoCadPago")] + public string? TipoCadPago { get; set; } = default!; + + /// + /// Format: base64 + /// Certificado que corresponde al pago, como una cadena de texto en formato base 64. + /// Opcional. + /// + [JsonProperty("certPago")] + public string? CertPago { get; set; } = default!; + + /// + /// Cadena original del comprobante de pago generado por la entidad emisora de la cuenta beneficiaria. + /// Opcional. + /// + [JsonProperty("cadPago")] + public string? CadPago { get; set; } = default!; + + /// + /// Format: base64 + /// Sello digital que se asocie al pago expresado como una cadena de texto en formato base 64. + /// Opcional. + /// + [JsonProperty("selloPago")] + public string? SelloPago { get; set; } = default!; - public class PaymentRelated - { - public string Uuid { get; set; } - public int Installment { get; set; } - public Decimal LastBalance { get; set; } - public Decimal Amount { get; set; } - public string Currency { get; set; } - public Decimal Exchange { get; set; } } } diff --git a/Models/PaymentRelated.cs b/Models/PaymentRelated.cs new file mode 100644 index 0000000..b97d212 --- /dev/null +++ b/Models/PaymentRelated.cs @@ -0,0 +1,31 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// PaymentRelated + /// + public class PaymentRelated + { + /// + /// Clave de relación del catálogo del SAT que puedes consultar en [esta tabla](https://docs.facturapi.io/api/#relacion-entre-facturas). Es requerido cuando se envíe el parámetro `related_documents`. + /// Opcional. + /// + [JsonProperty("relationship")] + public string? Relationship { get; set; } = default!; + + /// + /// Folios fiscales (UUID) de facturas relacionadas. + /// Opcional. + /// + [JsonProperty("documents")] + public List? Documents { get; set; } = default!; + + } +} diff --git a/Models/PaymentRelatedDocumentsItem.cs b/Models/PaymentRelatedDocumentsItem.cs new file mode 100644 index 0000000..de7d8b4 --- /dev/null +++ b/Models/PaymentRelatedDocumentsItem.cs @@ -0,0 +1,104 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// PaymentRelatedDocumentsItem + /// + public class PaymentRelatedDocumentsItem + { + /// + /// Format: uuid + /// Folio fiscal ó UUID del comprobante de ingreso relacionado. + /// Requerido. + /// + [JsonProperty("uuid")] + public string Uuid { get; set; } = default!; + + /// + /// Cantidad del pago correspondiente al comprobante relacionado, + /// usando el método de pago indicado en este elemento del arreglo + /// de pagos. Este valor debe ser expresado en la moneda definida + /// en `related_documents[].currency`. + /// Requerido. + /// + [JsonProperty("amount")] + public decimal Amount { get; set; } = default!; + + /// + /// Arreglo con impuestos del documento relacionado que aplican al pago realizado. + /// Requerido. + /// + [JsonProperty("taxes")] + public List Taxes { get; set; } = default!; + + /// + /// Código que representa si el bien o servicio es objeto de impuesto o no. Este atributo corresponde al campo "ObjetoImp" en el CFDI. + /// + /// - `01`: No objeto de impuesto. + /// - `02`: Sí objeto de impuesto. + /// - `03`: Sí objeto de impuesto, pero no obligado a desglose. + /// - `04`: Sí objeto de impuesto, y no causa impuesto. + /// - `05`: Sí objeto de impuesto, IVA crédito PODEBI. + /// - `06`: Sí objeto de impuesto, no IVA trasladado. + /// - `07`: No traslado de IVA, pero desglose de IEPS. + /// - `08`: No traslado de IVA sin desglose de IEPS. + /// + /// Si se omite, se utiliza `01` cuando `taxes` está vacío y `02` cuando contiene al menos un impuesto. + /// Valores: "01", "04", "02", "03", "05", "06", "07", "08". + /// Opcional. + /// + [JsonProperty("taxability")] + public string? Taxability { get; set; } = default!; + + /// + /// Número de parcialidad del pago. + /// Requerido. + /// + [JsonProperty("installment")] + public int Installment { get; set; } = default!; + + /// + /// Cantidad que estaba pendiente por pagar antes de recibir este pago. Este valor se expresa en la moneda definida en `related_documents[].currency`. + /// Requerido. + /// + [JsonProperty("last_balance")] + public decimal LastBalance { get; set; } = default!; + + /// + /// Si la moneda utilizada en la factura relacionada no es moneda nacional (MXN), debe especificarse su valor acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonProperty("currency")] + public string? Currency { get; set; } = default!; + + /// + /// Obligatorio cuando la moneda del documento relacionado es distinta a la moneda de pago. Tipo de cambio entre las dos monedas al momento del pago. Ejemplo: La factura de ingreso relacionada se registra en USD, mientras que el pago actual se realiza en MXN, este atributo debería registrarse como `0.45` (USD/MXN). + /// Opcional. + /// + [JsonProperty("exchange")] + public decimal? Exchange { get; set; } = default!; + + /// + /// Opcionalmente se puede incluir el número de folio del documento relacionado. + /// Opcional. + /// + [JsonProperty("folio_number")] + public int? FolioNumber { get; set; } = default!; + + /// + /// Opcionalmente se puede incluir la serie del documento relacionado. + /// Opcional. + /// Admite null. + /// + [JsonProperty("series")] + public string? Series { get; set; } = default!; + + } +} diff --git a/Models/PaymentRelatedDocumentsItemTaxesItem.cs b/Models/PaymentRelatedDocumentsItemTaxesItem.cs new file mode 100644 index 0000000..0583756 --- /dev/null +++ b/Models/PaymentRelatedDocumentsItemTaxesItem.cs @@ -0,0 +1,54 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// PaymentRelatedDocumentsItemTaxesItem + /// + public class PaymentRelatedDocumentsItemTaxesItem + { + /// + /// Base utilizada para el cálculo del impuestos. + /// Requerido. + /// + [JsonProperty("base")] + public decimal Base { get; set; } = default!; + + /// + /// Tipo de impuesto. + /// Valores: "IVA", "ISR", "IEPS". + /// Requerido. + /// + [JsonProperty("type")] + public string Type { get; set; } = default!; + + /// + /// Tasa o cuota del impuesto + /// Requerido. + /// + [JsonProperty("rate")] + public decimal Rate { get; set; } = default!; + + /// + /// Tipo factor. + /// Valores: "Tasa", "Cuota", "Exento". + /// Opcional. + /// + [JsonProperty("factor")] + public string? Factor { get; set; } = default!; + + /// + /// Indica si el impuesto es una retención (`true`) o un traslado (`false`). + /// Opcional. + /// + [JsonProperty("withholding")] + public bool? Withholding { get; set; } = default!; + + } +} diff --git a/Models/PaymentSummary.cs b/Models/PaymentSummary.cs index e6c6d4a..b5e62ef 100644 --- a/Models/PaymentSummary.cs +++ b/Models/PaymentSummary.cs @@ -1,26 +1,81 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// PaymentSummary + /// public class PaymentSummary { - public string Uuid { get; set; } - public decimal? FolioNumber { get; set; } - public string Series { get; set; } - public int Installment { get; set; } - public decimal LastBalance { get; set; } - public decimal Total { get; set; } - public string Currency { get; set; } - public decimal Amount { get; set; } - public List Taxes { get; set; } - } + /// + /// UUID de la factura + /// Requerido. + /// + [JsonProperty("uuid")] + public string Uuid { get; set; } = default!; + + /// + /// Folio de la factura. Se omite si la factura no lo tiene registrado. + /// Opcional. + /// + [JsonProperty("folio_number")] + public decimal? FolioNumber { get; set; } = default!; + + /// + /// Serie de la factura + /// Requerido. + /// Admite null. + /// + [JsonProperty("series")] + public string? Series { get; set; } = default!; + + /// + /// Número de parcialidad que corresponde a este pago + /// Requerido. + /// + [JsonProperty("installment")] + public decimal Installment { get; set; } = default!; + + /// + /// Saldo pendiente de la factura antes de aplicar este pago + /// Requerido. + /// + [JsonProperty("last_balance")] + public decimal LastBalance { get; set; } = default!; + + /// + /// Total de la factura + /// Requerido. + /// + [JsonProperty("total")] + public decimal Total { get; set; } = default!; + + /// + /// Divisa de la factura + /// Requerido. + /// + [JsonProperty("currency")] + public string Currency { get; set; } = default!; + + /// + /// Monto que se paga en esta parcialidad + /// Requerido. + /// + [JsonProperty("amount")] + public decimal Amount { get; set; } = default!; + + /// + /// Impuestos de la factura prorrateados al monto pagado + /// Requerido. + /// + [JsonProperty("taxes")] + public List Taxes { get; set; } = default!; - public class PaymentSummaryTax - { - public decimal Base { get; set; } - public decimal Rate { get; set; } - public string Type { get; set; } - public string Factor { get; set; } - public bool Withholding { get; set; } } } diff --git a/Models/PaymentSummaryTax.cs b/Models/PaymentSummaryTax.cs new file mode 100644 index 0000000..7730604 --- /dev/null +++ b/Models/PaymentSummaryTax.cs @@ -0,0 +1,54 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// PaymentSummaryTax + /// + public class PaymentSummaryTax + { + /// + /// Base del impuesto prorrateada al monto pagado + /// Requerido. + /// + [JsonProperty("base")] + public decimal Base { get; set; } = default!; + + /// + /// Tasa o cuota del impuesto + /// Requerido. + /// + [JsonProperty("rate")] + public decimal Rate { get; set; } = default!; + + /// + /// Tipo de impuesto (IVA, ISR, etc.) + /// Valores: "IVA", "ISR", "IEPS". + /// Requerido. + /// + [JsonProperty("type")] + public string Type { get; set; } = default!; + + /// + /// Tipo de factor (Tasa, Exento, etc.) + /// Valores: "Tasa", "Cuota", "Exento". + /// Requerido. + /// + [JsonProperty("factor")] + public string Factor { get; set; } = default!; + + /// + /// Indica si se trata de una retención + /// Requerido. + /// + [JsonProperty("withholding")] + public bool Withholding { get; set; } = default!; + + } +} diff --git a/Models/Product.cs b/Models/Product.cs index 9882d2b..e6e079c 100644 --- a/Models/Product.cs +++ b/Models/Product.cs @@ -1,21 +1,136 @@ -using System; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// Objeto Product + /// public class Product { - public string Id { get; set; } - public bool Livemode { get; set; } - public string ProductKey { get; set; } - public string Description { get; set; } - public Decimal Price { get; set; } - public DateTime CreatedAt { get; set; } - public bool TaxIncluded { get; set; } - public List Taxes { get; set; } - public string UnitKey { get; set; } - public string UnitName { get; set; } - public string Sku { get; set; } - public string Taxability { get; set; } + /// + /// ID del objeto + /// Requerido. + /// + [JsonProperty("id")] + public string Id { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de registro + /// Requerido. + /// + [JsonProperty("created_at")] + public DateTime CreatedAt { get; set; } = default!; + + /// + /// Si el valor es `true`, indica que el objeto fue creado en ambiente Live; o si es `false`, en ambiente Test. + /// Requerido. + /// + [JsonProperty("livemode")] + public bool Livemode { get; set; } = default!; + + /// + /// Palabra que representa la unidad de medida de tu producto. Debe estar relacionada con la clave de unidad `unit_key`. + /// Opcional. + /// Admite null. + /// + [JsonProperty("unit_name")] + public string? UnitName { get; set; } = default!; + + /// + /// Descripción del bien o servicio como aparecerá en la factura. + /// Requerido. + /// + [JsonProperty("description")] + public string Description { get; set; } = default!; + + /// + /// Clave de producto/servicio, del catálogo del SAT. Nosotros te proporcionamos una manera más conveniente de encontrarlo utilizando nuestra [herramienta de búsqueda de claves](https://dashboard.facturapi.io/catalogs/productKey). + /// Requerido. + /// + [JsonProperty("product_key")] + public string ProductKey { get; set; } = default!; + + /// + /// Precio por unidad del bien o servicio. Este valor representará el precio con IVA incluido o sin él, dependiendo del valor de `tax_included`. + /// Requerido. + /// + [JsonProperty("price")] + public decimal Price { get; set; } = default!; + + /// + /// - `true`: Indica que todos los impuestos aplicables están incluidos en el precio (atributo price) y se desglosarán automáticamente al emitir la factura. + /// - `false`: Indica que el atributo price no incluye impuestos, por lo que aquellos impuestos a aplicar se sumarán en el precio final. + /// Opcional. + /// + [JsonProperty("tax_included")] + public bool? TaxIncluded { get; set; } = default!; + + /// + /// Código que representa si el bien o servicio es objeto de impuesto o no. Este atributo corresponde al campo "ObjetoImp" en el CFDI. + /// + /// - `01`: No objeto de impuesto. + /// - `02`: Sí objeto de impuesto. + /// - `03`: Sí objeto de impuesto, pero no obligado a desglose. + /// - `04`: Sí objeto de impuesto, y no causa impuesto. + /// - `05`: Sí objeto de impuesto, IVA crédito PODEBI. + /// - `06`: Sí objeto de impuesto, no IVA trasladado. + /// - `07`: No traslado de IVA, pero desglose de IEPS. + /// - `08`: No traslado de IVA sin desglose de IEPS. + /// Valores: "01", "04", "02", "03", "05", "06", "07", "08". + /// Opcional. + /// + [JsonProperty("taxability")] + public string? Taxability { get; set; } = default!; + + /// + /// Lista de impuestos que deberán aplicarse a este producto. + /// + /// Resolución cuando `taxes` se omite o es `null`: + /// - `taxability` omitido o `"02"`: se agrega IVA trasladado 16%. + /// - `taxability` en `"01"`, `"03"`, `"04"`, `"05"`, `"06"` o `"08"`: se guarda `[]`. + /// - `taxability = "07"`: la solicitud es inválida; debes enviar al menos un IEPS de traslado y no incluir IVA. + /// + /// Si envías `taxes` explícitamente, se usa el arreglo enviado. + /// Opcional. + /// + [JsonProperty("taxes")] + public List? Taxes { get; set; } = default!; + + /// + /// Arreglo de impuestos locales (estatales o municipales), en caso de haberlos. + /// Opcional. + /// + [JsonProperty("local_taxes")] + public List? LocalTaxes { get; set; } = default!; + + /// + /// Clave de unidad de medida, del catálogo del SAT. El valor por default `"H87"` (elemento) es la clave para representar una pieza o unidad de venta (lápiz, cuaderno, televisión, etc). + /// Si la unidad de tu producto es kilogramos, litros, horas u otra unidad, puedes encontrar la clave utilizando nuestra [herramienta de búsqueda de claves](https://dashboard.facturapi.io/catalogs/unit). + /// Opcional. + /// + [JsonProperty("unit_key")] + public string? UnitKey { get; set; } = default!; + + /// + /// Identificador de uso interno designado por la empresa. Puede tener cualquier valor. + /// Opcional. + /// + [JsonProperty("sku")] + public string? Sku { get; set; } = default!; + + /// + /// ID de la organización a la que pertenece este recurso. + /// Requerido. + /// + [JsonProperty("organization")] + public string Organization { get; set; } = default!; + } } diff --git a/Models/ProductCategory.cs b/Models/ProductCategory.cs new file mode 100644 index 0000000..c7e8c1f --- /dev/null +++ b/Models/ProductCategory.cs @@ -0,0 +1,39 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ProductCategory + /// + public class ProductCategory + { + /// + /// key + /// Requerido. + /// + [JsonProperty("key")] + public string Key { get; set; } = default!; + + /// + /// description + /// Requerido. + /// + [JsonProperty("description")] + public string Description { get; set; } = default!; + + /// + /// parent + /// Requerido. + /// Admite null. + /// + [JsonProperty("parent")] + public string? Parent { get; set; } = default!; + + } +} diff --git a/Models/ProductCategoryDetail.cs b/Models/ProductCategoryDetail.cs new file mode 100644 index 0000000..6695cb6 --- /dev/null +++ b/Models/ProductCategoryDetail.cs @@ -0,0 +1,53 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ProductCategoryDetail + /// + public class ProductCategoryDetail + { + /// + /// category + /// Requerido. + /// Admite null. + /// + [JsonProperty("category")] + public ProductCategory? Category { get; set; } = default!; + + /// + /// ancestors + /// Requerido. + /// + [JsonProperty("ancestors")] + public List Ancestors { get; set; } = default!; + + /// + /// children + /// Requerido. + /// + [JsonProperty("children")] + public List Children { get; set; } = default!; + + /// + /// product + /// Opcional. + /// + [JsonProperty("product")] + public CatalogItem? Product { get; set; } = default!; + + /// + /// products + /// Opcional. + /// + [JsonProperty("products")] + public SearchResult? Products { get; set; } = default!; + + } +} diff --git a/Models/ProductCategoryList.cs b/Models/ProductCategoryList.cs new file mode 100644 index 0000000..7adb5f3 --- /dev/null +++ b/Models/ProductCategoryList.cs @@ -0,0 +1,24 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ProductCategoryList + /// + public class ProductCategoryList + { + /// + /// data + /// Requerido. + /// + [JsonProperty("data")] + public List Data { get; set; } = default!; + + } +} diff --git a/Models/ProductInfo.cs b/Models/ProductInfo.cs new file mode 100644 index 0000000..d2513ab --- /dev/null +++ b/Models/ProductInfo.cs @@ -0,0 +1,114 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ProductInfo + /// + public class ProductInfo + { + /// + /// Lista de impuestos que deberán aplicarse a este producto. + /// + /// Resolución cuando `taxes` se omite o es `null`: + /// - `taxability` omitido o `"02"`: se agrega IVA trasladado 16%. + /// - `taxability` en `"01"`, `"03"`, `"04"`, `"05"`, `"06"` o `"08"`: se guarda `[]`. + /// - `taxability = "07"`: la solicitud es inválida; debes enviar al menos un IEPS de traslado y no incluir IVA. + /// + /// Si envías `taxes` explícitamente, se usa el arreglo enviado. + /// Requerido. + /// + [JsonProperty("taxes")] + public List Taxes { get; set; } = default!; + + /// + /// ID del producto base. Sólo presente si se utilizó como base un objeto `Product` guardado previamente. + /// Opcional. + /// + [JsonProperty("id")] + public string? Id { get; set; } = default!; + + /// + /// Palabra que representa la unidad de medida de tu producto. Debe estar relacionada con la clave de unidad `unit_key`. + /// Opcional. + /// Admite null. + /// + [JsonProperty("unit_name")] + public string? UnitName { get; set; } = default!; + + /// + /// Descripción del bien o servicio como aparecerá en la factura. + /// Requerido. + /// + [JsonProperty("description")] + public string Description { get; set; } = default!; + + /// + /// Clave de producto/servicio, del catálogo del SAT. Nosotros te proporcionamos una manera más conveniente de encontrarlo utilizando nuestra [herramienta de búsqueda de claves](https://dashboard.facturapi.io/catalogs/productKey). + /// Requerido. + /// + [JsonProperty("product_key")] + public string ProductKey { get; set; } = default!; + + /// + /// Precio por unidad del bien o servicio. Este valor representará el precio con IVA incluido o sin él, dependiendo del valor de `tax_included`. + /// Requerido. + /// + [JsonProperty("price")] + public decimal Price { get; set; } = default!; + + /// + /// - `true`: Indica que todos los impuestos aplicables están incluidos en el precio (atributo price) y se desglosarán automáticamente al emitir la factura. + /// - `false`: Indica que el atributo price no incluye impuestos, por lo que aquellos impuestos a aplicar se sumarán en el precio final. + /// Opcional. + /// + [JsonProperty("tax_included")] + public bool? TaxIncluded { get; set; } = default!; + + /// + /// Código que representa si el bien o servicio es objeto de impuesto o no. Este atributo corresponde al campo "ObjetoImp" en el CFDI. + /// + /// - `01`: No objeto de impuesto. + /// - `02`: Sí objeto de impuesto. + /// - `03`: Sí objeto de impuesto, pero no obligado a desglose. + /// - `04`: Sí objeto de impuesto, y no causa impuesto. + /// - `05`: Sí objeto de impuesto, IVA crédito PODEBI. + /// - `06`: Sí objeto de impuesto, no IVA trasladado. + /// - `07`: No traslado de IVA, pero desglose de IEPS. + /// - `08`: No traslado de IVA sin desglose de IEPS. + /// Valores: "01", "04", "02", "03", "05", "06", "07", "08". + /// Opcional. + /// + [JsonProperty("taxability")] + public string? Taxability { get; set; } = default!; + + /// + /// Arreglo de impuestos locales (estatales o municipales), en caso de haberlos. + /// Opcional. + /// + [JsonProperty("local_taxes")] + public List? LocalTaxes { get; set; } = default!; + + /// + /// Clave de unidad de medida, del catálogo del SAT. El valor por default `"H87"` (elemento) es la clave para representar una pieza o unidad de venta (lápiz, cuaderno, televisión, etc). + /// Si la unidad de tu producto es kilogramos, litros, horas u otra unidad, puedes encontrar la clave utilizando nuestra [herramienta de búsqueda de claves](https://dashboard.facturapi.io/catalogs/unit). + /// Opcional. + /// + [JsonProperty("unit_key")] + public string? UnitKey { get; set; } = default!; + + /// + /// Identificador de uso interno designado por la empresa. Puede tener cualquier valor. + /// Opcional. + /// + [JsonProperty("sku")] + public string? Sku { get; set; } = default!; + + } +} diff --git a/Models/Receipt.cs b/Models/Receipt.cs index c2b0e24..d5be3a1 100644 --- a/Models/Receipt.cs +++ b/Models/Receipt.cs @@ -1,26 +1,182 @@ -using System; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// Objeto Receipt + /// public class Receipt { - public string Id { get; set; } - public string ExternalId { get; set; } - public bool Livemode { get; set; } - public DateTime CreatedAt { get; set; } - public DateTime ExpiresAt { get; set; } - public string SelfInvoiceUrl { get; set; } - public string FolioNumber { get; set; } - public string Key { get; set; } - public string Branch { get; set; } - public string Status { get; set; } - public string Invoice { get; set; } - public string PaymentForm { get; set; } - public string Currency { get; set; } - public Decimal Exchange { get; set; } - public Decimal Total { get; set; } - public List Items { get; set; } + /// + /// ID del objeto + /// Requerido. + /// + [JsonProperty("id")] + public string Id { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de registro + /// Requerido. + /// + [JsonProperty("created_at")] + public DateTime CreatedAt { get; set; } = default!; + + /// + /// Si el valor es `true`, indica que el objeto fue creado en ambiente Live; o si es `false`, en ambiente Test. + /// Requerido. + /// + [JsonProperty("livemode")] + public bool Livemode { get; set; } = default!; + + /// + /// address + /// Opcional. + /// + [JsonProperty("address")] + public Address? Address { get; set; } = default!; + + /// + /// Versión de la API usada para crear el recibo. + /// Opcional. + /// + [JsonProperty("api_version")] + public int? ApiVersion { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de emisión del recibo. + /// Fecha de emisión del recibo. Por defecto se utiliza la fecha actual. + /// Requerido. + /// + [JsonProperty("date")] + public DateTime Date { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de expiración en formato ISO8601 (UTC String). + /// Es la fecha límite para que el cliente pueda facturar su recibo en el portal de autofactura. + /// Se calcula automáticamente a partir de las configuraciones de recibo de la organización. + /// Requerido. + /// + [JsonProperty("expires_at")] + public DateTime ExpiresAt { get; set; } = default!; + + /// + /// Estado actual del recibo. + /// Valores: "canceled", "open", "invoiced_to_customer", "invoiced_globally". + /// Requerido. + /// + [JsonProperty("status")] + public string Status { get; set; } = default!; + + /// + /// Format: url + /// Dirección URL para realizar autofactura. Incluye el `key` del recibo. + /// Puedes usarla para generar un botón o un QR de facturación para tus clientes. + /// Opcional. + /// + [JsonProperty("self_invoice_url")] + public string? SelfInvoiceUrl { get; set; } = default!; + + /// + /// Monto total de la operación + /// Requerido. + /// + [JsonProperty("total")] + public decimal Total { get; set; } = default!; + + /// + /// ID de la factura asociada, en caso de estar facturado. + /// Opcional. + /// Admite null. + /// + [JsonProperty("invoice")] + public string? Invoice { get; set; } = default!; + + /// + /// ID del cliente asociado al recibo, en caso de haberse asignado. + /// Opcional. + /// + [JsonProperty("customer")] + public string? Customer { get; set; } = default!; + + /// + /// Autogenerado. Identificador único alfanumérico corto, útil para acceder a la autofactura desde tu micrositio en factura.space + /// Requerido. + /// + [JsonProperty("key")] + public string Key { get; set; } = default!; + + /// + /// Conceptos incluidos en el recibo + /// Requerido. + /// + [JsonProperty("items")] + public List Items { get; set; } = default!; + + /// + /// Identificador que puedes usar para relacionar este recibo con tus registros para después buscar por este número. + /// Identificador opcional que puedes usar para relacionar este recibo con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// + [JsonProperty("external_id")] + public string? ExternalId { get; set; } = default!; + + /// + /// Clave que identifica una operación para evitar recursos duplicados. Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// + [JsonProperty("idempotency_key")] + public string? IdempotencyKey { get; set; } = default!; + + /// + /// Código que representa la forma de pago, según el [catálogo del SAT](https://docs.facturapi.io/api/#forma-de-pago). + /// Opcional. + /// + [JsonProperty("payment_form")] + public string? PaymentForm { get; set; } = default!; + + /// + /// Autoincremental. Número de folio del recibo para control interno y sin validez fiscal. + /// Opcional. + /// + [JsonProperty("folio_number")] + public int? FolioNumber { get; set; } = default!; + + /// + /// Código de la moneda, acorde al estándar [ISO 4217](https://es.wikipedia.org/wiki/ISO_4217). + /// Opcional. + /// + [JsonProperty("currency")] + public string? Currency { get; set; } = default!; + + /// + /// Tipo de cambio conforme a la moneda usada. Representa el número de pesos mexicanos que equivalen a una unidad de la divisa señalada en el atributo `currency`. + /// Opcional. + /// + [JsonProperty("exchange")] + public decimal? Exchange { get; set; } = default!; + + /// + /// Nombre de la sucursal donde se expidió el recibo. + /// Opcional. + /// + [JsonProperty("branch")] + public string? Branch { get; set; } = default!; + + /// + /// ID de la organización a la que pertenece este recurso. + /// Opcional. + /// + [JsonProperty("organization")] + public string? Organization { get; set; } = default!; } } diff --git a/Models/ReceiptInvoiceSummaryTax.cs b/Models/ReceiptInvoiceSummaryTax.cs new file mode 100644 index 0000000..b8e2e3f --- /dev/null +++ b/Models/ReceiptInvoiceSummaryTax.cs @@ -0,0 +1,72 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ReceiptInvoiceSummaryTax + /// + public class ReceiptInvoiceSummaryTax + { + /// + /// type + /// Opcional. + /// + [JsonProperty("type")] + public string? Type { get; set; } = default!; + + /// + /// rate + /// Opcional. + /// + [JsonProperty("rate")] + public decimal? Rate { get; set; } = default!; + + /// + /// factor + /// Valores: "Tasa", "Cuota", "Exento". + /// Requerido. + /// + [JsonProperty("factor")] + public string Factor { get; set; } = default!; + + /// + /// withholding + /// Requerido. + /// + [JsonProperty("withholding")] + public bool Withholding { get; set; } = default!; + + /// + /// base + /// Requerido. + /// + [JsonProperty("base")] + public decimal Base { get; set; } = default!; + + /// + /// amount + /// Requerido. + /// + [JsonProperty("amount")] + public decimal Amount { get; set; } = default!; + + /// + /// name + /// Opcional. + /// + [JsonProperty("name")] + public string? Name { get; set; } = default!; + + /// + /// Propiedades adicionales del objeto JSON. + /// + [JsonExtensionData] + public IDictionary? AdditionalProperties { get; set; } + } +} diff --git a/Models/RelatedResourceMessage.cs b/Models/RelatedResourceMessage.cs new file mode 100644 index 0000000..f1087fe --- /dev/null +++ b/Models/RelatedResourceMessage.cs @@ -0,0 +1,61 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// RelatedResourceMessage + /// + public class RelatedResourceMessage + { + /// + /// Tipo de recurso relacionado. + /// Opcional. + /// + [JsonProperty("resource_type")] + public string? ResourceType { get; set; } = default!; + + /// + /// ID del recurso relacionado. + /// Opcional. + /// + [JsonProperty("resource_id")] + public string? ResourceId { get; set; } = default!; + + /// + /// Origen del mensaje. + /// Opcional. + /// + [JsonProperty("source")] + public string? Source { get; set; } = default!; + + /// + /// Severidad del mensaje. + /// Valores: "error", "warning", "info". + /// Opcional. + /// + [JsonProperty("severity")] + public string? Severity { get; set; } = default!; + + /// + /// Mensaje relacionado con el recurso. + /// Opcional. + /// + [JsonProperty("message")] + public string? Message { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha y hora de creación del mensaje. + /// Opcional. + /// + [JsonProperty("created_at")] + public DateTime? CreatedAt { get; set; } = default!; + + } +} diff --git a/Models/Retention.cs b/Models/Retention.cs index 9dbe5ae..a8d13ec 100644 --- a/Models/Retention.cs +++ b/Models/Retention.cs @@ -1,54 +1,198 @@ -using System; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// Objeto Retention + /// public class Retention { - public string Id { get; set; } - public string ExternalId { get; set; } - public DateTime CreatedAt { get; set; } - public Customer Customer { get; set; } - public bool Livemode { get; set; } - public string Status { get; set; } - public string VerificationUrl { get; set; } - public string Type { get; set; } - public string Uuid { get; set; } - public DateTime FechaExp { get; set; } - public string CveRetenc { get; set; } - public string FolioInt { get; set; } - public string DescRetenc { get; set; } - public RetentionPeriod Periodo { get; set; } - public RetentionTotals Totales { get; set; } - public List Namespaces { get; set; } - public string[] Complements { get; set; } - public string[] Addenda { get; set; } - public string CancellationReceipt { get; set; } - public Stamp Stamp { get; set; } - public string PdfCustomSection { get; set; } - } + /// + /// ID del objeto + /// Requerido. + /// + [JsonProperty("id")] + public string Id { get; set; } = default!; - public class RetentionPeriod - { - public int MesIni { get; set; } - public int MesFin { get; set; } - public int Ejerc { get; set; } - } + /// + /// Format: date-time + /// Fecha de registro + /// Requerido. + /// + [JsonProperty("created_at")] + public DateTime CreatedAt { get; set; } = default!; - public class RetentionTotals - { - public Decimal MontoTotGrav { get; set; } - public Decimal MontoTotExent { get; set; } - public Decimal MontoTotOperacion { get; set; } - public Decimal MontoTotRet { get; set; } - public RetentionRetainedTax[] ImpRetenidos { get; set; } - } + /// + /// Si el valor es `true`, indica que el objeto fue creado en ambiente Live; o si es `false`, en ambiente Test. + /// Requerido. + /// + [JsonProperty("livemode")] + public bool Livemode { get; set; } = default!; + + /// + /// Estado actual de la retención. + /// Valores: "pending", "valid", "canceled", "draft". + /// Opcional. + /// + [JsonProperty("status")] + public string? Status { get; set; } = default!; + + /// + /// Format: uri + /// Dirección URL para verificar el estado de la retención en el portal del SAT. Este link es el mismo que aparece en el código QR, en el PDF de la retención. + /// Opcional. + /// Admite null. + /// + [JsonProperty("verification_url")] + public string? VerificationUrl { get; set; } = default!; + + /// + /// Tipo de comprobante. + /// Valores: "Retención". + /// Opcional. + /// + [JsonProperty("type")] + public string? Type { get; set; } = default!; + + /// + /// Format: uuid + /// Folio fiscal de la retención, asignado por el SAT. + /// Opcional. + /// Admite null. + /// + [JsonProperty("uuid")] + public string? Uuid { get; set; } = default!; + + /// + /// stamp + /// Opcional. + /// Admite null. + /// + [JsonProperty("stamp")] + public Stamp? Stamp { get; set; } = default!; + + /// + /// customer + /// Opcional. + /// Admite null. + /// + [JsonProperty("customer")] + public CustomerInfo? Customer { get; set; } = default!; + + /// + /// Indica si la retención con status `draft` está completa y lista para intentar timbrarse. + /// En una retención con status diferente a `draft`, este campo siempre será `false`. + /// Opcional. + /// + [JsonProperty("is_ready_to_stamp")] + public bool? IsReadyToStamp { get; set; } = default!; + + /// + /// Clave de la retención o información de pagos de acuerdo al catálogo del SAT. + /// Opcional. + /// Admite null. + /// + [JsonProperty("cve_retenc")] + public string? CveRetenc { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de expedición del comprobante en formato ISO8601 (UTC String). + /// Requerido. + /// Admite null. + /// + [JsonProperty("fecha_exp")] + public DateTime? FechaExp { get; set; } = default!; + + /// + /// Si la clave de la retención es “25” (Otro tipo de retenciones), este campo se usa para registrar la descripción de la retención. + /// Opcional. + /// + [JsonProperty("desc_retenc")] + public string? DescRetenc { get; set; } = default!; + + /// + /// Identificador alfanumérico para control interno de la empresa y sin relevancia fiscal. + /// Opcional. + /// + [JsonProperty("folio_int")] + public string? FolioInt { get; set; } = default!; + + /// + /// Información sobre el periodo de la retención. + /// Opcional. + /// Admite null. + /// + [JsonProperty("periodo")] + public RetentionPeriod? Periodo { get; set; } = default!; + + /// + /// Información sobre el total de retenciones efectuadas en el periodo correspondiente. + /// Opcional. + /// Admite null. + /// + [JsonProperty("totales")] + public RetentionTotals? Totales { get; set; } = default!; + + /// + /// Identificador opcional que puedes usar para relacionar esta retención con tus registros y poder hacer búsquedas usando este identificador. Facturapi no valida que este campo sea único. + /// Opcional. + /// Admite null. + /// + [JsonProperty("external_id")] + public string? ExternalId { get; set; } = default!; + + /// + /// Clave que identifica una operación para evitar recursos duplicados. Si se deja en blanco, no se toma en cuenta. + /// Consulta [Idempotencia](https://docs.facturapi.io/docs/getting-started/idempotency). + /// Opcional. + /// Admite null. + /// + [JsonProperty("idempotency_key")] + public string? IdempotencyKey { get; set; } = default!; + + /// + /// Arreglo de complementos a incluir en la factura. Cada elemento contiene + /// un `string` con el código XML del complemento. + /// Opcional. + /// + [JsonProperty("complements")] + public List? Complements { get; set; } = default!; + + /// + /// Format: html + /// En caso de que necesites incluir más información en el PDF, este campo te permite insertar código HTML con tu propio contenido. + /// Opcional. + /// + [JsonProperty("pdf_custom_section")] + public string? PdfCustomSection { get; set; } = default!; + + /// + /// Lista de fragmentos XML que se incluirán como addendas en la retención. + /// Opcional. + /// + [JsonProperty("addenda")] + public List? Addenda { get; set; } = default!; + + /// + /// Namespaces a insertar en el nodo raíz de la factura. Requerido en `addenda`. + /// Opcional. + /// + [JsonProperty("namespaces")] + public List? Namespaces { get; set; } = default!; + + /// + /// ID de la organización a la que pertenece este recurso. + /// Opcional. + /// + [JsonProperty("organization")] + public string? Organization { get; set; } = default!; - public class RetentionRetainedTax - { - public Decimal BaseRet { get; set; } - public string Impuesto { get; set; } - public Decimal MontoRet { get; set; } - public bool PagoProvisional { get; set; } } } diff --git a/Models/RetentionPeriod.cs b/Models/RetentionPeriod.cs new file mode 100644 index 0000000..975af0f --- /dev/null +++ b/Models/RetentionPeriod.cs @@ -0,0 +1,38 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// RetentionPeriod + /// + public class RetentionPeriod + { + /// + /// Mes inicial del periodo de la retención. + /// Opcional. + /// + [JsonProperty("mes_ini")] + public int? MesIni { get; set; } = default!; + + /// + /// Mes final del periodo de la retención. + /// Opcional. + /// + [JsonProperty("mes_fin")] + public int? MesFin { get; set; } = default!; + + /// + /// Año o ejercicio fiscal en que se realizó la retención. + /// Opcional. + /// + [JsonProperty("ejerc")] + public int? Ejerc { get; set; } = default!; + + } +} diff --git a/Models/RetentionRetainedTax.cs b/Models/RetentionRetainedTax.cs new file mode 100644 index 0000000..b270f2c --- /dev/null +++ b/Models/RetentionRetainedTax.cs @@ -0,0 +1,57 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// RetentionRetainedTax + /// + public class RetentionRetainedTax + { + /// + /// Base del impuesto retenido. + /// Opcional. + /// + [JsonProperty("base_ret")] + public decimal? BaseRet { get; set; } = default!; + + /// + /// Clave del tipo de impuesto retenido, del catálogo del SAT. + /// Valores: "IVA", "ISR". + /// Opcional. + /// + [JsonProperty("impuesto")] + public string? Impuesto { get; set; } = default!; + + /// + /// Importe del impuesto retenido + /// Opcional. + /// + [JsonProperty("monto_ret")] + public decimal? MontoRet { get; set; } = default!; + + /// + /// pago_provisional + /// Opcional. + /// + [JsonProperty("pago_provisional")] + public bool? PagoProvisional { get; set; } = default!; + + /// + /// - `01`: Pago definitivo IVA + /// - `02`: Pago definitivo IEPS + /// - `03`: Pago definitivo ISR Plataformas + /// - `04`: Pago provisional ISR + /// Valores: "01", "04", "02", "03". + /// Opcional. + /// + [JsonProperty("tipo_pago_ret")] + public string? TipoPagoRet { get; set; } = default!; + + } +} diff --git a/Models/RetentionTotals.cs b/Models/RetentionTotals.cs new file mode 100644 index 0000000..cdadbac --- /dev/null +++ b/Models/RetentionTotals.cs @@ -0,0 +1,52 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// RetentionTotals + /// + public class RetentionTotals + { + /// + /// Monto total de la operación, con precisión de hasta 6 decimales. + /// Opcional. + /// + [JsonProperty("monto_tot_operacion")] + public decimal? MontoTotOperacion { get; set; } = default!; + + /// + /// Monto total gravado. + /// Opcional. + /// + [JsonProperty("monto_tot_grav")] + public decimal? MontoTotGrav { get; set; } = default!; + + /// + /// Monto total exento. + /// Opcional. + /// + [JsonProperty("monto_tot_exent")] + public decimal? MontoTotExent { get; set; } = default!; + + /// + /// Suma de los montos de impuestos retenidos. + /// Opcional. + /// + [JsonProperty("monto_tot_ret")] + public decimal? MontoTotRet { get; set; } = default!; + + /// + /// Colección de impuestos retenidos. + /// Opcional. + /// + [JsonProperty("imp_retenidos")] + public List? ImpRetenidos { get; set; } = default!; + + } +} diff --git a/Models/SearchCartaPorteNavalAuthorizationsResponseDataItem.cs b/Models/SearchCartaPorteNavalAuthorizationsResponseDataItem.cs new file mode 100644 index 0000000..3b1139c --- /dev/null +++ b/Models/SearchCartaPorteNavalAuthorizationsResponseDataItem.cs @@ -0,0 +1,24 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// SearchCartaPorteNavalAuthorizationsResponseDataItem + /// + public class SearchCartaPorteNavalAuthorizationsResponseDataItem + { + /// + /// key + /// Opcional. + /// + [JsonProperty("key")] + public string? Key { get; set; } = default!; + + } +} diff --git a/Models/SearchResult.cs b/Models/SearchResult.cs index 6515842..35bc2cd 100644 --- a/Models/SearchResult.cs +++ b/Models/SearchResult.cs @@ -1,7 +1,10 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { @@ -16,7 +19,7 @@ public class SearchResult /// Opcional. /// [JsonProperty("page")] - public int? Page { get; set; } + public int? Page { get; set; } = default!; /// /// Páginas totales @@ -24,7 +27,7 @@ public class SearchResult /// Opcional. /// [JsonProperty("total_pages")] - public int? TotalPages { get; set; } + public int? TotalPages { get; set; } = default!; /// /// Resultados totales @@ -32,7 +35,7 @@ public class SearchResult /// Opcional. /// [JsonProperty("total_results")] - public int? TotalResults { get; set; } + public int? TotalResults { get; set; } = default!; /// /// Cursor anterior @@ -41,7 +44,7 @@ public class SearchResult /// Admite null. /// [JsonProperty("previous_cursor")] - public string PreviousCursor { get; set; } + public string? PreviousCursor { get; set; } = default!; /// /// Cursor siguiente @@ -50,7 +53,7 @@ public class SearchResult /// Admite null. /// [JsonProperty("next_cursor")] - public string NextCursor { get; set; } + public string? NextCursor { get; set; } = default!; /// /// Resultados con tope @@ -58,14 +61,14 @@ public class SearchResult /// Opcional. /// [JsonProperty("totals_are_capped")] - public bool? TotalsAreCapped { get; set; } + public bool? TotalsAreCapped { get; set; } = default!; /// - /// data + /// Elementos de la página. /// Requerido. /// [JsonProperty("data")] - public List Data { get; set; } + public List Data { get; set; } = default!; } } diff --git a/Models/SelfInvoiceSettings.cs b/Models/SelfInvoiceSettings.cs index 2c45dfd..409559e 100644 --- a/Models/SelfInvoiceSettings.cs +++ b/Models/SelfInvoiceSettings.cs @@ -1,10 +1,46 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + namespace Facturapi { - public class SelfInvoiceSettings - { - public string[] AllowedCfdiUses { get; set; } - public bool ApplyResicoIsr { get; set; } - public string SupportEmail { get; set; } - public bool SupportEmailVerified { get; set; } - } -} \ No newline at end of file + /// + /// SelfInvoiceSettings + /// + public class SelfInvoiceSettings + { + /// + /// Lista de usos CFDI permitidos para la autofactura. Si este campo está vacío, se permitirán todos los usos CFDI. + /// Opcional. + /// + [JsonProperty("allowed_cfdi_uses")] + public List? AllowedCfdiUses { get; set; } = default!; + + /// + /// Indica si la organización aplica el ISR bajo el régimen RESICO. Si es verdadero, el ISR se calculará de acuerdo con el régimen RESICO. + /// Si es falso, el ISR se calculará de acuerdo con el régimen general. + /// Opcional. + /// + [JsonProperty("apply_resico_isr")] + public bool? ApplyResicoIsr { get; set; } = default!; + + /// + /// Dirección de correo electrónico para aclaraciones. Aparecerá en el portal de autofacturación. + /// Opcional. + /// + [JsonProperty("support_email")] + public string? SupportEmail { get; set; } = default!; + + /// + /// Indica si el correo electrónico de soporte ha sido verificado. Si es falso, el correo electrónico utilizado en el portal de autofacturación será el correo electrónico principal de la cuenta. + /// Opcional. + /// + [JsonProperty("support_email_verified")] + public bool? SupportEmailVerified { get; set; } = default!; + + } +} diff --git a/Models/SendInvoiceByEmailResponse.cs b/Models/SendInvoiceByEmailResponse.cs new file mode 100644 index 0000000..4fdc130 --- /dev/null +++ b/Models/SendInvoiceByEmailResponse.cs @@ -0,0 +1,24 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// SendInvoiceByEmailResponse + /// + public class SendInvoiceByEmailResponse + { + /// + /// Indica si el correo fue enviado exitosamente + /// Requerido. + /// + [JsonProperty("ok")] + public bool Ok { get; set; } = default!; + + } +} diff --git a/Models/SendReceiptByEmailResponse.cs b/Models/SendReceiptByEmailResponse.cs new file mode 100644 index 0000000..8dd8e47 --- /dev/null +++ b/Models/SendReceiptByEmailResponse.cs @@ -0,0 +1,24 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// SendReceiptByEmailResponse + /// + public class SendReceiptByEmailResponse + { + /// + /// Indica si el correo fue enviado exitosamente + /// Requerido. + /// + [JsonProperty("ok")] + public bool Ok { get; set; } = default!; + + } +} diff --git a/Models/SendRetentionByEmailResponse.cs b/Models/SendRetentionByEmailResponse.cs new file mode 100644 index 0000000..9d4b3c1 --- /dev/null +++ b/Models/SendRetentionByEmailResponse.cs @@ -0,0 +1,24 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// SendRetentionByEmailResponse + /// + public class SendRetentionByEmailResponse + { + /// + /// Indica si el correo fue enviado exitosamente + /// Requerido. + /// + [JsonProperty("ok")] + public bool Ok { get; set; } = default!; + + } +} diff --git a/Models/SeriesGroup.cs b/Models/SeriesGroup.cs index f92b236..1714732 100644 --- a/Models/SeriesGroup.cs +++ b/Models/SeriesGroup.cs @@ -1,12 +1,38 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// SeriesGroup + /// public class SeriesGroup { - public string Name { get; set; } - public int NextFolio { get; set; } - public int NextFolioTest { get; set; } + /// + /// Nombre de la serie. + /// Opcional. + /// + [JsonProperty("series")] + public string? Series { get; set; } = default!; + + /// + /// Número de folio que se asignará a la siguiente factura en ambiente Live (y que se incrementará automáticamente por cada nueva factura). + /// Opcional. + /// + [JsonProperty("next_folio")] + public int? NextFolio { get; set; } = default!; + + /// + /// Número de folio que se asignará a la siguiente factura en ambiente Test (y que se incrementará automáticamente por cada nueva factura). + /// Opcional. + /// + [JsonProperty("next_folio_test")] + public int? NextFolioTest { get; set; } = default!; + } } diff --git a/Models/SignedDownloadUrl.cs b/Models/SignedDownloadUrl.cs new file mode 100644 index 0000000..a674ef1 --- /dev/null +++ b/Models/SignedDownloadUrl.cs @@ -0,0 +1,47 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Objeto con un enlace temporal de descarga y los metadatos del archivo. + /// + public class SignedDownloadUrl + { + /// + /// Format: uri + /// Enlace de descarga. Da acceso al archivo mientras siga vigente. + /// Requerido. + /// + [JsonProperty("url")] + public string Url { get; set; } = default!; + + /// + /// Format: date-time + /// Momento en el que el enlace deja de funcionar. + /// Requerido. + /// + [JsonProperty("expires_at")] + public DateTime ExpiresAt { get; set; } = default!; + + /// + /// Tipo de contenido del archivo. + /// Requerido. + /// + [JsonProperty("content_type")] + public string ContentType { get; set; } = default!; + + /// + /// Nombre sugerido del archivo. + /// Requerido. + /// + [JsonProperty("filename")] + public string Filename { get; set; } = default!; + + } +} diff --git a/Models/Stamp.cs b/Models/Stamp.cs index 1f507ff..714fc46 100644 --- a/Models/Stamp.cs +++ b/Models/Stamp.cs @@ -1,14 +1,75 @@ -using System; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// Stamp + /// public class Stamp { - public string Date { get; set; } - public string SatSignature { get; set; } - public string SatCertNumber { get; set; } - public string Signature { get; set; } - public string ComplementString { get; set; } + /// + /// Versión del timbre fiscal digital. + /// Valores: "1.0", "1.1". + /// Opcional. + /// + [JsonProperty("version")] + public string? Version { get; set; } = default!; + + /// + /// Leyenda opcional incluida en el timbre fiscal digital. + /// Opcional. + /// + [JsonProperty("legend")] + public string? Legend { get; set; } = default!; + + /// + /// Sello digital del comprobante fiscal. + /// Opcional. + /// + [JsonProperty("signature")] + public string? Signature { get; set; } = default!; + + /// + /// FechaTimbrado del SAT: fecha y hora local sin offset de zona horaria. Se conserva como texto. + /// Opcional. + /// + [JsonProperty("date")] + public string? Date { get; set; } = default!; + + /// + /// RFC del proveedor que certificó el comprobante. + /// Opcional. + /// + [JsonProperty("rfc_provider_cert")] + public string? RfcProviderCert { get; set; } = default!; + + /// + /// Número de serie del certificado del SAT usado para timbrar. + /// Opcional. + /// + [JsonProperty("sat_cert_number")] + public string? SatCertNumber { get; set; } = default!; + + /// + /// Sello digital del timbre fiscal digital. + /// Opcional. + /// + [JsonProperty("sat_signature")] + public string? SatSignature { get; set; } = default!; + + /// + /// Cadena original del timbre fiscal digital. + /// Opcional. + /// Admite null. + /// + [JsonProperty("complement_string")] + public string? ComplementString { get; set; } = default!; + } } diff --git a/Models/Tax.cs b/Models/Tax.cs index 53107cd..cf98b76 100644 --- a/Models/Tax.cs +++ b/Models/Tax.cs @@ -1,19 +1,70 @@ -using System; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { - + /// + /// Tax + /// public class Tax { - public string Type { get; set; } - public decimal Rate { get; set; } - public bool Withholding { get; set; } - public string Factor {get; set;} - public string IepsMode { get; set; } + /// + /// Tasa del impuesto en fracción decimal. + /// Requerido. + /// + [JsonProperty("rate")] + public decimal Rate { get; set; } = default!; + + /// + /// Importe calculado del impuesto. + /// Opcional. + /// + [JsonProperty("amount")] + public decimal? Amount { get; set; } = default!; + + /// + /// Base del impuesto. Si se omite, se calcula a partir del subtotal del concepto y el factor del impuesto. Para el factor Cuota, se utiliza la cantidad de unidades. + /// Opcional. + /// Admite null. + /// + [JsonProperty("base")] + public decimal? Base { get; set; } = default!; + + /// + /// Tipo de impuesto. + /// Valores: "IVA", "ISR", "IEPS". + /// Opcional. + /// + [JsonProperty("type")] + public string? Type { get; set; } = default!; + + /// + /// ieps_mode + /// Valores: "sum_before_taxes", "break_down", "unit", "subtract_before_break_down". + /// Opcional. + /// + [JsonProperty("ieps_mode")] + public string? IepsMode { get; set; } = default!; + + /// + /// Tipo factor + /// Valores: "Tasa", "Cuota", "Exento". + /// Opcional. + /// + [JsonProperty("factor")] + public string? Factor { get; set; } = default!; + + /// + /// Indica si se trata de un impuesto retenido (`true`), o un impuesto trasladado (`false`) + /// Opcional. + /// + [JsonProperty("withholding")] + public bool? Withholding { get; set; } = default!; + } } diff --git a/Models/TaxIdValidation.cs b/Models/TaxIdValidation.cs index fce9054..2c5afeb 100644 --- a/Models/TaxIdValidation.cs +++ b/Models/TaxIdValidation.cs @@ -1,41 +1,25 @@ -using System; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { - public class EfosDetalle - { - public string Rfc { get; set; } - public string RazonSocial { get; set; } - public string SituacionContribuyente { get; set; } - public string NumFechaPresuncion { get; set; } - public string PubFechaSatPresuntos { get; set; } - public string NumGlobalPresuncion { get; set; } - public string PubFechaDofPresuntos { get; set; } - public string PubSatDefinitivos { get; set; } - public string PubDofDefinitivos { get; set; } - public string NumFechaSentFav { get; set; } - public string PubSatSentFav { get; set; } - } - - public class EfosData - { - public string Mensaje { get; set; } - public string FechaLista { get; set; } - public List Detalles { get; set; } - } - - public class Efos - { - public bool IsValid { get; set; } - public EfosData Data { get; set; } - } - + /// + /// TaxIdValidation + /// public class TaxIdValidation { - public Efos Efos { get; set; } + /// + /// Resultado de la validación en la lista de Empresas que + /// Facturan Operaciones Simuladas del SAT. + /// Opcional. + /// + [JsonProperty("efos")] + public Efos? Efos { get; set; } = default!; + } } diff --git a/Models/TaxInfoError.cs b/Models/TaxInfoError.cs index f8291bd..e0bf569 100644 --- a/Models/TaxInfoError.cs +++ b/Models/TaxInfoError.cs @@ -1,12 +1,15 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { /// - /// TaxInfoValidationError + /// TaxInfoError /// public class TaxInfoError { @@ -16,28 +19,28 @@ public class TaxInfoError /// Requerido. /// [JsonProperty("source")] - public string Source { get; set; } + public string Source { get; set; } = default!; /// /// Código estable del detalle de validación. /// Requerido. /// [JsonProperty("code")] - public string Code { get; set; } + public string Code { get; set; } = default!; /// /// Ruta del campo cuya información fiscal no es válida. /// Opcional. /// [JsonProperty("path")] - public string Path { get; set; } + public string? Path { get; set; } = default!; /// /// Mensaje descriptivo del detalle de validación. /// Requerido. /// [JsonProperty("message")] - public string Message { get; set; } + public string Message { get; set; } = default!; } } diff --git a/Models/TaxInfoValidation.cs b/Models/TaxInfoValidation.cs index 5e9a24c..5b3998e 100644 --- a/Models/TaxInfoValidation.cs +++ b/Models/TaxInfoValidation.cs @@ -1,7 +1,10 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { @@ -15,14 +18,14 @@ public class TaxInfoValidation /// Requerido. /// [JsonProperty("is_valid")] - public bool IsValid { get; set; } + public bool IsValid { get; set; } = default!; /// /// Detalles de validación fiscal. Es un array vacío cuando `is_valid` es `true`. /// Requerido. /// [JsonProperty("errors")] - public TaxInfoError[] Errors { get; set; } + public TaxInfoError[] Errors { get; set; } = default!; } } diff --git a/Models/ToInvoiceSummary.cs b/Models/ToInvoiceSummary.cs new file mode 100644 index 0000000..a4f4e18 --- /dev/null +++ b/Models/ToInvoiceSummary.cs @@ -0,0 +1,66 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// Resumen de importes e impuestos de los recibos cuando `dry_run=true`. + /// + public class ToInvoiceSummary + { + /// + /// subtotal + /// Requerido. + /// + [JsonProperty("subtotal")] + public decimal Subtotal { get; set; } = default!; + + /// + /// discount + /// Requerido. + /// + [JsonProperty("discount")] + public decimal Discount { get; set; } = default!; + + /// + /// total + /// Requerido. + /// + [JsonProperty("total")] + public decimal Total { get; set; } = default!; + + /// + /// receipts + /// Requerido. + /// + [JsonProperty("receipts")] + public List Receipts { get; set; } = default!; + + /// + /// payment_form + /// Requerido. + /// + [JsonProperty("payment_form")] + public string PaymentForm { get; set; } = default!; + + /// + /// item_count + /// Requerido. + /// + [JsonProperty("item_count")] + public int ItemCount { get; set; } = default!; + + /// + /// taxes + /// Requerido. + /// + [JsonProperty("taxes")] + public CreateToInvoiceFromReceiptsResponseTaxes Taxes { get; set; } = default!; + + } +} diff --git a/Models/Webhook.cs b/Models/Webhook.cs index d5a8bb9..be0d5f6 100644 --- a/Models/Webhook.cs +++ b/Models/Webhook.cs @@ -1,21 +1,84 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Facturapi { + /// + /// Objeto Webhook + /// public class Webhook - { - public string Id { get; set; } - public DateTime CreatedAt { get; set; } + /// + /// ID del objeto + /// Requerido. + /// + [JsonProperty("id")] + public string Id { get; set; } = default!; + + /// + /// Format: date-time + /// Fecha de registro + /// Requerido. + /// + [JsonProperty("created_at")] + public DateTime CreatedAt { get; set; } = default!; + + /// + /// Si el valor es `true`, indica que el objeto fue creado en ambiente Live; o si es `false`, en ambiente Test. + /// Ambiente en el cual se está dando de alta el webhook. + /// Requerido. + /// + [JsonProperty("livemode")] + public bool Livemode { get; set; } = default!; + + /// + /// Id de la organización la cual se está dando de alta el webhook. + /// Opcional. + /// + [JsonProperty("organization")] + public string? Organization { get; set; } = default!; + + /// + /// Eventos a los que está suscrito el webhook. El valor "*" puede aparecer en respuestas existentes, pero no se acepta al crear o actualizar un webhook; envía los nombres de eventos explícitos. + /// Opcional. + /// + [JsonProperty("enabled_events")] + public List? EnabledEvents { get; set; } = default!; - public string[] EnabledEvents { get; set; } + /// + /// Format: uri + /// Http ruta para el webhook + /// Opcional. + /// + [JsonProperty("url")] + public string? Url { get; set; } = default!; - public bool Livemode { get; set; } + /// + /// Status del webhook + /// Valores: "enabled", "disabled". + /// Opcional. + /// + [JsonProperty("status")] + public string? Status { get; set; } = default!; - public Organization Organization { get; set; } + /// + /// Secreto para verificar las firmas. Se entrega al crear el webhook. + /// Opcional. + /// + [JsonProperty("secret")] + public string? Secret { get; set; } = default!; - public string Url { get; set; } + /// + /// description + /// Opcional. + /// + [JsonProperty("description")] + public string? Description { get; set; } = default!; - public string Status { get; set; } } -} \ No newline at end of file +} diff --git a/Models/ZipCode.cs b/Models/ZipCode.cs new file mode 100644 index 0000000..11bc5cb --- /dev/null +++ b/Models/ZipCode.cs @@ -0,0 +1,62 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Facturapi +{ + /// + /// ZipCode + /// + public class ZipCode + { + /// + /// key + /// Requerido. + /// + [JsonProperty("key")] + public string Key { get; set; } = default!; + + /// + /// country + /// Requerido. + /// + [JsonProperty("country")] + public CatalogItem Country { get; set; } = default!; + + /// + /// state + /// Requerido. + /// Admite null. + /// + [JsonProperty("state")] + public CatalogItem? State { get; set; } = default!; + + /// + /// municipality + /// Requerido. + /// Admite null. + /// + [JsonProperty("municipality")] + public CatalogItem? Municipality { get; set; } = default!; + + /// + /// locality + /// Requerido. + /// Admite null. + /// + [JsonProperty("locality")] + public CatalogItem? Locality { get; set; } = default!; + + /// + /// Todas las colonias del código postal, aunque la búsqueda coincida por otro campo. + /// Requerido. + /// + [JsonProperty("neighborhoods")] + public List Neighborhoods { get; set; } = default!; + + } +} diff --git a/README.md b/README.md index 4c44bce..ddcdc64 100644 --- a/README.md +++ b/README.md @@ -210,28 +210,80 @@ Mándanos un Pull Request! Agradecemos todo tipo de ayuda :) contacto@facturapi.io -## Clientes con entradas tipadas +## Entradas y respuestas tipadas -Puedes seguir usando `Dictionary` y las firmas existentes. Los modelos de entrada también son diccionarios y sólo serializan los campos asignados; un `null` explícito se conserva. +Los recursos de clientes, productos, facturas, recibos, retenciones, organizaciones, webhooks, herramientas y catálogos se generan desde la especificación pública de la API. Esto incluye los complementos de pago, nómina, Carta Porte, comercio exterior y leyendas fiscales. + +Puedes seguir enviando `Dictionary`. Los modelos de entrada ofrecen propiedades, documentación en IntelliSense y constructores con los campos requeridos de cada variante. Sólo se serializan los campos asignados: omitir una propiedad y asignarle `null` conservan sus diferencias. ```csharp var customer = await facturapi.Customer.CreateNationalAsync( new CustomerNationalCreateInput("Dunder Mifflin", "ABC101010111", "601", new CustomerNationalAddressInput("86500"))); -await facturapi.Customer.UpdateAsync(customer.Id, new CustomerUpdateInput { Email = null }); +var product = await facturapi.Product.CreateAsync( + new ProductCreateInput("Consultoría", "84111506", 100.25m)); +var invoice = await facturapi.Invoice.CreateIngresoAsync( + new InvoiceIngresoInput(new List + { + new InvoiceItemInput(product.Id) { Quantity = 1 } + }, PaymentForm.TRANSFERENCIA_ELECTRONICA) { Customer = customer.Id }); +``` + +También puedes elegir las variantes de Egreso, Pago, Nómina o Traslado. Los métodos `CreateDraftIngresoAsync`, `CreateDraftEgresoAsync`, `CreateDraftPagoAsync`, `CreateDraftNominaAsync` y `CreateDraftTrasladoAsync` usan modelos de borrador que permiten datos parciales y seleccionan el tipo y estado correspondientes: + +```csharp +var draft = await facturapi.Invoice.CreateDraftIngresoAsync(new InvoiceIngresoDraftInput()); +await facturapi.Invoice.CancelAsync(invoice.Id, new CancellationWithSubstitutionInput( + CancellationMotive.COMPROBANTE_EMITIDO_CON_ERRORES_CON_RELACION, "replacement_id")); +``` + +`CancellationWithSubstitutionInput` requiere tanto motivo como sustitución, para los motivos 01 y 04. `CancellationQueryInput` conserva la entrada general, incluida la eliminación de borradores sin motivo. Para clientes están disponibles las variantes nacional, extranjera, de RFC genérico y de enlace de edición. + +Los filtros tienen modelos propios, como `InvoiceListParams`. Los campos de fecha y hora (`date-time`) de entrada aceptan texto ISO 8601, `DateTime` o `DateTimeOffset`: + +```csharp +var page = await facturapi.Invoice.ListAsync(new InvoiceListParams +{ + Pagination = "cursor", + Date = new DateRangeInput { Gte = DateTime.UtcNow.AddDays(-30) } +}); ``` -También están disponibles `CreateForeignAsync`, `CreateGenericAsync`, `CreateWithEditLinkAsync` y `UpdateWithEditLinkAsync`, y los filtros `CustomerListParams`, `CustomerCreateParams` y `CustomerUpdateParams`. +Cuando un campo acepta formas diferentes se usa `OneOf<...>`, por ejemplo ID de cliente u objeto de cliente, y correo individual o lista. Las conversiones implícitas permiten asignar cada alternativa; se envía su valor directamente, sin envoltura JSON. Para inspeccionar una respuesta usa `TryGet(out var value)`. + +Los complementos concretos se pueden agregar a `List`. Los complementos personalizados y la addenda conservan su XML como texto. Los objetos abiertos de la API mantienen sus valores dinámicos. El tipado es una ayuda: los catálogos y valores literales se documentan como strings, y las validaciones fiscales y de negocio siguen a cargo de la API. + +`Receipt.SummarizeToInvoiceAsync(new ToInvoiceInput(keys))` obtiene el resumen de recibos sin crear una factura. Los métodos de URL firmada devuelven `SignedDownloadUrl`; las descargas siguen devolviendo un `Stream` en memoria que debes disponer. Las cargas de certificados, FIEL y logotipo reciben streams y los disponen al terminar la solicitud. + +`FacturapiException.ErrorDetails` expone detalles de error tipados, con `Code`, `Source`, `Path`, `Location` y `Message`. `Errors` conserva el JSON original; no necesitas analizar los mensajes para identificar un código. + +### Webhooks + +`Webhook.ValidateSignatureAsync(secret, signature, payload)` verifica localmente HMAC SHA-256 y devuelve `ApiEvent`. Pasa el texto JSON original del request, conservando sus bytes UTF-8 y espacios. La sobrecarga con diccionario sigue admitiendo `secret`, `signature` y `payload`. + +`ApiEvent.Data.Object` distingue facturas, recibos y clientes usando el tipo indicado por el evento. `Webhook.ValidateSignatureRemotelyAsync` permite usar el endpoint de verificación y conserva su respuesta como string u objeto abierto, según el payload enviado. + +## Migración a v8 -### Migración a v8 +Las llamadas con diccionarios conservan sus nombres y argumentos. Quienes sólo envían diccionarios, esperan el resultado con `var` y leen propiedades que conservan su tipo normalmente no necesitan cambiar esas llamadas. Revisa estos casos al actualizar: -`Customer.SatValidatedAt` y `Customer.EditLinkExpiresAt` ahora son `DateTime?`, porque la API admite `null`. Si asignabas estas propiedades a una variable `DateTime`, maneja el caso nulo antes de acceder a `.Value`. Las llamadas con diccionarios no requieren cambios. Las implementaciones manuales de `ICustomerWrapper` deben añadir los métodos nuevos. +| Uso anterior | Cambio en v8 | +|---|---| +| Fechas siempre presentes | Las fechas que admiten ausencia o `null`, como `Invoice.Date`, `Customer.SatValidatedAt` y `Customer.EditLinkExpiresAt`, son `DateTime?`. Maneja el caso nulo antes de acceder a `.Value`. | +| Modelos numéricos y campos opcionales | `number` se representa con `decimal`, `integer` con `int`, y los campos opcionales usan tipos anulables. Esto incluye folios y metadatos de respuestas parciales. | +| `Retention.*` devuelve `Invoice` | Devuelve `Retention` o `SearchResult`. | +| ZIP requests como diccionarios | Devuelven `InvoiceZipRequest`; usa `.Id`, `.Status`, etc. en lugar de indexadores. | +| Llaves Live o series como objeto individual | `ListLiveApiKeysAsync` y las operaciones de crear, actualizar y eliminar series devuelven listas de los modelos correspondientes. `DeleteCertificateAsync` devuelve `OrganizationDeleteCerts`. | +| Métodos que descartaban el resultado | Envíos por correo y operaciones de recibos exponen las respuestas de la API, incluidos los resultados de facturación y resúmenes. | +| `Invoice.Currecy` y `SeriesGroup.Name` | Usa los nombres corregidos `Currency` y `Series`. | +| Implementaciones manuales de interfaces | Actualiza los miembros y firmas de `I*Wrapper` e incorpora `ComercioExteriorCatalog` a `IFacturapiClient`. | +| Verificación de webhook como `Webhook` | `ValidateSignatureAsync` devuelve `ApiEvent` y verifica localmente. El acceso remoto explícito conserva el payload original. | -## SDK generation +Las respuestas incluyen más campos y objetos específicos del contrato; las fechas locales del timbre SAT que la API entrega como texto se conservan como strings. Consulta la documentación XML de cada propiedad cuando adaptes asignaciones a tipos concretos. -The Customers resource is generated from the public OpenAPI contract. The scope currently includes Customers and its input/output models; other resources remain handwritten. Generated files carry a banner and must be changed through the generator or the public specification. +## Generación del SDK -For SDK development, install Node.js 24+ and pnpm 11.9, then run: +Para desarrollar el SDK, instala Node.js 24+ y pnpm 11.9: ```sh pnpm install --frozen-lockfile @@ -240,6 +292,6 @@ pnpm test:codegen pnpm generate:sdk:check ``` -`openapi/source.json` pins the public documentation commit. To update it, run `pnpm sync:openapi [public-ref]` followed by generation and the SDK's normal test suite. Generation downloads the spec at that exact commit into memory; builds and consumers use the tracked generated code and need neither Node.js nor access to the spec. CI verifies regeneration and rejects unbound Customers operations or unsupported schema shapes instead of silently widening their types. +`openapi/source.json` fija una revisión pública del contrato de API v2. `pnpm sync:openapi [public-ref]` actualiza esa revisión; después ejecuta la generación y las pruebas de .NET. La generación lee el spec de esa revisión en memoria. Los builds y los consumidores usan los archivos generados que se incluyen en el repositorio, sin descargar el spec ni instalar Node.js. -The TypeScript compiler resolves the contract after `openapi-typescript`; C# renderers emit models, methods and documentation. SDK bindings preserve method names, generic pagination and established compatibility behavior. Input models distinguish properties that were never assigned from explicit `null`. Literal string constraints remain documented strings so existing catalog values and response parsing stay compatible; server-side validation still applies. +El compilador de TypeScript resuelve referencias, intersecciones y variantes después de `openapi-typescript`; los renderers de C# producen modelos, métodos y documentación. Los bindings conservan nombres y firmas del SDK, formatos de descarga y variantes de conveniencia. Toda operación pública debe tener un método asociado y CI verifica que la generación esté actualizada. Las constantes y los helpers locales se mantienen aparte cuando no derivan de un contrato HTTP. diff --git a/Router/CartaporteCatalogRouter.cs b/Router/CartaporteCatalogRouter.cs deleted file mode 100644 index e6d67a9..0000000 --- a/Router/CartaporteCatalogRouter.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System.Collections.Generic; - -namespace Facturapi -{ - internal static partial class Router - { - // Carta Porte 3.1 catalogs - public static string SearchCartaporteAirTransportCodes(Dictionary query = null) - { - return UriWithQuery("catalogs/cartaporte/3.1/air-transport-codes", query); - } - - public static string SearchCartaporteTransportConfigs(Dictionary query = null) - { - return UriWithQuery("catalogs/cartaporte/3.1/transport-configs", query); - } - - public static string SearchCartaporteRightsOfPassage(Dictionary query = null) - { - return UriWithQuery("catalogs/cartaporte/3.1/rights-of-passage", query); - } - - public static string SearchCartaporteCustomsDocuments(Dictionary query = null) - { - return UriWithQuery("catalogs/cartaporte/3.1/customs-documents", query); - } - - public static string SearchCartaportePackagingTypes(Dictionary query = null) - { - return UriWithQuery("catalogs/cartaporte/3.1/packaging-types", query); - } - - public static string SearchCartaporteTrailerTypes(Dictionary query = null) - { - return UriWithQuery("catalogs/cartaporte/3.1/trailer-types", query); - } - - public static string SearchCartaporteHazardousMaterials(Dictionary query = null) - { - return UriWithQuery("catalogs/cartaporte/3.1/hazardous-materials", query); - } - - public static string SearchCartaporteNavalAuthorizations(Dictionary query = null) - { - return UriWithQuery("catalogs/cartaporte/3.1/naval-authorizations", query); - } - - public static string SearchCartaportePortStations(Dictionary query = null) - { - return UriWithQuery("catalogs/cartaporte/3.1/port-stations", query); - } - - public static string SearchCartaporteMarineContainers(Dictionary query = null) - { - return UriWithQuery("catalogs/cartaporte/3.1/marine-containers", query); - } - } -} diff --git a/Router/CatalogRouter.cs b/Router/CatalogRouter.cs deleted file mode 100644 index 1583f81..0000000 --- a/Router/CatalogRouter.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Collections.Generic; - -namespace Facturapi -{ - internal static partial class Router - { - public static string SearchProductKeys(Dictionary query = null) - { - return UriWithQuery("catalogs/products", query); - } - - public static string SearchUnitKeys(Dictionary query = null) - { - return UriWithQuery("catalogs/units", query); - } - } -} diff --git a/Router/CustomerRouter.cs b/Router/CustomerRouter.cs deleted file mode 100644 index ace3eff..0000000 --- a/Router/CustomerRouter.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Generated by pnpm generate:sdk. Do not edit directly. -using System; -using System.Collections.Generic; - -namespace Facturapi -{ - internal static partial class Router - { - public static string CreateCustomer(Dictionary query = null) - { - return UriWithQuery($"customers", query); - } - - public static string ListCustomers(Dictionary query = null) - { - return UriWithQuery($"customers", query); - } - - public static string RetrieveCustomer(string id) - { - return UriWithQuery($"customers/{Uri.EscapeDataString(id)}"); - } - - public static string UpdateCustomer(string id, Dictionary query = null) - { - return UriWithQuery($"customers/{Uri.EscapeDataString(id)}", query); - } - - public static string DeleteCustomer(string id) - { - return UriWithQuery($"customers/{Uri.EscapeDataString(id)}"); - } - - public static string ValidateCustomerTaxInfo(string id) - { - return UriWithQuery($"customers/{Uri.EscapeDataString(id)}/tax-info-validation"); - } - - public static string SendEditLinkByEmail(string id) - { - return UriWithQuery($"customers/{Uri.EscapeDataString(id)}/email-edit-link"); - } - - } -} diff --git a/Router/HealthRouter.cs b/Router/HealthRouter.cs deleted file mode 100644 index 73986a7..0000000 --- a/Router/HealthRouter.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Facturapi -{ - internal static partial class Router - { - public static string HealthCheck() - { - return "check"; - } - } -} diff --git a/Router/InvoiceRouter.cs b/Router/InvoiceRouter.cs deleted file mode 100644 index 7f7d2dd..0000000 --- a/Router/InvoiceRouter.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Facturapi -{ - internal static partial class Router - { - public static string ListInvoices(Dictionary query = null) - { - return UriWithQuery("invoices", query); - } - - public static string RetrieveInvoice(string id) - { - return $"invoices/{id}"; - } - - public static string RetrieveInvoicePaymentSummary(string id, double amount) - { - return UriWithQuery($"{RetrieveInvoice(id)}/payment-summary", new Dictionary - { - ["amount"] = amount - }); - } - - public static string CreateInvoice(Dictionary query = null) - { - return UriWithQuery("invoices", query); - } - - public static string CancelInvoice(string id, Dictionary query = null) - { - return UriWithQuery(RetrieveInvoice(id), query); - } - - public static string DownloadInvoice(string id, string format) - { - return $"invoices/{id}/{format}"; - } - - public static string DownloadCancellationReceipt(string id, string format) - { - return $"invoices/{id}/cancellation_receipt/{format}"; - } - - public static string SendByEmail(string id) - { - return $"invoices/{id}/email"; - } - - public static string UpdateStatus(string id) - { - return $"invoices/{id}/status"; - } - - public static string UpdateDraftInvoice(string id) - { - return $"invoices/{id}"; - } - - public static string StampDraftInvoice(string id, Dictionary query = null) - { - return UriWithQuery($"invoices/{id}/stamp", query); - } - - public static string CopyInvoice(string id) - { - return $"invoices/{id}/copy"; - } - - public static string PreviewPdf() - { - return "invoices/preview/pdf"; - } - - public static string ListZipRequests(Dictionary query = null) - { - return UriWithQuery("invoices/zip-requests", query); - } - - public static string CreateZipRequest() - { - return "invoices/zip-requests"; - } - - public static string RetrieveZipRequest(string id) - { - return $"invoices/zip-requests/{id}"; - } - - public static string DownloadZipRequest(string id) - { - return $"invoices/zip-requests/{id}/zip"; - } - } -} diff --git a/Router/NominaCatalogRouter.cs b/Router/NominaCatalogRouter.cs deleted file mode 100644 index a2f6774..0000000 --- a/Router/NominaCatalogRouter.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Collections.Generic; - -namespace Facturapi -{ - internal static partial class Router - { - public static string SearchNominaDeductions(Dictionary query = null) - { - return UriWithQuery("catalogs/deductions", query); - } - - public static string SearchNominaPerceptions(Dictionary query = null) - { - return UriWithQuery("catalogs/perceptions", query); - } - } -} diff --git a/Router/OrganizationRouter.cs b/Router/OrganizationRouter.cs deleted file mode 100644 index fe200ef..0000000 --- a/Router/OrganizationRouter.cs +++ /dev/null @@ -1,184 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Facturapi -{ - internal static partial class Router - { - public static string ListOrganizations(Dictionary query = null) - { - return UriWithQuery("organizations", query); - } - - public static string OrganizationMe() - { - return "organizations/me"; - } - - public static string RetrieveOrganization(string id) - { - return $"organizations/{id}"; - } - - public static string CreateOrganization() - { - return "organizations"; - } - - public static string DeleteOrganization(string id) - { - return RetrieveOrganization(id); - } - - public static string CheckDomainAvailability(Dictionary query = null) - { - return UriWithQuery("organizations/domain-check", query); - } - - public static string UpdateLegal(string id) - { - return $"{RetrieveOrganization(id)}/legal"; - } - - public static string UpdateCustomization(string id) - { - return $"{RetrieveOrganization(id)}/customization"; - } - - public static string UploadLogo(string id) - { - return $"{RetrieveOrganization(id)}/logo"; - } - - public static string UpdateReceipts(string id) - { - return $"{RetrieveOrganization(id)}/receipts"; - } - - public static string UploadCertificate(string id) - { - return $"{RetrieveOrganization(id)}/certificate"; - } - - public static string DeleteCertificate(string id) - { - return $"{RetrieveOrganization(id)}/certificate"; - } - - public static string GetTestApiKey(string id) - { - return $"{RetrieveOrganization(id)}/apikeys/test"; - } - - - public static string RenewTestApiKey(string id) - { - return $"{RetrieveOrganization(id)}/apikeys/test"; - } - - public static string ListAsyncLiveApiKeys(string id) - { - return $"{RetrieveOrganization(id)}/apikeys/live"; - } - - public static string RenewLiveApiKey(string id) - { - return $"{RetrieveOrganization(id)}/apikeys/live"; - } - - public static string DeleteLiveApiKey(string organizationId, string apiKeyId) - { - return $"{RetrieveOrganization(organizationId)}/apikeys/live/{apiKeyId}"; - } - - - public static string ListSeriesGroup (string id) - { - return $"{RetrieveOrganization(id)}/series-group"; - } - - public static string CreateSeriesGroup (string id) - { - return $"{RetrieveOrganization(id)}/series-group"; - } - - public static string UpdateSeriesGroup (string id, string series_name) - { - return $"{RetrieveOrganization(id)}/series-group/{series_name}"; - } - public static string DeleteSeriesGroup (string id, string series_name) - { - return $"{RetrieveOrganization(id)}/series-group/{series_name}"; - } - - public static string UpdateDefaultSeries(string organizationId) - { - return $"{RetrieveOrganization(organizationId)}/series-group/default-series"; - } - - public static string UpdateSelfInvoiceSettings(string organizationId) - { - return $"{RetrieveOrganization(organizationId)}/self-invoice"; - } - - public static string UpdateDomain(string organizationId) - { - return $"{RetrieveOrganization(organizationId)}/domain"; - } - - public static string ListTeamAccess(string organizationId) - { - return $"{RetrieveOrganization(organizationId)}/team"; - } - - public static string RetrieveTeamAccess(string organizationId, string accessId) - { - return $"{ListTeamAccess(organizationId)}/{accessId}"; - } - - public static string UpdateTeamAccessRole(string organizationId, string accessId) - { - return $"{RetrieveTeamAccess(organizationId, accessId)}/role"; - } - - public static string ListSentTeamInvites(string organizationId) - { - return $"{ListTeamAccess(organizationId)}/invites"; - } - - public static string CancelTeamInvite(string organizationId, string inviteKey) - { - return $"{ListSentTeamInvites(organizationId)}/{inviteKey}"; - } - - public static string ListReceivedTeamInvites() - { - return "organizations/invites/pending"; - } - - public static string RespondTeamInvite(string inviteKey) - { - return $"organizations/invites/{inviteKey}/response"; - } - - public static string ListTeamRoles(string organizationId) - { - return $"{ListTeamAccess(organizationId)}/roles"; - } - - public static string ListTeamRoleTemplates(string organizationId) - { - return $"{ListTeamRoles(organizationId)}/templates"; - } - - public static string ListTeamRoleOperations(string organizationId) - { - return $"{ListTeamRoles(organizationId)}/operations"; - } - - public static string RetrieveTeamRole(string organizationId, string roleId) - { - return $"{ListTeamRoles(organizationId)}/{roleId}"; - } - } -} diff --git a/Router/ProductRouter.cs b/Router/ProductRouter.cs deleted file mode 100644 index 4675eee..0000000 --- a/Router/ProductRouter.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Facturapi -{ - internal static partial class Router - { - public static string ListProducts(Dictionary query = null) - { - return UriWithQuery("products", query); - } - - public static string RetrieveProduct(string id) - { - return $"products/{id}"; - } - - public static string CreateProduct() - { - return "products"; - } - - public static string DeleteProduct(string id) - { - return RetrieveProduct(id); - } - - public static string UpdateProduct(string id) - { - return RetrieveProduct(id); - } - } -} diff --git a/Router/ReceiptRouter.cs b/Router/ReceiptRouter.cs deleted file mode 100644 index 92c6e37..0000000 --- a/Router/ReceiptRouter.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Facturapi -{ - internal static partial class Router - { - public static string ListReceipts(Dictionary query = null) - { - return UriWithQuery("receipts", query); - } - - public static string RetrieveReceipt(string id) - { - return $"receipts/{id}"; - } - - public static string CreateReceipt() - { - return "receipts"; - } - - public static string CancelReceipt(string id) - { - return RetrieveReceipt(id); - } - - public static string InvoiceReceipt(string id) - { - return $"receipts/{id}/invoice"; - } - - public static string CreateGlobalInvoice() - { - return $"receipts/global-invoice"; - } - - public static string ToInvoice() - { - return "receipts/to-invoice"; - } - - public static string PreviewToInvoicePdf() - { - return "receipts/to-invoice/preview"; - } - - public static string DownloadReceiptPdf(string id) - { - return $"receipts/{id}/pdf"; - } - - public static string SendReceiptByEmail(string id) - { - return $"receipts/{id}/email"; - } - } -} diff --git a/Router/RetentionRouter.cs b/Router/RetentionRouter.cs deleted file mode 100644 index bf5d8ff..0000000 --- a/Router/RetentionRouter.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Facturapi -{ - internal static partial class Router - { - public static string ListRetentions(Dictionary query = null) - { - return UriWithQuery("retentions", query); - } - - public static string RetrieveRetention(string id) - { - return $"retentions/{id}"; - } - - public static string CreateRetention() - { - return "retentions"; - } - - public static string CancelRetention(string id, Dictionary query = null) - { - return UriWithQuery(RetrieveRetention(id), query); - } - - public static string UpdateDraftRetention(string id) - { - return RetrieveRetention(id); - } - - public static string StampDraftRetention(string id, Dictionary query = null) - { - return UriWithQuery($"retentions/{id}/stamp", query); - } - - public static string CopyRetention(string id) - { - return $"retentions/{id}/copy"; - } - - public static string DownloadRetention(string id, string format) - { - return $"retentions/{id}/{format}"; - } - - public static string SendRetentionByEmail(string id) - { - return $"retentions/{id}/email"; - } - } -} diff --git a/Router/Router.cs b/Router/Router.cs index 67c446d..9f4a98e 100644 --- a/Router/Router.cs +++ b/Router/Router.cs @@ -7,7 +7,7 @@ namespace Facturapi { internal static partial class Router { - private static string UriWithQuery(string path, Dictionary query = null) + internal static string UriWithQuery(string path, Dictionary query = null) { if (query == null || query.Count == 0) { @@ -39,6 +39,12 @@ private static void AppendQueryPart(List parts, string key, object value // A null value means "no filter": omit the key instead of sending it // empty, which the API can read as an explicit empty value. Pass an // empty string to send `key=` on purpose. + if (value is IOneOfValue alternative) + { + AppendQueryPart(parts, key, alternative.Value); + return; + } + if (value == null) { return; @@ -64,7 +70,14 @@ private static void AppendQueryPart(List parts, string key, object value return; } - parts.Add(Uri.EscapeDataString(key) + "=" + Uri.EscapeDataString(value is bool boolean ? (boolean ? "true" : "false") : value.ToString() ?? String.Empty)); + parts.Add(Uri.EscapeDataString(key) + "=" + Uri.EscapeDataString(value switch + { + bool boolean => boolean ? "true" : "false", + DateTime date => date.ToString("o", System.Globalization.CultureInfo.InvariantCulture), + DateTimeOffset offset => offset.ToString("o", System.Globalization.CultureInfo.InvariantCulture), + IFormattable scalar => scalar.ToString(null, System.Globalization.CultureInfo.InvariantCulture), + _ => value.ToString() ?? String.Empty + })); } } } diff --git a/Router/ToolRouter.cs b/Router/ToolRouter.cs deleted file mode 100644 index db66999..0000000 --- a/Router/ToolRouter.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections.Generic; - -namespace Facturapi -{ - internal static partial class Router - { - public static string ValidateTaxId(Dictionary query = null) - { - return UriWithQuery("tools/tax_id_validation", query); - } - } -} diff --git a/Router/WebhookRouter.cs b/Router/WebhookRouter.cs deleted file mode 100644 index ffb73a3..0000000 --- a/Router/WebhookRouter.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Facturapi -{ - internal static partial class Router - { - public static string ListWebhooks(Dictionary query = null) - { - return UriWithQuery("webhooks", query); - } - - public static string RetrieveWebhook(string id) - { - return $"webhooks/{id}"; - } - - public static string CreateWebhook() - { - return "webhooks"; - } - - public static string UpdateWebhook(string id) - { - return RetrieveWebhook(id); - } - - public static string DeleteWebhook(string id) - { - return RetrieveWebhook(id); - } - - public static string ValidateSignature() - { - return "webhooks/validate-signature"; - } - - - } -} diff --git a/Serialization/OneOfConverter.cs b/Serialization/OneOfConverter.cs new file mode 100644 index 0000000..8d0a7b5 --- /dev/null +++ b/Serialization/OneOfConverter.cs @@ -0,0 +1,45 @@ +#nullable enable +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections; +using System.Reflection; + +namespace Facturapi +{ + /// Valor de una alternativa del contrato. + public interface IOneOfValue + { + /// Valor seleccionado, sin envoltura JSON. + object? Value { get; } + } + + internal sealed class OneOfConverter : JsonConverter + { + public override bool CanConvert(Type type) => typeof(IOneOfValue).IsAssignableFrom(Nullable.GetUnderlyingType(type) ?? type); + + public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) + { + serializer.Serialize(writer, (value as IOneOfValue)?.Value); + } + + public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) + { + var token = JToken.Load(reader); + if (token.Type == JTokenType.Null) return null; + var unionType = Nullable.GetUnderlyingType(objectType) ?? objectType; + foreach (var type in unionType.GetGenericArguments()) + { + if (type == typeof(object) || + token.Type == JTokenType.String && (type == typeof(string) || type == typeof(DateTime) || type == typeof(DateTimeOffset)) || + token.Type == JTokenType.Date && (type == typeof(DateTime) || type == typeof(DateTimeOffset) || type == typeof(string)) || + token.Type == JTokenType.Boolean && type == typeof(bool) || + (token.Type == JTokenType.Integer || token.Type == JTokenType.Float) && (type == typeof(int) || type == typeof(decimal) || type == typeof(double)) || + token.Type == JTokenType.Array && typeof(IEnumerable).IsAssignableFrom(type) && type != typeof(string) && !typeof(IDictionary).IsAssignableFrom(type) || + token.Type == JTokenType.Object && !type.IsValueType && type != typeof(string) && (!typeof(IEnumerable).IsAssignableFrom(type) || typeof(IDictionary).IsAssignableFrom(type))) + return Activator.CreateInstance(unionType, BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { token.ToObject(type, serializer) }, null); + } + throw new JsonSerializationException("The JSON value does not match any documented alternative."); + } + } +} diff --git a/Wrappers/BaseWrapper.Requests.cs b/Wrappers/BaseWrapper.Requests.cs new file mode 100644 index 0000000..63f9655 --- /dev/null +++ b/Wrappers/BaseWrapper.Requests.cs @@ -0,0 +1,53 @@ +#nullable enable +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Facturapi.Wrappers +{ + public abstract partial class BaseWrapper + { + /// Envía JSON o consulta parámetros y materializa la respuesta tipada. + protected async Task RequestAsync(HttpMethod method, string path, Dictionary? query, object? body, bool hasJsonBody, CancellationToken cancellationToken) + { + using (var request = new HttpRequestMessage(method, Router.UriWithQuery(path, query))) + { + if (hasJsonBody) + request.Content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"); + using (var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false)) + return await ReadResponseAsync(response, cancellationToken).ConfigureAwait(false); + } + } + + /// Envía archivos multipart usando el transporte y errores del cliente. + protected async Task RequestMultipartAsync(HttpMethod method, string path, MultipartFormDataContent form, CancellationToken cancellationToken) + { + using (var request = new HttpRequestMessage(method, path) { Content = form }) + using (var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false)) + return await ReadResponseAsync(response, cancellationToken).ConfigureAwait(false); + } + + private async Task ReadResponseAsync(HttpResponseMessage response, CancellationToken cancellationToken) + { + await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); + if (typeof(T) == typeof(Stream)) + { + var memory = new MemoryStream(); + try + { + using (var source = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) + await source.CopyToAsync(memory, 81920, cancellationToken).ConfigureAwait(false); + memory.Position = 0; + return (T)(object)memory; + } + catch { memory.Dispose(); throw; } + } + return JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync().ConfigureAwait(false), jsonSettings)!; + } + } +} diff --git a/Wrappers/BaseWrapper.cs b/Wrappers/BaseWrapper.cs index 0871265..0d64562 100644 --- a/Wrappers/BaseWrapper.cs +++ b/Wrappers/BaseWrapper.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; @@ -9,7 +9,7 @@ namespace Facturapi.Wrappers { - public abstract class BaseWrapper + public abstract partial class BaseWrapper { protected HttpClient client; protected JsonSerializerSettings jsonSettings { get; set; } @@ -25,7 +25,8 @@ public BaseWrapper(string apiKey, string apiVersion, HttpClient httpClient) this.jsonSettings = new JsonSerializerSettings { ContractResolver = new SnakeCasePropertyNamesContractResolver(), - NullValueHandling = NullValueHandling.Ignore + NullValueHandling = NullValueHandling.Ignore, + DateParseHandling = DateParseHandling.None }; } diff --git a/Wrappers/CartaporteCatalogWrapper.cs b/Wrappers/CartaporteCatalogWrapper.cs index f354a4c..a60dece 100644 --- a/Wrappers/CartaporteCatalogWrapper.cs +++ b/Wrappers/CartaporteCatalogWrapper.cs @@ -1,76 +1,305 @@ -using Newtonsoft.Json; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; using System.Net.Http; -using System.Threading.Tasks; using System.Threading; +using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public class CartaporteCatalogWrapper : BaseWrapper, ICartaporteCatalogWrapper + /// + /// Operaciones de CartaporteCatalog. + /// + public partial class CartaporteCatalogWrapper : BaseWrapper, ICartaporteCatalogWrapper { - internal CartaporteCatalogWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) + internal CartaporteCatalogWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) {} + + /// + /// Buscar códigos de transporte aéreo + /// + /// Devuelve entradas del catálogo de aerolíneas que coinciden con la consulta. Usado para el complemento Carta Porte. + /// + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchAirTransportCodesParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchAirTransportCodes(JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/air-transport-codes", query, null, false, cancellationToken); + } + + /// + /// Buscar códigos de transporte aéreo + /// + /// Devuelve entradas del catálogo de aerolíneas que coinciden con la consulta. Usado para el complemento Carta Porte. + /// + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchAirTransportCodesParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchAirTransportCodes(CartaporteCatalogSearchAirTransportCodesParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/air-transport-codes", query, null, false, cancellationToken); + } + + /// + /// Buscar configuraciones de autotransporte + /// + /// Devuelve configuraciones de transporte (p. ej., camión/semirremolque). + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchTransportConfigsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchTransportConfigs(JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/transport-configs", query, null, false, cancellationToken); + } + + /// + /// Buscar configuraciones de autotransporte + /// + /// Devuelve configuraciones de transporte (p. ej., camión/semirremolque). + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchTransportConfigsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchTransportConfigs(CartaporteCatalogSearchTransportConfigsParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/transport-configs", query, null, false, cancellationToken); + } + + /// + /// Buscar derechos de paso + /// + /// Devuelve derechos de paso ferroviarios que coinciden con la consulta. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchRightsOfPassageParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchRightsOfPassage(JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/rights-of-passage", query, null, false, cancellationToken); + } + + /// + /// Buscar derechos de paso + /// + /// Devuelve derechos de paso ferroviarios que coinciden con la consulta. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchRightsOfPassageParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchRightsOfPassage(CartaporteCatalogSearchRightsOfPassageParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/rights-of-passage", query, null, false, cancellationToken); + } + + /// + /// Buscar documentos aduaneros + /// + /// Devuelve tipos de documentos aduaneros. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchCustomsDocumentsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchCustomsDocuments(JsonObject? query = null, CancellationToken cancellationToken = default) { + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/customs-documents", query, null, false, cancellationToken); } - public async Task> SearchAirTransportCodes(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Buscar documentos aduaneros + /// + /// Devuelve tipos de documentos aduaneros. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchCustomsDocumentsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchCustomsDocuments(CartaporteCatalogSearchCustomsDocumentsParams? query, CancellationToken cancellationToken = default) { - return await this.SearchCatalogAsync(Router.SearchCartaporteAirTransportCodes(query), cancellationToken).ConfigureAwait(false); + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/customs-documents", query, null, false, cancellationToken); } - public async Task> SearchTransportConfigs(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Buscar tipos de empaque + /// + /// Devuelve tipos de empaque para mercancías. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchPackagingTypesParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchPackagingTypes(JsonObject? query = null, CancellationToken cancellationToken = default) { - return await this.SearchCatalogAsync(Router.SearchCartaporteTransportConfigs(query), cancellationToken).ConfigureAwait(false); + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/packaging-types", query, null, false, cancellationToken); } - public async Task> SearchRightsOfPassage(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Buscar tipos de empaque + /// + /// Devuelve tipos de empaque para mercancías. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchPackagingTypesParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchPackagingTypes(CartaporteCatalogSearchPackagingTypesParams? query, CancellationToken cancellationToken = default) { - return await this.SearchCatalogAsync(Router.SearchCartaporteRightsOfPassage(query), cancellationToken).ConfigureAwait(false); + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/packaging-types", query, null, false, cancellationToken); } - public async Task> SearchCustomsDocuments(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Buscar tipos de remolque + /// + /// Devuelve tipos de remolque/semirremolque. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchTrailerTypesParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchTrailerTypes(JsonObject? query = null, CancellationToken cancellationToken = default) { - return await this.SearchCatalogAsync(Router.SearchCartaporteCustomsDocuments(query), cancellationToken).ConfigureAwait(false); + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/trailer-types", query, null, false, cancellationToken); } - public async Task> SearchPackagingTypes(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Buscar tipos de remolque + /// + /// Devuelve tipos de remolque/semirremolque. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchTrailerTypesParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchTrailerTypes(CartaporteCatalogSearchTrailerTypesParams? query, CancellationToken cancellationToken = default) { - return await this.SearchCatalogAsync(Router.SearchCartaportePackagingTypes(query), cancellationToken).ConfigureAwait(false); + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/trailer-types", query, null, false, cancellationToken); } - public async Task> SearchTrailerTypes(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Buscar materiales peligrosos + /// + /// Devuelve entradas del catálogo de materiales peligrosos. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchHazardousMaterialsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchHazardousMaterials(JsonObject? query = null, CancellationToken cancellationToken = default) { - return await this.SearchCatalogAsync(Router.SearchCartaporteTrailerTypes(query), cancellationToken).ConfigureAwait(false); + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/hazardous-materials", query, null, false, cancellationToken); } - public async Task> SearchHazardousMaterials(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Buscar materiales peligrosos + /// + /// Devuelve entradas del catálogo de materiales peligrosos. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchHazardousMaterialsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchHazardousMaterials(CartaporteCatalogSearchHazardousMaterialsParams? query, CancellationToken cancellationToken = default) { - return await this.SearchCatalogAsync(Router.SearchCartaporteHazardousMaterials(query), cancellationToken).ConfigureAwait(false); + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/hazardous-materials", query, null, false, cancellationToken); } - public async Task> SearchNavalAuthorizations(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Buscar autorizaciones navales + /// + /// Devuelve códigos de autorización naval (solo `key`). + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchNavalAuthorizationsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchNavalAuthorizations(JsonObject? query = null, CancellationToken cancellationToken = default) { - return await this.SearchCatalogAsync(Router.SearchCartaporteNavalAuthorizations(query), cancellationToken).ConfigureAwait(false); + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/naval-authorizations", query, null, false, cancellationToken); } - public async Task> SearchPortStations(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Buscar autorizaciones navales + /// + /// Devuelve códigos de autorización naval (solo `key`). + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchNavalAuthorizationsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchNavalAuthorizations(CartaporteCatalogSearchNavalAuthorizationsParams? query, CancellationToken cancellationToken = default) { - return await this.SearchCatalogAsync(Router.SearchCartaportePortStations(query), cancellationToken).ConfigureAwait(false); + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/naval-authorizations", query, null, false, cancellationToken); } - public async Task> SearchMarineContainers(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Buscar estaciones/puertos + /// + /// Devuelve entradas de estaciones aéreas/marítimas/terrestres. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchPortStationsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchPortStations(JsonObject? query = null, CancellationToken cancellationToken = default) { - return await this.SearchCatalogAsync(Router.SearchCartaporteMarineContainers(query), cancellationToken).ConfigureAwait(false); + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/port-stations", query, null, false, cancellationToken); } - private async Task> SearchCatalogAsync(string url, CancellationToken cancellationToken) + /// + /// Buscar estaciones/puertos + /// + /// Devuelve entradas de estaciones aéreas/marítimas/terrestres. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchPortStationsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchPortStations(CartaporteCatalogSearchPortStationsParams? query, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(url, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var searchResult = JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - return searchResult; - } + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/port-stations", query, null, false, cancellationToken); } + + /// + /// Buscar contenedores marítimos + /// + /// Devuelve tipos de contenedores marítimos. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchMarineContainersParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchMarineContainers(JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/marine-containers", query, null, false, cancellationToken); + } + + /// + /// Buscar contenedores marítimos + /// + /// Devuelve tipos de contenedores marítimos. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchMarineContainersParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchMarineContainers(CartaporteCatalogSearchMarineContainersParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/cartaporte/3.1/marine-containers", query, null, false, cancellationToken); + } + } } diff --git a/Wrappers/CatalogWrapper.cs b/Wrappers/CatalogWrapper.cs index ed21955..c64c5af 100644 --- a/Wrappers/CatalogWrapper.cs +++ b/Wrappers/CatalogWrapper.cs @@ -1,36 +1,248 @@ -using Newtonsoft.Json; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; using System.Net.Http; -using System.Threading.Tasks; using System.Threading; +using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public class CatalogWrapper : BaseWrapper, ICatalogWrapper + /// + /// Operaciones de Catalog. + /// + public partial class CatalogWrapper : BaseWrapper, ICatalogWrapper { - internal CatalogWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) + internal CatalogWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) {} + + /// + /// Clave Producto/Servicio + /// + /// Busca en el catálogo Productos/Servicios del SAT, el cual contiene la clave a incluir en la factura. + /// + /// Parámetros de consulta. Admite CatalogSearchProductsParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> SearchProducts(JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/products", query, null, false, cancellationToken); + } + + /// + /// Clave Producto/Servicio + /// + /// Busca en el catálogo Productos/Servicios del SAT, el cual contiene la clave a incluir en la factura. + /// + /// Parámetros de consulta. Admite CatalogSearchProductsParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> SearchProducts(CatalogSearchProductsParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/products", query, null, false, cancellationToken); + } + + /// + /// Unidades de medida + /// + /// Busca en el catálogo de Unidades de Medida del SAT. + /// + /// Parámetros de consulta. Admite CatalogSearchUnitsParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> SearchUnits(JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/units", query, null, false, cancellationToken); + } + + /// + /// Unidades de medida + /// + /// Busca en el catálogo de Unidades de Medida del SAT. + /// + /// Parámetros de consulta. Admite CatalogSearchUnitsParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> SearchUnits(CatalogSearchUnitsParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/units", query, null, false, cancellationToken); + } + + /// + /// Listar categorías raíz de productos y servicios + /// + /// Devuelve las raíces Productos y Servicios. Consulta una raíz por su clave para explorar sus divisiones. + /// + /// Permite cancelar la solicitud. + /// OK + /// + public Task ListProductCategories(CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"catalogs/product-categories", null, null, false, cancellationToken); + } + + /// + /// Explorar una categoría o consultar la ruta de una clave + /// + /// Explora el árbol de categorías de productos y servicios del SAT. Las categorías usan claves de 2, 4 o 6 dígitos. Una clave completa de 8 dígitos devuelve el producto y su ruta; nunca se eliminan ceros finales. La clave especial 01010101 no tiene categoría. Consultar una clase de 6 dígitos incluye un resultado paginado de productos. Consultar una clave de 8 dígitos devuelve su ruta sin listar otros productos de la clase. + /// + /// Raíz, prefijo de categoría o clave completa de producto/servicio. + /// Parámetros de consulta. Admite CatalogGetProductCategoryParams. + /// Permite cancelar la solicitud. + /// OK + /// + public Task GetProductCategory(string key, JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"catalogs/product-categories/{Uri.EscapeDataString(key)}", query, null, false, cancellationToken); + } + + /// + /// Explorar una categoría o consultar la ruta de una clave + /// + /// Explora el árbol de categorías de productos y servicios del SAT. Las categorías usan claves de 2, 4 o 6 dígitos. Una clave completa de 8 dígitos devuelve el producto y su ruta; nunca se eliminan ceros finales. La clave especial 01010101 no tiene categoría. Consultar una clase de 6 dígitos incluye un resultado paginado de productos. Consultar una clave de 8 dígitos devuelve su ruta sin listar otros productos de la clase. + /// + /// Raíz, prefijo de categoría o clave completa de producto/servicio. + /// Parámetros de consulta. Admite CatalogGetProductCategoryParams. + /// Permite cancelar la solicitud. + /// OK + /// + public Task GetProductCategory(string key, CatalogGetProductCategoryParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"catalogs/product-categories/{Uri.EscapeDataString(key)}", query, null, false, cancellationToken); + } + + /// + /// Buscar códigos postales + /// + /// Busca códigos postales mexicanos. Una consulta de 1 a 5 dígitos busca por código o prefijo; el texto busca nombres de colonia, localidad/ciudad, municipio o estado, sin distinguir mayúsculas ni diacríticos. Las coincidencias exactas de nombre preceden a las parciales. Cada código postal aparece una sola vez e incluye todas sus colonias en neighborhoods. El filtro de estado se aplica en ambos casos. Sin consulta, lista códigos postales. Admite páginas y cursores; los totales de búsquedas textuales pueden estar limitados, indicado por totals_are_capped. + /// + /// Parámetros de consulta. Admite CatalogSearchZipCodesParams. + /// Permite cancelar la solicitud. + /// Resultados de búsqueda + /// + public Task> SearchZipCodes(JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/zip-codes", query, null, false, cancellationToken); + } + + /// + /// Buscar códigos postales + /// + /// Busca códigos postales mexicanos. Una consulta de 1 a 5 dígitos busca por código o prefijo; el texto busca nombres de colonia, localidad/ciudad, municipio o estado, sin distinguir mayúsculas ni diacríticos. Las coincidencias exactas de nombre preceden a las parciales. Cada código postal aparece una sola vez e incluye todas sus colonias en neighborhoods. El filtro de estado se aplica en ambos casos. Sin consulta, lista códigos postales. Admite páginas y cursores; los totales de búsquedas textuales pueden estar limitados, indicado por totals_are_capped. + /// + /// Parámetros de consulta. Admite CatalogSearchZipCodesParams. + /// Permite cancelar la solicitud. + /// Resultados de búsqueda + /// + public Task> SearchZipCodes(CatalogSearchZipCodesParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/zip-codes", query, null, false, cancellationToken); + } + + /// + /// Consultar código postal + /// + /// Devuelve los datos de domicilio y las colonias de un código postal mexicano. + /// + /// code + /// Permite cancelar la solicitud. + /// Código postal + /// + public Task GetZipCode(string code, CancellationToken cancellationToken = default) { + return RequestAsync(HttpMethod.Get, $"catalogs/zip-codes/{Uri.EscapeDataString(code)}", null, null, false, cancellationToken); } - public async Task> SearchProducts(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Buscar países + /// + /// Busca países por código ISO de tres letras o nombre. La búsqueda ignora acentos y mayúsculas. + /// + /// Parámetros de consulta. Admite CatalogSearchCountriesParams. + /// Permite cancelar la solicitud. + /// Resultados de búsqueda + /// + public Task> SearchCountries(JsonObject? query = null, CancellationToken cancellationToken = default) { - return await this.SearchCatalogAsync(Router.SearchProductKeys(query), cancellationToken).ConfigureAwait(false); + return RequestAsync>(HttpMethod.Get, $"catalogs/countries", query, null, false, cancellationToken); } - public async Task> SearchUnits(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Buscar países + /// + /// Busca países por código ISO de tres letras o nombre. La búsqueda ignora acentos y mayúsculas. + /// + /// Parámetros de consulta. Admite CatalogSearchCountriesParams. + /// Permite cancelar la solicitud. + /// Resultados de búsqueda + /// + public Task> SearchCountries(CatalogSearchCountriesParams? query, CancellationToken cancellationToken = default) { - return await this.SearchCatalogAsync(Router.SearchUnitKeys(query), cancellationToken).ConfigureAwait(false); + return RequestAsync>(HttpMethod.Get, $"catalogs/countries", query, null, false, cancellationToken); } - private async Task> SearchCatalogAsync(string url, CancellationToken cancellationToken) + /// + /// Buscar regímenes fiscales + /// + /// Consulta los regímenes fiscales admitidos por la API. El receptor debe declarar su régimen; esta búsqueda no lo determina. + /// + /// Parámetros de consulta. Admite CatalogSearchTaxSystemsParams. + /// Permite cancelar la solicitud. + /// Resultados de búsqueda + /// + public Task> SearchTaxSystems(JsonObject? query = null, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(url, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var searchResult = JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - return searchResult; - } + return RequestAsync>(HttpMethod.Get, $"catalogs/tax-systems", query, null, false, cancellationToken); } + + /// + /// Buscar regímenes fiscales + /// + /// Consulta los regímenes fiscales admitidos por la API. El receptor debe declarar su régimen; esta búsqueda no lo determina. + /// + /// Parámetros de consulta. Admite CatalogSearchTaxSystemsParams. + /// Permite cancelar la solicitud. + /// Resultados de búsqueda + /// + public Task> SearchTaxSystems(CatalogSearchTaxSystemsParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/tax-systems", query, null, false, cancellationToken); + } + + /// + /// Buscar usos CFDI + /// + /// Consulta claves de uso CFDI por código o descripción. El uso debe ser declarado por el receptor. + /// + /// Parámetros de consulta. Admite CatalogSearchInvoiceUsesParams. + /// Permite cancelar la solicitud. + /// Resultados de búsqueda + /// + public Task> SearchInvoiceUses(JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/invoice-uses", query, null, false, cancellationToken); + } + + /// + /// Buscar usos CFDI + /// + /// Consulta claves de uso CFDI por código o descripción. El uso debe ser declarado por el receptor. + /// + /// Parámetros de consulta. Admite CatalogSearchInvoiceUsesParams. + /// Permite cancelar la solicitud. + /// Resultados de búsqueda + /// + public Task> SearchInvoiceUses(CatalogSearchInvoiceUsesParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/invoice-uses", query, null, false, cancellationToken); + } + } } diff --git a/Wrappers/ComercioExteriorCatalogWrapper.cs b/Wrappers/ComercioExteriorCatalogWrapper.cs new file mode 100644 index 0000000..5fb3da0 --- /dev/null +++ b/Wrappers/ComercioExteriorCatalogWrapper.cs @@ -0,0 +1,51 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable + +namespace Facturapi.Wrappers +{ + /// + /// Operaciones de ComercioExteriorCatalog. + /// + public partial class ComercioExteriorCatalogWrapper : BaseWrapper, IComercioExteriorCatalogWrapper + { + internal ComercioExteriorCatalogWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) {} + + /// + /// Buscar fracciones arancelarias + /// + /// Devuelve fracciones arancelarias que coinciden con la consulta. + /// + /// Parámetros de consulta. Admite ComercioExteriorCatalogSearchTariffFractionsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchTariffFractions(JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/comercioexterior/2.0/tariff-fractions", query, null, false, cancellationToken); + } + + /// + /// Buscar fracciones arancelarias + /// + /// Devuelve fracciones arancelarias que coinciden con la consulta. + /// + /// Parámetros de consulta. Admite ComercioExteriorCatalogSearchTariffFractionsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchTariffFractions(ComercioExteriorCatalogSearchTariffFractionsParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"catalogs/comercioexterior/2.0/tariff-fractions", query, null, false, cancellationToken); + } + + } +} diff --git a/Wrappers/CustomerWrapper.cs b/Wrappers/CustomerWrapper.cs index 625737b..5177828 100644 --- a/Wrappers/CustomerWrapper.cs +++ b/Wrappers/CustomerWrapper.cs @@ -1,18 +1,21 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; +using System.IO; using System.Collections.Generic; using System.Net.Http; -using System.Text; using System.Threading; using System.Threading.Tasks; -using Newtonsoft.Json; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { /// - /// Operaciones de clientes. + /// Operaciones de Customer. /// - public class CustomerWrapper : BaseWrapper, ICustomerWrapper + public partial class CustomerWrapper : BaseWrapper, ICustomerWrapper { internal CustomerWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) {} @@ -34,19 +37,42 @@ internal CustomerWrapper(string apiKey, string apiVersion, HttpClient httpClient /// comparten** con el ambiente _Live_. /// /// - /// Datos de la solicitud. Admite los modelos Customer*Input. + /// Datos de la solicitud. Admite CustomerCreateInput. /// Parámetros de consulta. Admite CustomerCreateParams. /// Permite cancelar la solicitud. - /// Un objeto `Customer` con la misma información ya existía + /// Un objeto `Customer` con la misma información ya existía Nuevo objeto `Customer` creado /// - public async Task CreateAsync(Dictionary data, Dictionary queryParams = null, CancellationToken cancellationToken = default) + public Task CreateAsync(JsonObject data, JsonObject? queryParams = null, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.CreateCustomer(queryParams), content, cancellationToken).ConfigureAwait(false)) - { - await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - return JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync().ConfigureAwait(false), jsonSettings); - } + return RequestAsync(HttpMethod.Post, $"customers", queryParams, data, true, cancellationToken); + } + + /// + /// Crear cliente + /// + /// Registra un nuevo cliente en Facturapi. + /// + /// Esta llamada valida que los datos fiscales coincidan con + /// los registros del SAT para ese RFC, de lo contrario, la llamada + /// devolverá un error indicando el problema. + /// + /// Una vez creado el cliente y obtenido un objeto de respuesta, + /// te recomendamos guardar el ID en tu base de datos junto a la información + /// de tu cliente. Posteriormente, puedes llamar al endpoint de Crear Factura + /// pasando el ID del cliente en lugar de repetir la información. + /// + /// Por último, ten en cuenta que los clientes que crees en ambiente _Test_ **no se + /// comparten** con el ambiente _Live_. + /// + /// + /// Datos de la solicitud. Admite CustomerCreateInput. + /// Parámetros de consulta. Admite CustomerCreateParams. + /// Permite cancelar la solicitud. + /// Un objeto `Customer` con la misma información ya existía Nuevo objeto `Customer` creado + /// + public Task CreateAsync(CustomerCreateInput data, CustomerCreateParams? queryParams = null, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"customers", queryParams, data, true, cancellationToken); } /// @@ -58,13 +84,23 @@ public async Task CreateAsync(Dictionary data, Diction /// Permite cancelar la solicitud. /// Resultado de la búsqueda /// - public async Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default) + public Task> ListAsync(JsonObject? query = null, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.ListCustomers(query), cancellationToken).ConfigureAwait(false)) - { - await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - return JsonConvert.DeserializeObject>(await response.Content.ReadAsStringAsync().ConfigureAwait(false), jsonSettings); - } + return RequestAsync>(HttpMethod.Get, $"customers", query, null, false, cancellationToken); + } + + /// + /// Listar clientes + /// + /// Regresa una lista paginada de todos los clientes de una organización o realiza una búsqueda de acuerdo a parámetros + /// + /// Parámetros de consulta. Admite CustomerListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> ListAsync(CustomerListParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"customers", query, null, false, cancellationToken); } /// @@ -76,13 +112,25 @@ public async Task> ListAsync(Dictionary q /// Permite cancelar la solicitud. /// Objeto `Customer` /// - public async Task RetrieveAsync(string id, CancellationToken cancellationToken = default) + public Task RetrieveAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"customers/{Uri.EscapeDataString(id)}", null, null, false, cancellationToken); + } + + /// + /// Editar cliente + /// + /// Actualiza la información de un cliente existente, asignando los valores de los parámetros enviados. Los parámetros que no se envíen en la petición no se modificarán. + /// + /// ID del objeto a editar + /// Datos de la solicitud. Admite CustomerUpdateInput. + /// Parámetros de consulta. Admite CustomerUpdateParams. + /// Permite cancelar la solicitud. + /// Objeto `Customer` editado correctamente + /// + public Task UpdateAsync(string id, JsonObject data, JsonObject? queryParams = null, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.RetrieveCustomer(id), cancellationToken).ConfigureAwait(false)) - { - await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - return JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync().ConfigureAwait(false), jsonSettings); - } + return RequestAsync(HttpMethod.Put, $"customers/{Uri.EscapeDataString(id)}", queryParams, data, true, cancellationToken); } /// @@ -91,19 +139,14 @@ public async Task RetrieveAsync(string id, CancellationToken cancellat /// Actualiza la información de un cliente existente, asignando los valores de los parámetros enviados. Los parámetros que no se envíen en la petición no se modificarán. /// /// ID del objeto a editar - /// Datos de la solicitud. Admite los modelos Customer*Input. + /// Datos de la solicitud. Admite CustomerUpdateInput. /// Parámetros de consulta. Admite CustomerUpdateParams. /// Permite cancelar la solicitud. /// Objeto `Customer` editado correctamente /// - public async Task UpdateAsync(string id, Dictionary data, Dictionary queryParams = null, CancellationToken cancellationToken = default) + public Task UpdateAsync(string id, CustomerUpdateInput data, CustomerUpdateParams? queryParams = null, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PutAsync(Router.UpdateCustomer(id, queryParams), content, cancellationToken).ConfigureAwait(false)) - { - await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - return JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync().ConfigureAwait(false), jsonSettings); - } + return RequestAsync(HttpMethod.Put, $"customers/{Uri.EscapeDataString(id)}", queryParams, data, true, cancellationToken); } /// @@ -115,13 +158,9 @@ public async Task UpdateAsync(string id, Dictionary da /// Permite cancelar la solicitud. /// Objeto `Customer` eliminado correctamente /// - public async Task DeleteAsync(string id, CancellationToken cancellationToken = default) + public Task DeleteAsync(string id, CancellationToken cancellationToken = default) { - using (var response = await client.DeleteAsync(Router.DeleteCustomer(id), cancellationToken).ConfigureAwait(false)) - { - await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - return JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync().ConfigureAwait(false), jsonSettings); - } + return RequestAsync(HttpMethod.Delete, $"customers/{Uri.EscapeDataString(id)}", null, null, false, cancellationToken); } /// @@ -142,13 +181,9 @@ public async Task DeleteAsync(string id, CancellationToken cancellatio /// Permite cancelar la solicitud. /// Resultado de la validación /// - public async Task ValidateTaxInfoAsync(string id, CancellationToken cancellationToken = default) + public Task ValidateTaxInfoAsync(string id, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.ValidateCustomerTaxInfo(id), cancellationToken).ConfigureAwait(false)) - { - await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - return JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync().ConfigureAwait(false), jsonSettings); - } + return RequestAsync(HttpMethod.Get, $"customers/{Uri.EscapeDataString(id)}/tax-info-validation", null, null, false, cancellationToken); } /// @@ -160,17 +195,31 @@ public async Task ValidateTaxInfoAsync(string id, Cancellatio /// /// /// ID del objeto `Customer` a editar - /// Datos de la solicitud. Admite CustomerEditLinkEmailInput. + /// Datos de la solicitud. Admite SendEditLinkByEmailInput. /// Permite cancelar la solicitud. /// Enlace de edición enviado correctamente /// - public async Task SendEditLinkByEmailAsync(string id, Dictionary data, CancellationToken cancellationToken = default) + public Task SendEditLinkByEmailAsync(string id, JsonObject data, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.SendEditLinkByEmail(id), content, cancellationToken).ConfigureAwait(false)) - { - await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - } + return RequestAsync(HttpMethod.Post, $"customers/{Uri.EscapeDataString(id)}/email-edit-link", null, data, true, cancellationToken); + } + + /// + /// Enviar enlace de edición por correo electrónico + /// + /// Envía un enlace para que el cliente pueda editar su información fiscal. + /// + /// Este enlace estará disponible en el campo `edit_link`, será válido por 3 días y sólo se podrá usar una vez. + /// + /// + /// ID del objeto `Customer` a editar + /// Datos de la solicitud. Admite SendEditLinkByEmailInput. + /// Permite cancelar la solicitud. + /// Enlace de edición enviado correctamente + /// + public Task SendEditLinkByEmailAsync(string id, SendEditLinkByEmailInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"customers/{Uri.EscapeDataString(id)}/email-edit-link", null, data, true, cancellationToken); } /// @@ -193,7 +242,7 @@ public async Task SendEditLinkByEmailAsync(string id, Dictionary /// /// País MEX, u omitido. Requiere razón social, RFC, régimen fiscal y código postal. Los RFC genéricos usan CustomerGenericCreateInput. /// Permite cancelar la solicitud. - /// Un objeto `Customer` con la misma información ya existía + /// Un objeto `Customer` con la misma información ya existía Nuevo objeto `Customer` creado /// public Task CreateNationalAsync(CustomerNationalCreateInput data, CancellationToken cancellationToken = default) { @@ -220,7 +269,7 @@ public Task CreateNationalAsync(CustomerNationalCreateInput data, Canc /// /// Requiere razón social y domicilio con un país explícito distinto de MEX. El identificador fiscal y el código postal son opcionales; el régimen fiscal predeterminado es 616. /// Permite cancelar la solicitud. - /// Un objeto `Customer` con la misma información ya existía + /// Un objeto `Customer` con la misma información ya existía Nuevo objeto `Customer` creado /// public Task CreateForeignAsync(CustomerForeignCreateInput data, CancellationToken cancellationToken = default) { @@ -247,7 +296,7 @@ public Task CreateForeignAsync(CustomerForeignCreateInput data, Cancel /// /// RFC de público en general XAXX010101000 o RFC genérico extranjero XEXX010101000. Requiere razón social y RFC. El régimen fiscal predeterminado es 616. El código postal es opcional; null o una cadena vacía se tratan como omitidos. /// Permite cancelar la solicitud. - /// Un objeto `Customer` con la misma información ya existía + /// Un objeto `Customer` con la misma información ya existía Nuevo objeto `Customer` creado /// public Task CreateGenericAsync(CustomerGenericCreateInput data, CancellationToken cancellationToken = default) { @@ -274,11 +323,11 @@ public Task CreateGenericAsync(CustomerGenericCreateInput data, Cancel /// /// La información del cliente puede estar incompleta cuando createEditLink=true. Los campos opcionales con valor null se tratan como omitidos. Los valores no nulos deben conservar formatos válidos. /// Permite cancelar la solicitud. - /// Un objeto `Customer` con la misma información ya existía + /// Un objeto `Customer` con la misma información ya existía Nuevo objeto `Customer` creado /// public Task CreateWithEditLinkAsync(CustomerCreateWithEditLinkInput data, CancellationToken cancellationToken = default) { - return CreateAsync(data, new Dictionary { ["createEditLink"] = true }, cancellationToken); + return CreateAsync(data, new Dictionary { ["createEditLink"] = true }, cancellationToken); } /// @@ -286,14 +335,14 @@ public Task CreateWithEditLinkAsync(CustomerCreateWithEditLinkInput da /// /// Actualiza la información de un cliente existente, asignando los valores de los parámetros enviados. Los parámetros que no se envíen en la petición no se modificarán. /// - /// ID del cliente. + /// ID del objeto a editar /// Con createEditLink=true, los campos omitidos conservan su valor y null borra el valor existente, incluidos los datos fiscales. Los valores no nulos deben ser válidos. En email, phone y los campos opcionales street, exterior, interior, neighborhood, city, municipality y state del domicilio, una cadena vacía o sólo espacios se normaliza a null. El código postal vacío no se acepta. /// Permite cancelar la solicitud. /// Objeto `Customer` editado correctamente /// public Task UpdateWithEditLinkAsync(string id, CustomerUpdateWithEditLinkInput data, CancellationToken cancellationToken = default) { - return UpdateAsync(id, data, new Dictionary { ["createEditLink"] = true }, cancellationToken); + return UpdateAsync(id, data, new Dictionary { ["createEditLink"] = true }, cancellationToken); } } diff --git a/Wrappers/ICartaporteCatalogWrapper.cs b/Wrappers/ICartaporteCatalogWrapper.cs index 3beb615..3c2cc7e 100644 --- a/Wrappers/ICartaporteCatalogWrapper.cs +++ b/Wrappers/ICartaporteCatalogWrapper.cs @@ -1,20 +1,242 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public interface ICartaporteCatalogWrapper + /// + /// Operaciones de CartaporteCatalog para inyección de dependencias. + /// + public partial interface ICartaporteCatalogWrapper { - Task> SearchAirTransportCodes(Dictionary query = null, CancellationToken cancellationToken = default); - Task> SearchTransportConfigs(Dictionary query = null, CancellationToken cancellationToken = default); - Task> SearchRightsOfPassage(Dictionary query = null, CancellationToken cancellationToken = default); - Task> SearchCustomsDocuments(Dictionary query = null, CancellationToken cancellationToken = default); - Task> SearchPackagingTypes(Dictionary query = null, CancellationToken cancellationToken = default); - Task> SearchTrailerTypes(Dictionary query = null, CancellationToken cancellationToken = default); - Task> SearchHazardousMaterials(Dictionary query = null, CancellationToken cancellationToken = default); - Task> SearchNavalAuthorizations(Dictionary query = null, CancellationToken cancellationToken = default); - Task> SearchPortStations(Dictionary query = null, CancellationToken cancellationToken = default); - Task> SearchMarineContainers(Dictionary query = null, CancellationToken cancellationToken = default); + /// + /// Buscar códigos de transporte aéreo + /// + /// Devuelve entradas del catálogo de aerolíneas que coinciden con la consulta. Usado para el complemento Carta Porte. + /// + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchAirTransportCodesParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchAirTransportCodes(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar códigos de transporte aéreo + /// + /// Devuelve entradas del catálogo de aerolíneas que coinciden con la consulta. Usado para el complemento Carta Porte. + /// + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchAirTransportCodesParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchAirTransportCodes(CartaporteCatalogSearchAirTransportCodesParams? query, CancellationToken cancellationToken = default); + + /// + /// Buscar configuraciones de autotransporte + /// + /// Devuelve configuraciones de transporte (p. ej., camión/semirremolque). + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchTransportConfigsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchTransportConfigs(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar configuraciones de autotransporte + /// + /// Devuelve configuraciones de transporte (p. ej., camión/semirremolque). + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchTransportConfigsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchTransportConfigs(CartaporteCatalogSearchTransportConfigsParams? query, CancellationToken cancellationToken = default); + + /// + /// Buscar derechos de paso + /// + /// Devuelve derechos de paso ferroviarios que coinciden con la consulta. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchRightsOfPassageParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchRightsOfPassage(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar derechos de paso + /// + /// Devuelve derechos de paso ferroviarios que coinciden con la consulta. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchRightsOfPassageParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchRightsOfPassage(CartaporteCatalogSearchRightsOfPassageParams? query, CancellationToken cancellationToken = default); + + /// + /// Buscar documentos aduaneros + /// + /// Devuelve tipos de documentos aduaneros. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchCustomsDocumentsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchCustomsDocuments(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar documentos aduaneros + /// + /// Devuelve tipos de documentos aduaneros. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchCustomsDocumentsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchCustomsDocuments(CartaporteCatalogSearchCustomsDocumentsParams? query, CancellationToken cancellationToken = default); + + /// + /// Buscar tipos de empaque + /// + /// Devuelve tipos de empaque para mercancías. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchPackagingTypesParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchPackagingTypes(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar tipos de empaque + /// + /// Devuelve tipos de empaque para mercancías. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchPackagingTypesParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchPackagingTypes(CartaporteCatalogSearchPackagingTypesParams? query, CancellationToken cancellationToken = default); + + /// + /// Buscar tipos de remolque + /// + /// Devuelve tipos de remolque/semirremolque. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchTrailerTypesParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchTrailerTypes(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar tipos de remolque + /// + /// Devuelve tipos de remolque/semirremolque. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchTrailerTypesParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchTrailerTypes(CartaporteCatalogSearchTrailerTypesParams? query, CancellationToken cancellationToken = default); + + /// + /// Buscar materiales peligrosos + /// + /// Devuelve entradas del catálogo de materiales peligrosos. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchHazardousMaterialsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchHazardousMaterials(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar materiales peligrosos + /// + /// Devuelve entradas del catálogo de materiales peligrosos. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchHazardousMaterialsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchHazardousMaterials(CartaporteCatalogSearchHazardousMaterialsParams? query, CancellationToken cancellationToken = default); + + /// + /// Buscar autorizaciones navales + /// + /// Devuelve códigos de autorización naval (solo `key`). + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchNavalAuthorizationsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchNavalAuthorizations(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar autorizaciones navales + /// + /// Devuelve códigos de autorización naval (solo `key`). + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchNavalAuthorizationsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchNavalAuthorizations(CartaporteCatalogSearchNavalAuthorizationsParams? query, CancellationToken cancellationToken = default); + + /// + /// Buscar estaciones/puertos + /// + /// Devuelve entradas de estaciones aéreas/marítimas/terrestres. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchPortStationsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchPortStations(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar estaciones/puertos + /// + /// Devuelve entradas de estaciones aéreas/marítimas/terrestres. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchPortStationsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchPortStations(CartaporteCatalogSearchPortStationsParams? query, CancellationToken cancellationToken = default); + + /// + /// Buscar contenedores marítimos + /// + /// Devuelve tipos de contenedores marítimos. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchMarineContainersParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchMarineContainers(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar contenedores marítimos + /// + /// Devuelve tipos de contenedores marítimos. + /// + /// Parámetros de consulta. Admite CartaporteCatalogSearchMarineContainersParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchMarineContainers(CartaporteCatalogSearchMarineContainersParams? query, CancellationToken cancellationToken = default); + } } diff --git a/Wrappers/ICatalogWrapper.cs b/Wrappers/ICatalogWrapper.cs index 80a41b3..85cfc8d 100644 --- a/Wrappers/ICatalogWrapper.cs +++ b/Wrappers/ICatalogWrapper.cs @@ -1,12 +1,197 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public interface ICatalogWrapper + /// + /// Operaciones de Catalog para inyección de dependencias. + /// + public partial interface ICatalogWrapper { - Task> SearchProducts(Dictionary query = null, CancellationToken cancellationToken = default); - Task> SearchUnits(Dictionary query = null, CancellationToken cancellationToken = default); + /// + /// Clave Producto/Servicio + /// + /// Busca en el catálogo Productos/Servicios del SAT, el cual contiene la clave a incluir en la factura. + /// + /// Parámetros de consulta. Admite CatalogSearchProductsParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> SearchProducts(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Clave Producto/Servicio + /// + /// Busca en el catálogo Productos/Servicios del SAT, el cual contiene la clave a incluir en la factura. + /// + /// Parámetros de consulta. Admite CatalogSearchProductsParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> SearchProducts(CatalogSearchProductsParams? query, CancellationToken cancellationToken = default); + + /// + /// Unidades de medida + /// + /// Busca en el catálogo de Unidades de Medida del SAT. + /// + /// Parámetros de consulta. Admite CatalogSearchUnitsParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> SearchUnits(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Unidades de medida + /// + /// Busca en el catálogo de Unidades de Medida del SAT. + /// + /// Parámetros de consulta. Admite CatalogSearchUnitsParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> SearchUnits(CatalogSearchUnitsParams? query, CancellationToken cancellationToken = default); + + /// + /// Listar categorías raíz de productos y servicios + /// + /// Devuelve las raíces Productos y Servicios. Consulta una raíz por su clave para explorar sus divisiones. + /// + /// Permite cancelar la solicitud. + /// OK + /// + Task ListProductCategories(CancellationToken cancellationToken = default); + + /// + /// Explorar una categoría o consultar la ruta de una clave + /// + /// Explora el árbol de categorías de productos y servicios del SAT. Las categorías usan claves de 2, 4 o 6 dígitos. Una clave completa de 8 dígitos devuelve el producto y su ruta; nunca se eliminan ceros finales. La clave especial 01010101 no tiene categoría. Consultar una clase de 6 dígitos incluye un resultado paginado de productos. Consultar una clave de 8 dígitos devuelve su ruta sin listar otros productos de la clase. + /// + /// Raíz, prefijo de categoría o clave completa de producto/servicio. + /// Parámetros de consulta. Admite CatalogGetProductCategoryParams. + /// Permite cancelar la solicitud. + /// OK + /// + Task GetProductCategory(string key, JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Explorar una categoría o consultar la ruta de una clave + /// + /// Explora el árbol de categorías de productos y servicios del SAT. Las categorías usan claves de 2, 4 o 6 dígitos. Una clave completa de 8 dígitos devuelve el producto y su ruta; nunca se eliminan ceros finales. La clave especial 01010101 no tiene categoría. Consultar una clase de 6 dígitos incluye un resultado paginado de productos. Consultar una clave de 8 dígitos devuelve su ruta sin listar otros productos de la clase. + /// + /// Raíz, prefijo de categoría o clave completa de producto/servicio. + /// Parámetros de consulta. Admite CatalogGetProductCategoryParams. + /// Permite cancelar la solicitud. + /// OK + /// + Task GetProductCategory(string key, CatalogGetProductCategoryParams? query, CancellationToken cancellationToken = default); + + /// + /// Buscar códigos postales + /// + /// Busca códigos postales mexicanos. Una consulta de 1 a 5 dígitos busca por código o prefijo; el texto busca nombres de colonia, localidad/ciudad, municipio o estado, sin distinguir mayúsculas ni diacríticos. Las coincidencias exactas de nombre preceden a las parciales. Cada código postal aparece una sola vez e incluye todas sus colonias en neighborhoods. El filtro de estado se aplica en ambos casos. Sin consulta, lista códigos postales. Admite páginas y cursores; los totales de búsquedas textuales pueden estar limitados, indicado por totals_are_capped. + /// + /// Parámetros de consulta. Admite CatalogSearchZipCodesParams. + /// Permite cancelar la solicitud. + /// Resultados de búsqueda + /// + Task> SearchZipCodes(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar códigos postales + /// + /// Busca códigos postales mexicanos. Una consulta de 1 a 5 dígitos busca por código o prefijo; el texto busca nombres de colonia, localidad/ciudad, municipio o estado, sin distinguir mayúsculas ni diacríticos. Las coincidencias exactas de nombre preceden a las parciales. Cada código postal aparece una sola vez e incluye todas sus colonias en neighborhoods. El filtro de estado se aplica en ambos casos. Sin consulta, lista códigos postales. Admite páginas y cursores; los totales de búsquedas textuales pueden estar limitados, indicado por totals_are_capped. + /// + /// Parámetros de consulta. Admite CatalogSearchZipCodesParams. + /// Permite cancelar la solicitud. + /// Resultados de búsqueda + /// + Task> SearchZipCodes(CatalogSearchZipCodesParams? query, CancellationToken cancellationToken = default); + + /// + /// Consultar código postal + /// + /// Devuelve los datos de domicilio y las colonias de un código postal mexicano. + /// + /// code + /// Permite cancelar la solicitud. + /// Código postal + /// + Task GetZipCode(string code, CancellationToken cancellationToken = default); + + /// + /// Buscar países + /// + /// Busca países por código ISO de tres letras o nombre. La búsqueda ignora acentos y mayúsculas. + /// + /// Parámetros de consulta. Admite CatalogSearchCountriesParams. + /// Permite cancelar la solicitud. + /// Resultados de búsqueda + /// + Task> SearchCountries(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar países + /// + /// Busca países por código ISO de tres letras o nombre. La búsqueda ignora acentos y mayúsculas. + /// + /// Parámetros de consulta. Admite CatalogSearchCountriesParams. + /// Permite cancelar la solicitud. + /// Resultados de búsqueda + /// + Task> SearchCountries(CatalogSearchCountriesParams? query, CancellationToken cancellationToken = default); + + /// + /// Buscar regímenes fiscales + /// + /// Consulta los regímenes fiscales admitidos por la API. El receptor debe declarar su régimen; esta búsqueda no lo determina. + /// + /// Parámetros de consulta. Admite CatalogSearchTaxSystemsParams. + /// Permite cancelar la solicitud. + /// Resultados de búsqueda + /// + Task> SearchTaxSystems(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar regímenes fiscales + /// + /// Consulta los regímenes fiscales admitidos por la API. El receptor debe declarar su régimen; esta búsqueda no lo determina. + /// + /// Parámetros de consulta. Admite CatalogSearchTaxSystemsParams. + /// Permite cancelar la solicitud. + /// Resultados de búsqueda + /// + Task> SearchTaxSystems(CatalogSearchTaxSystemsParams? query, CancellationToken cancellationToken = default); + + /// + /// Buscar usos CFDI + /// + /// Consulta claves de uso CFDI por código o descripción. El uso debe ser declarado por el receptor. + /// + /// Parámetros de consulta. Admite CatalogSearchInvoiceUsesParams. + /// Permite cancelar la solicitud. + /// Resultados de búsqueda + /// + Task> SearchInvoiceUses(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar usos CFDI + /// + /// Consulta claves de uso CFDI por código o descripción. El uso debe ser declarado por el receptor. + /// + /// Parámetros de consulta. Admite CatalogSearchInvoiceUsesParams. + /// Permite cancelar la solicitud. + /// Resultados de búsqueda + /// + Task> SearchInvoiceUses(CatalogSearchInvoiceUsesParams? query, CancellationToken cancellationToken = default); + } } diff --git a/Wrappers/IComercioExteriorCatalogWrapper.cs b/Wrappers/IComercioExteriorCatalogWrapper.cs new file mode 100644 index 0000000..9cc991c --- /dev/null +++ b/Wrappers/IComercioExteriorCatalogWrapper.cs @@ -0,0 +1,42 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable + +namespace Facturapi.Wrappers +{ + /// + /// Operaciones de ComercioExteriorCatalog para inyección de dependencias. + /// + public partial interface IComercioExteriorCatalogWrapper + { + /// + /// Buscar fracciones arancelarias + /// + /// Devuelve fracciones arancelarias que coinciden con la consulta. + /// + /// Parámetros de consulta. Admite ComercioExteriorCatalogSearchTariffFractionsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchTariffFractions(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar fracciones arancelarias + /// + /// Devuelve fracciones arancelarias que coinciden con la consulta. + /// + /// Parámetros de consulta. Admite ComercioExteriorCatalogSearchTariffFractionsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchTariffFractions(ComercioExteriorCatalogSearchTariffFractionsParams? query, CancellationToken cancellationToken = default); + + } +} diff --git a/Wrappers/ICustomerWrapper.cs b/Wrappers/ICustomerWrapper.cs index 3ae7d38..a659b9c 100644 --- a/Wrappers/ICustomerWrapper.cs +++ b/Wrappers/ICustomerWrapper.cs @@ -1,14 +1,20 @@ // Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { /// - /// Operaciones de clientes para inyección de dependencias. + /// Operaciones de Customer para inyección de dependencias. /// - public interface ICustomerWrapper + public partial interface ICustomerWrapper { /// /// Crear cliente @@ -28,12 +34,37 @@ public interface ICustomerWrapper /// comparten** con el ambiente _Live_. /// /// - /// Datos de la solicitud. Admite los modelos Customer*Input. + /// Datos de la solicitud. Admite CustomerCreateInput. /// Parámetros de consulta. Admite CustomerCreateParams. /// Permite cancelar la solicitud. - /// Un objeto `Customer` con la misma información ya existía + /// Un objeto `Customer` con la misma información ya existía Nuevo objeto `Customer` creado /// - Task CreateAsync(Dictionary data, Dictionary queryParams = null, CancellationToken cancellationToken = default); + Task CreateAsync(JsonObject data, JsonObject? queryParams = null, CancellationToken cancellationToken = default); + + /// + /// Crear cliente + /// + /// Registra un nuevo cliente en Facturapi. + /// + /// Esta llamada valida que los datos fiscales coincidan con + /// los registros del SAT para ese RFC, de lo contrario, la llamada + /// devolverá un error indicando el problema. + /// + /// Una vez creado el cliente y obtenido un objeto de respuesta, + /// te recomendamos guardar el ID en tu base de datos junto a la información + /// de tu cliente. Posteriormente, puedes llamar al endpoint de Crear Factura + /// pasando el ID del cliente en lugar de repetir la información. + /// + /// Por último, ten en cuenta que los clientes que crees en ambiente _Test_ **no se + /// comparten** con el ambiente _Live_. + /// + /// + /// Datos de la solicitud. Admite CustomerCreateInput. + /// Parámetros de consulta. Admite CustomerCreateParams. + /// Permite cancelar la solicitud. + /// Un objeto `Customer` con la misma información ya existía Nuevo objeto `Customer` creado + /// + Task CreateAsync(CustomerCreateInput data, CustomerCreateParams? queryParams = null, CancellationToken cancellationToken = default); /// /// Listar clientes @@ -44,7 +75,18 @@ public interface ICustomerWrapper /// Permite cancelar la solicitud. /// Resultado de la búsqueda /// - Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default); + Task> ListAsync(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Listar clientes + /// + /// Regresa una lista paginada de todos los clientes de una organización o realiza una búsqueda de acuerdo a parámetros + /// + /// Parámetros de consulta. Admite CustomerListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> ListAsync(CustomerListParams? query, CancellationToken cancellationToken = default); /// /// Obtener cliente por ID @@ -63,12 +105,25 @@ public interface ICustomerWrapper /// Actualiza la información de un cliente existente, asignando los valores de los parámetros enviados. Los parámetros que no se envíen en la petición no se modificarán. /// /// ID del objeto a editar - /// Datos de la solicitud. Admite los modelos Customer*Input. + /// Datos de la solicitud. Admite CustomerUpdateInput. + /// Parámetros de consulta. Admite CustomerUpdateParams. + /// Permite cancelar la solicitud. + /// Objeto `Customer` editado correctamente + /// + Task UpdateAsync(string id, JsonObject data, JsonObject? queryParams = null, CancellationToken cancellationToken = default); + + /// + /// Editar cliente + /// + /// Actualiza la información de un cliente existente, asignando los valores de los parámetros enviados. Los parámetros que no se envíen en la petición no se modificarán. + /// + /// ID del objeto a editar + /// Datos de la solicitud. Admite CustomerUpdateInput. /// Parámetros de consulta. Admite CustomerUpdateParams. /// Permite cancelar la solicitud. /// Objeto `Customer` editado correctamente /// - Task UpdateAsync(string id, Dictionary data, Dictionary queryParams = null, CancellationToken cancellationToken = default); + Task UpdateAsync(string id, CustomerUpdateInput data, CustomerUpdateParams? queryParams = null, CancellationToken cancellationToken = default); /// /// Eliminar cliente @@ -110,11 +165,26 @@ public interface ICustomerWrapper /// /// /// ID del objeto `Customer` a editar - /// Datos de la solicitud. Admite CustomerEditLinkEmailInput. + /// Datos de la solicitud. Admite SendEditLinkByEmailInput. /// Permite cancelar la solicitud. /// Enlace de edición enviado correctamente /// - Task SendEditLinkByEmailAsync(string id, Dictionary data, CancellationToken cancellationToken = default); + Task SendEditLinkByEmailAsync(string id, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Enviar enlace de edición por correo electrónico + /// + /// Envía un enlace para que el cliente pueda editar su información fiscal. + /// + /// Este enlace estará disponible en el campo `edit_link`, será válido por 3 días y sólo se podrá usar una vez. + /// + /// + /// ID del objeto `Customer` a editar + /// Datos de la solicitud. Admite SendEditLinkByEmailInput. + /// Permite cancelar la solicitud. + /// Enlace de edición enviado correctamente + /// + Task SendEditLinkByEmailAsync(string id, SendEditLinkByEmailInput data, CancellationToken cancellationToken = default); /// /// Crear cliente @@ -136,7 +206,7 @@ public interface ICustomerWrapper /// /// País MEX, u omitido. Requiere razón social, RFC, régimen fiscal y código postal. Los RFC genéricos usan CustomerGenericCreateInput. /// Permite cancelar la solicitud. - /// Un objeto `Customer` con la misma información ya existía + /// Un objeto `Customer` con la misma información ya existía Nuevo objeto `Customer` creado /// Task CreateNationalAsync(CustomerNationalCreateInput data, CancellationToken cancellationToken = default); @@ -160,7 +230,7 @@ public interface ICustomerWrapper /// /// Requiere razón social y domicilio con un país explícito distinto de MEX. El identificador fiscal y el código postal son opcionales; el régimen fiscal predeterminado es 616. /// Permite cancelar la solicitud. - /// Un objeto `Customer` con la misma información ya existía + /// Un objeto `Customer` con la misma información ya existía Nuevo objeto `Customer` creado /// Task CreateForeignAsync(CustomerForeignCreateInput data, CancellationToken cancellationToken = default); @@ -184,7 +254,7 @@ public interface ICustomerWrapper /// /// RFC de público en general XAXX010101000 o RFC genérico extranjero XEXX010101000. Requiere razón social y RFC. El régimen fiscal predeterminado es 616. El código postal es opcional; null o una cadena vacía se tratan como omitidos. /// Permite cancelar la solicitud. - /// Un objeto `Customer` con la misma información ya existía + /// Un objeto `Customer` con la misma información ya existía Nuevo objeto `Customer` creado /// Task CreateGenericAsync(CustomerGenericCreateInput data, CancellationToken cancellationToken = default); @@ -208,7 +278,7 @@ public interface ICustomerWrapper /// /// La información del cliente puede estar incompleta cuando createEditLink=true. Los campos opcionales con valor null se tratan como omitidos. Los valores no nulos deben conservar formatos válidos. /// Permite cancelar la solicitud. - /// Un objeto `Customer` con la misma información ya existía + /// Un objeto `Customer` con la misma información ya existía Nuevo objeto `Customer` creado /// Task CreateWithEditLinkAsync(CustomerCreateWithEditLinkInput data, CancellationToken cancellationToken = default); @@ -217,7 +287,7 @@ public interface ICustomerWrapper /// /// Actualiza la información de un cliente existente, asignando los valores de los parámetros enviados. Los parámetros que no se envíen en la petición no se modificarán. /// - /// ID del cliente. + /// ID del objeto a editar /// Con createEditLink=true, los campos omitidos conservan su valor y null borra el valor existente, incluidos los datos fiscales. Los valores no nulos deben ser válidos. En email, phone y los campos opcionales street, exterior, interior, neighborhood, city, municipality y state del domicilio, una cadena vacía o sólo espacios se normaliza a null. El código postal vacío no se acepta. /// Permite cancelar la solicitud. /// Objeto `Customer` editado correctamente diff --git a/Wrappers/IInvoiceWrapper.cs b/Wrappers/IInvoiceWrapper.cs index 4a7bca0..8677f9a 100644 --- a/Wrappers/IInvoiceWrapper.cs +++ b/Wrappers/IInvoiceWrapper.cs @@ -1,34 +1,733 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; -using System.Collections.Generic; using System.IO; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public interface IInvoiceWrapper + /// + /// Operaciones de Invoice para inyección de dependencias. + /// + public partial interface IInvoiceWrapper { - Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default); - Task CreateAsync(Dictionary data, Dictionary options = null, CancellationToken cancellationToken = default); + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Datos de la solicitud. Admite InvoiceCreateInput. + /// Parámetros de consulta. Admite InvoiceCreateParams. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + Task CreateAsync(JsonObject data, JsonObject? options = null, CancellationToken cancellationToken = default); + + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Datos de la solicitud. Admite InvoiceCreateInput. + /// Parámetros de consulta. Admite InvoiceCreateParams. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + Task CreateAsync(InvoiceCreateInput data, InvoiceCreateParams? options = null, CancellationToken cancellationToken = default); + + /// + /// Listar facturas + /// + /// Regresa una lista paginada de todas las facturas de una organización o realiza una búsqueda de acuerdo a parámetros. + /// + /// Por defecto, los resultados se ordenan por fecha de emisión, usando el campo `date` de forma descendente. + /// + /// + /// Parámetros de consulta. Admite InvoiceListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> ListAsync(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Listar facturas + /// + /// Regresa una lista paginada de todas las facturas de una organización o realiza una búsqueda de acuerdo a parámetros. + /// + /// Por defecto, los resultados se ordenan por fecha de emisión, usando el campo `date` de forma descendente. + /// + /// + /// Parámetros de consulta. Admite InvoiceListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> ListAsync(InvoiceListParams? query, CancellationToken cancellationToken = default); + + /// + /// Obtener factura por ID + /// + /// Regresa el objeto 'Invoice' relacionado al `id` especificado. + /// + /// ID del objeto a obtener + /// Permite cancelar la solicitud. + /// Objeto `Invoice` + /// Task RetrieveAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Resumen de pago + /// + /// Devuelve la información necesaria para agregar esta factura como documento relacionado en un + /// Comprobante de Pago (complemento de pago): el número de parcialidad que corresponde según el + /// historial de pagos, el saldo anterior (`last_balance`) y el desglose de impuestos de la factura + /// prorrateado al monto que se pretende pagar. + /// + /// El valor de retorno está listo para usarse como elemento de `related_documents` al + /// [crear una factura de tipo Pago](https://docs.facturapi.io/api/#tag/invoice/operation/createInvoice). + /// + /// El parámetro `amount` debe expresarse en la divisa de la factura y no puede exceder el saldo + /// pendiente (`amount_due`). Cuando el pago se recibe en otra divisa, convierte el monto antes de + /// llamar este método. + /// + /// + /// ID de la factura de ingreso (método de pago PPD) que se desea pagar + /// amount + /// Permite cancelar la solicitud. + /// Resumen del documento relacionado + /// Task GetPaymentSummaryAsync(string id, double amount, CancellationToken cancellationToken = default); - Task CancelAsync(string id, Dictionary query = null, CancellationToken cancellationToken = default); - Task SendByEmailAsync(string id, Dictionary data = null, CancellationToken cancellationToken = default); - Task DownloadZipAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Cancelar factura + /// + /// Realiza una solicitud de cancelación de factura ante el SAT, soportando el esquema de cancelación 2022. + /// + /// Al usar este método pueden ocurrir 3 posibles resultados: + /// + /// - Que la llamada regrese un error con la explicación de por qué no se pudo cancelar. + /// - Que la llamada sea satisfactoria y regrese un objeto `invoice` con la propiedad `status: "canceled"`. + /// - Que la llamada sea satisfactoria, pero que la cancelación requiera de confirmación de parte de tu cliente, en cuyo caso se obtendrá como respuesta el objeto `invoice` con las propiedades `status: "valid"` y `cancellation_status: "pending"`. + /// + /// En el tercer escenario, el valor de `cancellation_status` será actualizado automáticamente por Facturapi cuando tu cliente acepte, rechace o deje expirar la solicitud, de tal manera que al consultar una factura (usando [Obtener Factura](https://docs.facturapi.io/api/#tag/invoice/operation/getInvoice)), la propiedad `cancellation_status` reflejará el estado más reciente de la solicitud. + /// + /// Consulta los valores posibles de `cancellation_status` más abajo. + /// + /// Después de la cancelación la factura ya no tendrá validez, el objeto cambiará su `status` a `"canceled"` y seguirá estando disponible para futuras consultas. + /// + /// Si el status de la factura es `draft`, este método la eliminará de la base de datos. + /// + /// Si el status de la factura es `canceled`, este método regresará un error. + /// + /// + /// ID de la factura a cancelar + /// Parámetros de consulta. Admite CancellationQueryInput. + /// Permite cancelar la solicitud. + /// Solicitud de cancelación exitosa + /// + Task CancelAsync(string id, JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Cancelar factura + /// + /// Realiza una solicitud de cancelación de factura ante el SAT, soportando el esquema de cancelación 2022. + /// + /// Al usar este método pueden ocurrir 3 posibles resultados: + /// + /// - Que la llamada regrese un error con la explicación de por qué no se pudo cancelar. + /// - Que la llamada sea satisfactoria y regrese un objeto `invoice` con la propiedad `status: "canceled"`. + /// - Que la llamada sea satisfactoria, pero que la cancelación requiera de confirmación de parte de tu cliente, en cuyo caso se obtendrá como respuesta el objeto `invoice` con las propiedades `status: "valid"` y `cancellation_status: "pending"`. + /// + /// En el tercer escenario, el valor de `cancellation_status` será actualizado automáticamente por Facturapi cuando tu cliente acepte, rechace o deje expirar la solicitud, de tal manera que al consultar una factura (usando [Obtener Factura](https://docs.facturapi.io/api/#tag/invoice/operation/getInvoice)), la propiedad `cancellation_status` reflejará el estado más reciente de la solicitud. + /// + /// Consulta los valores posibles de `cancellation_status` más abajo. + /// + /// Después de la cancelación la factura ya no tendrá validez, el objeto cambiará su `status` a `"canceled"` y seguirá estando disponible para futuras consultas. + /// + /// Si el status de la factura es `draft`, este método la eliminará de la base de datos. + /// + /// Si el status de la factura es `canceled`, este método regresará un error. + /// + /// + /// ID de la factura a cancelar + /// Parámetros de consulta. Admite CancellationQueryInput. + /// Permite cancelar la solicitud. + /// Solicitud de cancelación exitosa + /// + Task CancelAsync(string id, CancellationQueryInput? query, CancellationToken cancellationToken = default); + + /// + /// Enviar factura por correo electrónico + /// + /// Envía un correo electrónico a la dirección de tu cliente, con los archivos XML y PDF adjuntos al mensaje. + /// + /// ID del objeto a obtener + /// Datos de la solicitud. Admite SendInvoiceByEmailInput. + /// Permite cancelar la solicitud. + /// Objeto genérico de respuesta + /// + Task SendByEmailAsync(string id, JsonObject? data = null, CancellationToken cancellationToken = default); + + /// + /// Enviar factura por correo electrónico + /// + /// Envía un correo electrónico a la dirección de tu cliente, con los archivos XML y PDF adjuntos al mensaje. + /// + /// ID del objeto a obtener + /// Datos de la solicitud. Admite SendInvoiceByEmailInput. + /// Permite cancelar la solicitud. + /// Objeto genérico de respuesta + /// + Task SendByEmailAsync(string id, SendInvoiceByEmailInput data, CancellationToken cancellationToken = default); + + /// + /// Descargar factura + /// + /// Descarga tu Factura en PDF, XML o ambos en un archivo comprimido ZIP. + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// Task DownloadPdfAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Descargar factura + /// + /// Descarga tu Factura en PDF, XML o ambos en un archivo comprimido ZIP. + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// Task DownloadXmlAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Descargar factura + /// + /// Descarga tu Factura en PDF, XML o ambos en un archivo comprimido ZIP. + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// + Task DownloadZipAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Obtener enlace de descarga + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar la factura en PDF, XML o ambos en un archivo comprimido ZIP, sin que el archivo pase por tu servidor. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + Task DownloadPdfUrlAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Obtener enlace de descarga + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar la factura en PDF, XML o ambos en un archivo comprimido ZIP, sin que el archivo pase por tu servidor. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + Task DownloadXmlUrlAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Obtener enlace de descarga + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar la factura en PDF, XML o ambos en un archivo comprimido ZIP, sin que el archivo pase por tu servidor. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + Task DownloadZipUrlAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Solicitar ZIP mensual de facturas + /// + /// Solicita un archivo ZIP con las facturas del mes que coincidan con los filtros indicados. Consulta el estado de la solicitud y descarga el archivo cuando esté listo. + /// + /// Incluye XML y PDF de facturas vigentes y canceladas. Los archivos de facturas canceladas se agrupan en `canceladas/`. + /// + /// Requiere una llave de API de organización en ambiente Live, una suscripción activa y permiso para leer facturas. Las llaves de ambiente Test regresan HTTP 402. + /// + /// Puedes exportar el mes en curso. Consulta `is_current` para saber si el paquete refleja la información vigente; si está desactualizado, solicita nuevamente el ZIP con los mismos filtros. Los IDs anteriores siguen permitiendo descargar su paquete original. + /// + /// + /// Datos de la solicitud. Admite InvoiceZipRequestCreateInput. + /// Permite cancelar la solicitud. + /// Solicitud de ZIP procesada correctamente. + /// + Task CreateZipRequestAsync(JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Solicitar ZIP mensual de facturas + /// + /// Solicita un archivo ZIP con las facturas del mes que coincidan con los filtros indicados. Consulta el estado de la solicitud y descarga el archivo cuando esté listo. + /// + /// Incluye XML y PDF de facturas vigentes y canceladas. Los archivos de facturas canceladas se agrupan en `canceladas/`. + /// + /// Requiere una llave de API de organización en ambiente Live, una suscripción activa y permiso para leer facturas. Las llaves de ambiente Test regresan HTTP 402. + /// + /// Puedes exportar el mes en curso. Consulta `is_current` para saber si el paquete refleja la información vigente; si está desactualizado, solicita nuevamente el ZIP con los mismos filtros. Los IDs anteriores siguen permitiendo descargar su paquete original. + /// + /// + /// Datos de la solicitud. Admite InvoiceZipRequestCreateInput. + /// Permite cancelar la solicitud. + /// Solicitud de ZIP procesada correctamente. + /// + Task CreateZipRequestAsync(InvoiceZipRequestCreateInput data, CancellationToken cancellationToken = default); + + /// + /// Listar solicitudes de ZIP mensual + /// + /// Regresa una lista paginada de solicitudes de ZIP. `year` y `month` deben enviarse juntos. `invoice_types` filtra por un tipo o por un arreglo normalizado exacto. + /// + /// Este método requiere una llave de API de organización en ambiente Live, una suscripción activa y permiso para leer facturas. + /// + /// + /// Parámetros de consulta. Admite InvoiceListZipRequestsParams. + /// Permite cancelar la solicitud. + /// Resultado paginado de solicitudes de ZIP. + /// + Task> ListZipRequestsAsync(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Listar solicitudes de ZIP mensual + /// + /// Regresa una lista paginada de solicitudes de ZIP. `year` y `month` deben enviarse juntos. `invoice_types` filtra por un tipo o por un arreglo normalizado exacto. + /// + /// Este método requiere una llave de API de organización en ambiente Live, una suscripción activa y permiso para leer facturas. + /// + /// + /// Parámetros de consulta. Admite InvoiceListZipRequestsParams. + /// Permite cancelar la solicitud. + /// Resultado paginado de solicitudes de ZIP. + /// + Task> ListZipRequestsAsync(InvoiceListZipRequestsParams? query, CancellationToken cancellationToken = default); + + /// + /// Recuperar solicitud de ZIP mensual + /// + /// Recupera una solicitud de ZIP. Consulta este método hasta que el status sea `finished` o `failed`. Cuando sea `finished`, descarga el archivo con el método de descarga. + /// + /// Requiere una llave de API de organización en ambiente Live, una suscripción activa y permiso para leer facturas. + /// + /// + /// Identificador de la solicitud de ZIP. + /// Permite cancelar la solicitud. + /// Solicitud de ZIP recuperada correctamente. + /// + Task RetrieveZipRequestAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Descargar ZIP mensual + /// + /// Descarga el ZIP de una solicitud terminada. El nombre del archivo usa el formato `YYYY-MM.zip`. + /// + /// Requiere una llave de API de organización en ambiente Live, una suscripción activa y permiso para leer facturas. + /// + /// + /// Identificador de la solicitud de ZIP. + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// + Task DownloadZipRequestAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Obtener URL de descarga del ZIP mensual + /// + /// Devuelve un objeto con los metadatos del archivo y una URL temporal para descargar el ZIP de una solicitud terminada sin que el archivo viaje a través de tu servidor. + /// + /// La URL permite acceder únicamente a ese archivo mientras sea válida: trátala como una credencial y no la almacenes. Requiere una llave de API de organización en ambiente Live, una suscripción activa y permiso para leer facturas. + /// + /// + /// Identificador de la solicitud de ZIP. + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + Task DownloadZipRequestUrlAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Descargar acuse de cancelación + /// + /// Descarga en XML o PDF el acuse emitido por el SAT al solicitar la cancelación mediante Facturapi. El acuse contiene el resultado inmediato de la solicitud y no necesariamente acredita que el CFDI ya esté cancelado; consulta el estado de la factura para confirmar el desenlace. + /// + /// ID del objeto a obtener + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// Task DownloadCancellationReceiptXmlAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Descargar acuse de cancelación + /// + /// Descarga en XML o PDF el acuse emitido por el SAT al solicitar la cancelación mediante Facturapi. El acuse contiene el resultado inmediato de la solicitud y no necesariamente acredita que el CFDI ya esté cancelado; consulta el estado de la factura para confirmar el desenlace. + /// + /// ID del objeto a obtener + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// Task DownloadCancellationReceiptPdfAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Obtener enlace del acuse de cancelación + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar en XML o PDF el acuse emitido por el SAT al solicitar la cancelación mediante Facturapi. El acuse contiene el resultado inmediato de la solicitud y no necesariamente acredita que el CFDI ya esté cancelado; consulta el estado de la factura para confirmar el desenlace. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + Task DownloadCancellationReceiptPdfUrlAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Obtener enlace del acuse de cancelación + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar en XML o PDF el acuse emitido por el SAT al solicitar la cancelación mediante Facturapi. El acuse contiene el resultado inmediato de la solicitud y no necesariamente acredita que el CFDI ya esté cancelado; consulta el estado de la factura para confirmar el desenlace. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + Task DownloadCancellationReceiptXmlUrlAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Editar borrador de factura + /// + /// Actualiza la información de una factura con status `draft`, asignando + /// los valores de los parámetros enviados. Los parámetros que no se envíen + /// en la petición no se modificarán. + /// + /// En el objeto `invoice` de respuesta, Facturapi asignará automáticamente + /// el campo `is_ready_to_stamp` con el valor `true` si la factura pasa la + /// validación mínima requerida para ser timbrada; de lo contrario, el campo + /// `is_ready_to_stamp` será `false`. + /// + /// + /// ID del objeto a editar + /// Datos de la solicitud. Admite UpdateDraftInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto `Invoice` editado correctamente + /// + Task UpdateDraftAsync(string id, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Editar borrador de factura + /// + /// Actualiza la información de una factura con status `draft`, asignando + /// los valores de los parámetros enviados. Los parámetros que no se envíen + /// en la petición no se modificarán. + /// + /// En el objeto `invoice` de respuesta, Facturapi asignará automáticamente + /// el campo `is_ready_to_stamp` con el valor `true` si la factura pasa la + /// validación mínima requerida para ser timbrada; de lo contrario, el campo + /// `is_ready_to_stamp` será `false`. + /// + /// + /// ID del objeto a editar + /// Datos de la solicitud. Admite UpdateDraftInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto `Invoice` editado correctamente + /// + Task UpdateDraftAsync(string id, UpdateDraftInvoiceInput data, CancellationToken cancellationToken = default); + + /// + /// Timbrar borrador de factura + /// + /// Timbra una factura con status `draft` y la envía al SAT para su validación. + /// + /// Al usar este método, el valor del campo `is_ready_to_stamp` (asignado por Facturapi) + /// deberá ser `true`. De otra forma, la llamada regresará un error. + /// + /// Este método no permite editar la factura, sólo timbrarla. Si necesitas editar información + /// en la factura antes de timbrarla, usa el método [Editar Borrador de Factura](https://docs.facturapi.io/api/#tag/invoice/operation/editDraftInvoice). + /// + /// + /// ID del objeto a timbrar + /// Parámetros de consulta. Admite InvoiceStampDraftParams. + /// Permite cancelar la solicitud. + /// Objeto `Invoice` timbrado correctamente + /// + Task StampDraftAsync(string id, JsonObject? options = null, CancellationToken cancellationToken = default); + + /// + /// Timbrar borrador de factura + /// + /// Timbra una factura con status `draft` y la envía al SAT para su validación. + /// + /// Al usar este método, el valor del campo `is_ready_to_stamp` (asignado por Facturapi) + /// deberá ser `true`. De otra forma, la llamada regresará un error. + /// + /// Este método no permite editar la factura, sólo timbrarla. Si necesitas editar información + /// en la factura antes de timbrarla, usa el método [Editar Borrador de Factura](https://docs.facturapi.io/api/#tag/invoice/operation/editDraftInvoice). + /// + /// + /// ID del objeto a timbrar + /// Parámetros de consulta. Admite InvoiceStampDraftParams. + /// Permite cancelar la solicitud. + /// Objeto `Invoice` timbrado correctamente + /// + Task StampDraftAsync(string id, InvoiceStampDraftParams? options, CancellationToken cancellationToken = default); + + /// + /// Actualizar status de factura + /// + /// + /// Consulta el status de una factura timbrada en el SAT y actualiza el objeto invoice + /// con La información más reciente. + /// + /// + /// ID del objeto invoice a actualizar + /// Permite cancelar la solicitud. + /// Objeto `Invoice` actualizado + /// Task UpdateStatusAsync(string id, CancellationToken cancellationToken = default); - Task UpdateDraftAsync(string id, Dictionary data, CancellationToken cancellationToken = default); - Task StampDraftAsync(string id, Dictionary options = null, CancellationToken cancellationToken = default); - [Obsolete("Use StampDraftAsync instead.")] - Task StampDraft(string id, Dictionary options = null, CancellationToken cancellationToken = default); + + /// + /// Copiar a borrador + /// + /// Crea una copia en borrador de la factura especificada. + /// + /// + /// ID de la factura a copiar + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` con status `draft`. + /// Task CopyToDraftAsync(string id, CancellationToken cancellationToken = default); - Task PreviewPdfAsync(Dictionary data, CancellationToken cancellationToken = default); - Task> CreateZipRequestAsync(Dictionary data, CancellationToken cancellationToken = default); - Task>> ListZipRequestsAsync(Dictionary query = null, CancellationToken cancellationToken = default); - Task> RetrieveZipRequestAsync(string id, CancellationToken cancellationToken = default); - Task DownloadZipRequestAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Vista previa de factura en PDF + /// + /// Genera una vista previa en PDF de una factura sin timbrar ni guardar en la organización. + /// + /// Datos de la solicitud. Admite UpdateDraftInvoiceInput. + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// + Task PreviewPdfAsync(JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Vista previa de factura en PDF + /// + /// Genera una vista previa en PDF de una factura sin timbrar ni guardar en la organización. + /// + /// Datos de la solicitud. Admite UpdateDraftInvoiceInput. + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// + Task PreviewPdfAsync(UpdateDraftInvoiceInput data, CancellationToken cancellationToken = default); + + /// + /// Obtener URL del preview PDF de factura + /// + /// Devuelve un objeto con los metadatos del archivo y una URL temporal para el preview PDF de una factura sin timbrar. + /// + /// Datos de la solicitud. Admite UpdateDraftInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + Task PreviewPdfUrlAsync(JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Obtener URL del preview PDF de factura + /// + /// Devuelve un objeto con los metadatos del archivo y una URL temporal para el preview PDF de una factura sin timbrar. + /// + /// Datos de la solicitud. Admite UpdateDraftInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + Task PreviewPdfUrlAsync(UpdateDraftInvoiceInput data, CancellationToken cancellationToken = default); + + /// + /// Timbrar borrador de factura + /// + /// Timbra una factura con status `draft` y la envía al SAT para su validación. + /// + /// Al usar este método, el valor del campo `is_ready_to_stamp` (asignado por Facturapi) + /// deberá ser `true`. De otra forma, la llamada regresará un error. + /// + /// Este método no permite editar la factura, sólo timbrarla. Si necesitas editar información + /// en la factura antes de timbrarla, usa el método [Editar Borrador de Factura](https://docs.facturapi.io/api/#tag/invoice/operation/editDraftInvoice). + /// + /// + /// id + /// options + /// Permite cancelar la solicitud. + /// Objeto `Invoice` timbrado correctamente + /// + [Obsolete("Use StampDraftAsync instead.")] + Task StampDraft(string id, JsonObject? options = null, CancellationToken cancellationToken = default); + + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Ingreso + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + Task CreateIngresoAsync(InvoiceIngresoInput data, CancellationToken cancellationToken = default); + + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Egreso + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + Task CreateEgresoAsync(InvoiceEgresoInput data, CancellationToken cancellationToken = default); + + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Pago + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + Task CreatePagoAsync(InvoicePagoInput data, CancellationToken cancellationToken = default); + + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Nómina + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + Task CreateNominaAsync(InvoiceNominaInput data, CancellationToken cancellationToken = default); + + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Traslado + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + Task CreateTrasladoAsync(InvoiceTrasladoInput data, CancellationToken cancellationToken = default); + + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Datos de la factura según su tipo y estado inicial. Omite status para timbrar; usa draft para guardar un borrador. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + Task CreateDraftIngresoAsync(InvoiceIngresoDraftInput data, CancellationToken cancellationToken = default); + + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Datos de la factura según su tipo y estado inicial. Omite status para timbrar; usa draft para guardar un borrador. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + Task CreateDraftEgresoAsync(InvoiceEgresoDraftInput data, CancellationToken cancellationToken = default); + + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Datos de la factura según su tipo y estado inicial. Omite status para timbrar; usa draft para guardar un borrador. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + Task CreateDraftPagoAsync(InvoicePagoDraftInput data, CancellationToken cancellationToken = default); + + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Datos de la factura según su tipo y estado inicial. Omite status para timbrar; usa draft para guardar un borrador. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + Task CreateDraftNominaAsync(InvoiceNominaDraftInput data, CancellationToken cancellationToken = default); + + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Datos de la factura según su tipo y estado inicial. Omite status para timbrar; usa draft para guardar un borrador. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + Task CreateDraftTrasladoAsync(InvoiceTrasladoDraftInput data, CancellationToken cancellationToken = default); + } } diff --git a/Wrappers/INominaCatalogWrapper.cs b/Wrappers/INominaCatalogWrapper.cs index 24971c2..a691cd5 100644 --- a/Wrappers/INominaCatalogWrapper.cs +++ b/Wrappers/INominaCatalogWrapper.cs @@ -1,12 +1,64 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public interface INominaCatalogWrapper + /// + /// Operaciones de NominaCatalog para inyección de dependencias. + /// + public partial interface INominaCatalogWrapper { - Task> SearchDeductions(Dictionary query = null, CancellationToken cancellationToken = default); - Task> SearchPerceptions(Dictionary query = null, CancellationToken cancellationToken = default); + /// + /// Buscar tipos de deducción de nómina + /// + /// Devuelve tipos de deducción que coinciden con la consulta. + /// + /// Parámetros de consulta. Admite NominaCatalogSearchDeductionsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchDeductions(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar tipos de deducción de nómina + /// + /// Devuelve tipos de deducción que coinciden con la consulta. + /// + /// Parámetros de consulta. Admite NominaCatalogSearchDeductionsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchDeductions(NominaCatalogSearchDeductionsParams? query, CancellationToken cancellationToken = default); + + /// + /// Buscar tipos de percepción de nómina + /// + /// Devuelve tipos de percepción que coinciden con la consulta. + /// + /// Parámetros de consulta. Admite NominaCatalogSearchPerceptionsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchPerceptions(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Buscar tipos de percepción de nómina + /// + /// Devuelve tipos de percepción que coinciden con la consulta. + /// + /// Parámetros de consulta. Admite NominaCatalogSearchPerceptionsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + Task> SearchPerceptions(NominaCatalogSearchPerceptionsParams? query, CancellationToken cancellationToken = default); + } } diff --git a/Wrappers/IOrganizationWrapper.cs b/Wrappers/IOrganizationWrapper.cs index 07c7c75..2c2beac 100644 --- a/Wrappers/IOrganizationWrapper.cs +++ b/Wrappers/IOrganizationWrapper.cs @@ -1,51 +1,783 @@ -using System.Collections.Generic; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; using System.IO; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public interface IOrganizationWrapper + /// + /// Operaciones de Organization para inyección de dependencias. + /// + public partial interface IOrganizationWrapper { - Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default); - Task MeAsync(CancellationToken cancellationToken = default); - Task CheckDomainIsAvailableAsync(string domain, CancellationToken cancellationToken = default); - Task CreateAsync(Dictionary data, CancellationToken cancellationToken = default); + /// + /// Crear organización + /// + /// Crea una nueva Organización que pertenecerá a tu cuenta de usuario. + /// + /// Después de crear la organización y antes de poder emitir facturas con + /// la organización, deberás de terminar de configurarla llamando a los + /// métodos de [Actualizar datos fiscales](https://docs.facturapi.io/api/#tag/organization/operation/editOrganizationLegal) y + /// [Subir certificados (CSD)](https://docs.facturapi.io/api/#tag/organization/operation/uploadOrganizationCertificate) + /// + /// + /// Después de crear la organización y antes de poder emitir facturas con + /// la organización, deberás de terminar de configurarla llamando a los + /// métodos de [Actualizar datos fiscales](https://docs.facturapi.io/api/#tag/organization/operation/editOrganizationLegal) y + /// [Subir certificados (CSD)](https://docs.facturapi.io/api/#tag/organization/operation/uploadOrganizationCertificate), + /// además de firmar la Carta Manifiesto que autoriza a nuestro PAC a timbrar facturas; + /// puedes hacerlo en [tu dashboard](https://dashboard.facturapi.io/settings/manifiesto) + /// o en [nuestro portal público](https://www.facturapi.io/manifiesto). También puedes incrustar + /// en tu solución el módulo de firma de la carta (sin logos, listo para iframe): https://www.facturapi.io/embedded/manifiesto + /// + /// Recuerda que los folios de tu suscripción podrán ser consumidos por + /// cualquiera de las organizaciones registradas bajo tu cuenta. + /// + /// + /// Datos de la solicitud. Admite OrganizationCreateInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Organization` creado + /// + Task CreateAsync(JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Crear organización + /// + /// Crea una nueva Organización que pertenecerá a tu cuenta de usuario. + /// + /// Después de crear la organización y antes de poder emitir facturas con + /// la organización, deberás de terminar de configurarla llamando a los + /// métodos de [Actualizar datos fiscales](https://docs.facturapi.io/api/#tag/organization/operation/editOrganizationLegal) y + /// [Subir certificados (CSD)](https://docs.facturapi.io/api/#tag/organization/operation/uploadOrganizationCertificate) + /// + /// + /// Después de crear la organización y antes de poder emitir facturas con + /// la organización, deberás de terminar de configurarla llamando a los + /// métodos de [Actualizar datos fiscales](https://docs.facturapi.io/api/#tag/organization/operation/editOrganizationLegal) y + /// [Subir certificados (CSD)](https://docs.facturapi.io/api/#tag/organization/operation/uploadOrganizationCertificate), + /// además de firmar la Carta Manifiesto que autoriza a nuestro PAC a timbrar facturas; + /// puedes hacerlo en [tu dashboard](https://dashboard.facturapi.io/settings/manifiesto) + /// o en [nuestro portal público](https://www.facturapi.io/manifiesto). También puedes incrustar + /// en tu solución el módulo de firma de la carta (sin logos, listo para iframe): https://www.facturapi.io/embedded/manifiesto + /// + /// Recuerda que los folios de tu suscripción podrán ser consumidos por + /// cualquiera de las organizaciones registradas bajo tu cuenta. + /// + /// + /// Datos de la solicitud. Admite OrganizationCreateInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Organization` creado + /// + Task CreateAsync(OrganizationCreateInput data, CancellationToken cancellationToken = default); + + /// + /// Listar organizaciones + /// + /// Regresa una lista paginada de todas las organizationes registradas bajo tu cuenta, o realiza una búsqueda de acuerdo a parámetros. + /// + /// Parámetros de consulta. Admite OrganizationListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> ListAsync(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Listar organizaciones + /// + /// Regresa una lista paginada de todas las organizationes registradas bajo tu cuenta, o realiza una búsqueda de acuerdo a parámetros. + /// + /// Parámetros de consulta. Admite OrganizationListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> ListAsync(OrganizationListParams? query, CancellationToken cancellationToken = default); + + /// + /// Obtener organización por ID + /// + /// Regresa el objeto 'Organization' relacionado al `id` especificado. + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Objeto `Organization` + /// Task RetrieveAsync(string id, CancellationToken cancellationToken = default); - Task DeleteAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Editar datos fiscales + /// + /// Actualiza los datos fiscales de la organización. + /// + /// Si estás buscando cómo editar el RFC, recuerda que la propiedad + /// `tax_id` se asigna automáticamente al subir los Certificados de Sello + /// Digital. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationLegalInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + Task UpdateLegalAsync(string id, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Editar datos fiscales + /// + /// Actualiza los datos fiscales de la organización. + /// + /// Si estás buscando cómo editar el RFC, recuerda que la propiedad + /// `tax_id` se asigna automáticamente al subir los Certificados de Sello + /// Digital. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationLegalInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + Task UpdateLegalAsync(string id, OrganizationLegalInput data, CancellationToken cancellationToken = default); + + /// + /// Editar personalización + /// + /// Actualiza la información relacionada con la identidad o branding de la organización. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationCustomizationInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + Task UpdateCustomizationAsync(string id, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Editar personalización + /// + /// Actualiza la información relacionada con la identidad o branding de la organización. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationCustomizationInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + Task UpdateCustomizationAsync(string id, OrganizationCustomizationInput data, CancellationToken cancellationToken = default); + + /// + /// Editar config. recibos + /// + /// Actualiza los campos enviados de la configuración de recibos de la organización. + /// Para activar la generación automática de facturas globales, la organización + /// debe tener contratado ese feature. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationReceiptsInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + Task UpdateReceiptSettingsAsync(string id, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Editar config. recibos + /// + /// Actualiza los campos enviados de la configuración de recibos de la organización. + /// Para activar la generación automática de facturas globales, la organización + /// debe tener contratado ese feature. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationReceiptsInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + Task UpdateReceiptSettingsAsync(string id, OrganizationReceiptsInput data, CancellationToken cancellationToken = default); + + /// + /// Elegir dominio de autofactura + /// + /// Elige el dominio que utilizará esta organización en su micrositio de + /// autofactura. Una vez elegido el dominio, deberás ponerte en contacto + /// con nosotros si necesitas cambiarlo. + /// + /// El dominio que elijas será el que aparecerá en el campo + /// `self_invoice_url` al crear un nuevo recibo, de la siguiente manera: + /// + /// `https://factura.space/{DOMAIN}/{RECEIPT_KEY}` + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationDomainInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + Task UpdateDomainAsync(string id, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Elegir dominio de autofactura + /// + /// Elige el dominio que utilizará esta organización en su micrositio de + /// autofactura. Una vez elegido el dominio, deberás ponerte en contacto + /// con nosotros si necesitas cambiarlo. + /// + /// El dominio que elijas será el que aparecerá en el campo + /// `self_invoice_url` al crear un nuevo recibo, de la siguiente manera: + /// + /// `https://factura.space/{DOMAIN}/{RECEIPT_KEY}` + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationDomainInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + Task UpdateDomainAsync(string id, OrganizationDomainInput data, CancellationToken cancellationToken = default); + + /// + /// Revisar dominio disponible + /// + /// Revisa si un identificador está disponible para elegir como dominio para el portal de autofactura. + /// + /// domain + /// Permite cancelar la solicitud. + /// Información de disponibilidad de dominio + /// + Task CheckDomainIsAvailableAsync(string domain, CancellationToken cancellationToken = default); + + /// + /// Subir logotipo + /// + /// Sube el logotipo de la organización que será colocado en el PDF y en + /// los correos que se envían al cliente con la factura adjunta. + /// + /// El archivo debe ser una imagen en formato JPG o PNG y tener un tamaño + /// no mayor a 500 KB. Las dimensiones recomendadas son 800 × 500px. + /// + /// Si la organización ya tiene un logotipo, esta llamada reemplaza el + /// logotipo anterior. + /// + /// + /// ID de la organización + /// Format: binary Contenido binario del archivo con la imagen que se usará como logotipo. Formatos soportados: - jpg - png - svg Usa un Stream; se dispone al finalizar la solicitud. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// Task UploadLogoAsync(string id, Stream file, CancellationToken cancellationToken = default); + + /// + /// Subir certificados (CSD) + /// + /// Sube los archivos del Certificado de Sello Digital (CSD) proporcionado + /// por el SAT. Esta llamada también debe usarse para reemplazar los + /// certificados existentes en caso de solicitar nuevos. + /// + /// Al actualizar tus certificados se leerá el RFC y asignará + /// automáticamente a `legal.tax_id`. + /// + /// + /// ID de la organización + /// Format: binary Contenido binario del archivo con extensión `.cer` del certificado CSD. Usa un Stream; se dispone al finalizar la solicitud. + /// Format: binary Contenido binario del archivo con extensión `.key` del certificado CSD. Usa un Stream; se dispone al finalizar la solicitud. + /// Contraseña de la llave del certificado. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// Task UploadCertificateAsync(string id, Stream cerFile, Stream keyFile, string password, CancellationToken cancellationToken = default); - Task DeleteCertificateAsync(string id, CancellationToken cancellationToken = default); - Task UpdateLegalAsync(string id, Dictionary data, CancellationToken cancellationToken = default); - Task UpdateReceiptSettingsAsync(string id, Dictionary data, CancellationToken cancellationToken = default); - Task UpdateCustomizationAsync(string id, Dictionary data, CancellationToken cancellationToken = default); - Task UpdateDomainAsync(string id, Dictionary data, CancellationToken cancellationToken = default); + + /// + /// Eliminar certificados (CSD) + /// + /// Elimina los certificados (CSD) de tu organización. + /// + /// Esto no afecta a las facturas ya emitidas, pero no podrás emitir nuevas facturas hasta que subas nuevos certificados. + /// + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + Task DeleteCertificateAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Obtener enlace de descarga de Carta Manifiesto + /// + /// Devuelve un enlace temporal para descargar en ZIP la Carta Manifiesto firmada que corresponde al RFC del CSD cargado en la organización. + /// + /// La organización debe tener un CSD cargado y debe existir una Carta Manifiesto firmada para el RFC extraído de ese certificado. El enlace da acceso al archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID de la organización. También puedes usar `me` con una Secret Key de la organización. + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal para descargar la Carta Manifiesto en ZIP, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + Task DownloadManifiestoZipUrlAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Eliminar organización + /// + /// Elimina la organización de tu cuenta de Facturapi. Una vez eliminada, + /// ya no podrás acceder a sus recursos, tales como clientes, productos, + /// facturas, recibos o retenciones. + /// + /// + /// ID del objeto a eliminar + /// Permite cancelar la solicitud. + /// Objeto `Organization` eliminado correctamente + /// + Task DeleteAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Obtener Test Api Key + /// + /// Obtiene la llave secreta de ambiente Test de la organización. + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Test API Key + /// Task GetTestApiKeyAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Renovar Test API Key + /// + /// Renueva la llave secreta de ambiente Test de la organización e invalida inmediatamente la anterior. + /// + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Test API Key + /// Task RenewTestApiKeyAsync(string id, CancellationToken cancellationToken = default); - Task ListLiveApiKeysAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Listar Live API Keys + /// + /// Listar llaves secretas de ambiente Live de la organización. + /// + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Live API Key + /// + Task> ListLiveApiKeysAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Crear Live API Key + /// + /// Genera una nueva llave secreta de ambiente Live de la organización. + /// Esta operación no invalida las llaves generadas previamente. El endpoint usa `PUT` + /// por compatibilidad histórica, pero su comportamiento es crear una nueva llave. + /// + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Live API Key + /// Task RenewLiveApiKeyAsync(string id, CancellationToken cancellationToken = default); - Task> ListSeriesAsync(string id, CancellationToken cancellationToken = default); - Task CreateSeriesAsync(string id, Dictionary data, CancellationToken cancellationToken = default); - Task UpdateSeriesAsync(string id, string seriesName, Dictionary data, CancellationToken cancellationToken = default); - Task DeleteSeriesAsync(string id, string seriesName, CancellationToken cancellationToken = default); - Task UpdateDefaultSeriesAsync(string organizationId, Dictionary data, CancellationToken cancellationToken = default); + + /// + /// Revocar Live API Key + /// + /// Revocar Live Api Key de tu organización. + /// + /// + /// ID de la organización + /// ID de la llave secreta a eliminar + /// Permite cancelar la solicitud. + /// Live API Key + /// Task> DeleteLiveApiKeyAsync(string id, string apiKeyId, CancellationToken cancellationToken = default); - Task UpdateSelfInvoiceSettingsAsync(string organizationId, Dictionary data, CancellationToken cancellationToken = default); + + /// + /// Listado de series + /// + /// Listado de series creadas para la personalización de organización. La cual lleva control de foliaje para cada tipo de factura si está asignada en las personalización de organización. + /// + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Listado de objetos `Series` creadas previamente + /// + Task> ListSeriesAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Crear serie + /// + /// Crea una nueva serie de folios para la organización. + /// Las series son útiles para llevar un control de los folios emitidos para cada tipo de factura. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationSeriesCreateInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto de la `Serie` creada + /// + Task> CreateSeriesAsync(string id, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Crear serie + /// + /// Crea una nueva serie de folios para la organización. + /// Las series son útiles para llevar un control de los folios emitidos para cada tipo de factura. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationSeriesCreateInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto de la `Serie` creada + /// + Task> CreateSeriesAsync(string id, OrganizationSeriesCreateInput data, CancellationToken cancellationToken = default); + + /// + /// Editar serie + /// + /// Edita el número de foliaje de la serie en ambientes Test y Live de la organización. + /// + /// + /// ID de la organización + /// Nombre de la serie + /// Datos de la solicitud. Admite OrganizationSeriesUpdateInput. + /// Permite cancelar la solicitud. + /// Objeto `Serie` editada + /// + Task> UpdateSeriesAsync(string id, string seriesName, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Editar serie + /// + /// Edita el número de foliaje de la serie en ambientes Test y Live de la organización. + /// + /// + /// ID de la organización + /// Nombre de la serie + /// Datos de la solicitud. Admite OrganizationSeriesUpdateInput. + /// Permite cancelar la solicitud. + /// Objeto `Serie` editada + /// + Task> UpdateSeriesAsync(string id, string seriesName, OrganizationSeriesUpdateInput data, CancellationToken cancellationToken = default); + + /// + /// Establecer serie predeterminada + /// + /// Asigna una serie predeterminada para el tipo de comprobante indicado. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationSeriesDefaultInput. + /// Permite cancelar la solicitud. + /// Serie predeterminada actualizada + /// + Task UpdateDefaultSeriesAsync(string organizationId, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Establecer serie predeterminada + /// + /// Asigna una serie predeterminada para el tipo de comprobante indicado. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationSeriesDefaultInput. + /// Permite cancelar la solicitud. + /// Serie predeterminada actualizada + /// + Task UpdateDefaultSeriesAsync(string organizationId, OrganizationSeriesDefaultInput data, CancellationToken cancellationToken = default); + + /// + /// Eliminar serie + /// + /// Elimina la serie previamente creada + /// + /// + /// ID de la organización + /// Nombre de la serie + /// Permite cancelar la solicitud. + /// Objeto `Serie` eliminado + /// + Task> DeleteSeriesAsync(string id, string seriesName, CancellationToken cancellationToken = default); + + /// + /// Detalle de organización + /// + /// Retorna el detalle de la organización actualmente autenticada. + /// + /// + /// Permite cancelar la solicitud. + /// Objeto `Organization` + /// + Task MeAsync(CancellationToken cancellationToken = default); + + /// + /// Editar config. autofactura + /// + /// Actualiza la configuración del portal de autofactura de la organización. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationSelfInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + Task UpdateSelfInvoiceSettingsAsync(string organizationId, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Editar config. autofactura + /// + /// Actualiza la configuración del portal de autofactura de la organización. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationSelfInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + Task UpdateSelfInvoiceSettingsAsync(string organizationId, OrganizationSelfInvoiceInput data, CancellationToken cancellationToken = default); + + /// + /// Listar usuarios con acceso a organización + /// + /// Regresa un arreglo con los usuarios que actualmente tienen acceso a la organización, incluyendo al propietario. Este endpoint no está paginado. + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Lista de accesos de usuarios dentro de la organización, incluyendo accesos implícitos como el del propietario + /// Task> ListTeamAccessAsync(string organizationId, CancellationToken cancellationToken = default); + + /// + /// Obtener acceso de usuario + /// + /// Regresa el detalle del acceso del usuario dentro de la organización usando su `access_id`, incluyendo accesos implícitos como el del propietario. + /// + /// ID de la organización + /// ID del acceso + /// Permite cancelar la solicitud. + /// Detalle del acceso del usuario dentro de la organización, incluyendo accesos implícitos como el del propietario + /// Task RetrieveTeamAccessAsync(string organizationId, string accessId, CancellationToken cancellationToken = default); + + /// + /// Reasignar rol a usuario + /// + /// ID de la organización + /// ID del acceso + /// role + /// Permite cancelar la solicitud. + /// Acceso del usuario actualizado con el nuevo rol + /// Task UpdateTeamAccessRoleAsync(string organizationId, string accessId, string role, CancellationToken cancellationToken = default); + + /// + /// Eliminar usuario con acceso + /// + /// ID de la organización + /// ID del acceso + /// Permite cancelar la solicitud. + /// Usuario removido de la organización + /// Task RemoveTeamAccessAsync(string organizationId, string accessId, CancellationToken cancellationToken = default); + + /// + /// Listar invitaciones enviadas + /// + /// Regresa invitaciones enviadas desde la organización. + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Lista de invitaciones enviadas y aún vigentes para la organización + /// Task> ListSentTeamInvitesAsync(string organizationId, CancellationToken cancellationToken = default); - Task InviteUserToTeamAsync(string organizationId, Dictionary data, CancellationToken cancellationToken = default); + + /// + /// Invitar usuario a organización + /// + /// Crea o actualiza una invitación de usuario. Por defecto, el acceso es de administrador con permisos completos; para limitarlo, crea un rol y envía su ID en `role`. + /// + /// Cada organización puede invitar a un usuario sin costo adicional. A partir del segundo usuario invitado, cada usuario adicional tendrá un costo mensual. Este cargo se aplica automáticamente cuando el usuario acepta la invitación. + /// Puedes consultar el precio vigente en nuestra [página de precios](https://www.facturapi.io/pricing). + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationInviteCreateInput. + /// Permite cancelar la solicitud. + /// Invitación creada o actualizada para el correo solicitado + /// + Task InviteUserToTeamAsync(string organizationId, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Invitar usuario a organización + /// + /// Crea o actualiza una invitación de usuario. Por defecto, el acceso es de administrador con permisos completos; para limitarlo, crea un rol y envía su ID en `role`. + /// + /// Cada organización puede invitar a un usuario sin costo adicional. A partir del segundo usuario invitado, cada usuario adicional tendrá un costo mensual. Este cargo se aplica automáticamente cuando el usuario acepta la invitación. + /// Puedes consultar el precio vigente en nuestra [página de precios](https://www.facturapi.io/pricing). + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationInviteCreateInput. + /// Permite cancelar la solicitud. + /// Invitación creada o actualizada para el correo solicitado + /// + Task InviteUserToTeamAsync(string organizationId, OrganizationInviteCreateInput data, CancellationToken cancellationToken = default); + + /// + /// Cancelar invitación enviada + /// + /// Elimina una invitación pendiente de la organización. + /// + /// ID de la organización + /// Clave pública de la invitación. + /// Permite cancelar la solicitud. + /// Invitación cancelada + /// Task CancelTeamInviteAsync(string organizationId, string inviteKey, CancellationToken cancellationToken = default); + + /// + /// Listar invitaciones recibidas + /// + /// Regresa las invitaciones recibidas para el usuario autenticado. + /// + /// Permite cancelar la solicitud. + /// Lista de invitaciones recibidas por el usuario autenticado + /// Task> ListReceivedTeamInvitesAsync(CancellationToken cancellationToken = default); - Task RespondTeamInviteAsync(string inviteKey, Dictionary data, CancellationToken cancellationToken = default); + + /// + /// Responder invitación + /// + /// Acepta o rechaza una invitación usando su `invite_key`. + /// + /// Clave pública de la invitación. + /// Datos de la solicitud. Admite OrganizationInviteRespondInput. + /// Permite cancelar la solicitud. + /// Invitación aceptada o rechazada exitosamente + /// + Task RespondTeamInviteAsync(string inviteKey, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Responder invitación + /// + /// Acepta o rechaza una invitación usando su `invite_key`. + /// + /// Clave pública de la invitación. + /// Datos de la solicitud. Admite OrganizationInviteRespondInput. + /// Permite cancelar la solicitud. + /// Invitación aceptada o rechazada exitosamente + /// + Task RespondTeamInviteAsync(string inviteKey, OrganizationInviteRespondInput data, CancellationToken cancellationToken = default); + + /// + /// Listar roles de organización + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Lista de roles + /// Task> ListTeamRolesAsync(string organizationId, CancellationToken cancellationToken = default); + + /// + /// Listar plantillas de roles + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Plantillas disponibles + /// Task> ListTeamRoleTemplatesAsync(string organizationId, CancellationToken cancellationToken = default); + + /// + /// Listar operaciones de permisos + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Lista de códigos de operación + /// Task> ListTeamRoleOperationsAsync(string organizationId, CancellationToken cancellationToken = default); + + /// + /// Obtener rol de organización + /// + /// ID de la organización + /// ID del rol + /// Permite cancelar la solicitud. + /// Detalle del rol + /// Task RetrieveTeamRoleAsync(string organizationId, string roleId, CancellationToken cancellationToken = default); - Task CreateTeamRoleAsync(string organizationId, Dictionary data, CancellationToken cancellationToken = default); - Task UpdateTeamRoleAsync(string organizationId, string roleId, Dictionary data, CancellationToken cancellationToken = default); + + /// + /// Crear rol de organización + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationPermissionRoleCreateInput. + /// Permite cancelar la solicitud. + /// Rol creado + /// + Task CreateTeamRoleAsync(string organizationId, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Crear rol de organización + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationPermissionRoleCreateInput. + /// Permite cancelar la solicitud. + /// Rol creado + /// + Task CreateTeamRoleAsync(string organizationId, OrganizationPermissionRoleCreateInput data, CancellationToken cancellationToken = default); + + /// + /// Actualizar rol de organización + /// + /// ID de la organización + /// ID del rol + /// Datos de la solicitud. Admite OrganizationPermissionRoleUpdateInput. + /// Permite cancelar la solicitud. + /// Rol actualizado + /// + Task UpdateTeamRoleAsync(string organizationId, string roleId, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Actualizar rol de organización + /// + /// ID de la organización + /// ID del rol + /// Datos de la solicitud. Admite OrganizationPermissionRoleUpdateInput. + /// Permite cancelar la solicitud. + /// Rol actualizado + /// + Task UpdateTeamRoleAsync(string organizationId, string roleId, OrganizationPermissionRoleUpdateInput data, CancellationToken cancellationToken = default); + + /// + /// Eliminar rol de organización + /// + /// ID de la organización + /// ID del rol + /// Permite cancelar la solicitud. + /// Rol eliminado + /// Task DeleteTeamRoleAsync(string organizationId, string roleId, CancellationToken cancellationToken = default); + + /// + /// Subir certificado FIEL + /// + /// Sube los archivos de la e.firma (FIEL) de la organización. + /// + /// La e.firma (FIEL) no es necesaria para crear CFDI. Para timbrar CFDI + /// solo necesitas cargar el Certificado de Sello Digital (CSD). La FIEL es + /// necesaria para utilizar la descarga masiva de CFDI. + /// + /// + /// ID de la organización. También puedes usar `me` con la Live Secret Key de la organización. + /// Format: binary Contenido binario del archivo con extensión `.cer` de la e.firma (FIEL). Usa un Stream; se dispone al finalizar la solicitud. + /// Format: binary Contenido binario del archivo con extensión `.key` de la e.firma (FIEL). Usa un Stream; se dispone al finalizar la solicitud. + /// Contraseña de la llave privada de la e.firma (FIEL). + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + Task UploadFielAsync(string id, Stream cerFile, Stream keyFile, string password, CancellationToken cancellationToken = default); + } } diff --git a/Wrappers/IProductWrapper.cs b/Wrappers/IProductWrapper.cs index 006a19a..a0c3ffa 100644 --- a/Wrappers/IProductWrapper.cs +++ b/Wrappers/IProductWrapper.cs @@ -1,15 +1,122 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public interface IProductWrapper + /// + /// Operaciones de Product para inyección de dependencias. + /// + public partial interface IProductWrapper { - Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default); - Task CreateAsync(Dictionary data, CancellationToken cancellationToken = default); + /// + /// Crear producto + /// + /// Registra un nuevo producto o servicio en tu catálogo de Facturapi. + /// + /// Puedes usar el ID del producto para crear facturas sin tener que enviar todos los datos del producto cada vez. + /// + /// Ten en cuenta que los productos que crees en ambiente _Test_ **no se + /// comparten** con el ambiente _Live_. + /// + /// + /// Datos de la solicitud. Admite ProductCreateInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Product` creado + /// + Task CreateAsync(JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Crear producto + /// + /// Registra un nuevo producto o servicio en tu catálogo de Facturapi. + /// + /// Puedes usar el ID del producto para crear facturas sin tener que enviar todos los datos del producto cada vez. + /// + /// Ten en cuenta que los productos que crees en ambiente _Test_ **no se + /// comparten** con el ambiente _Live_. + /// + /// + /// Datos de la solicitud. Admite ProductCreateInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Product` creado + /// + Task CreateAsync(ProductCreateInput data, CancellationToken cancellationToken = default); + + /// + /// Listar productos + /// + /// Regresa una lista paginada de todos los productos de una organización o realiza una búsqueda de acuerdo a parámetros + /// + /// Parámetros de consulta. Admite ProductListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> ListAsync(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Listar productos + /// + /// Regresa una lista paginada de todos los productos de una organización o realiza una búsqueda de acuerdo a parámetros + /// + /// Parámetros de consulta. Admite ProductListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> ListAsync(ProductListParams? query, CancellationToken cancellationToken = default); + + /// + /// Obtener producto por ID + /// + /// Regresa el objeto `Product` relacionado al `id` especificado. + /// + /// ID del objeto a obtener + /// Permite cancelar la solicitud. + /// Objeto `Product` + /// Task RetrieveAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Editar producto + /// + /// Actualiza la información de un producto existente, asignando los valores de los parámetros enviados. Los parámetros que no se envíen en la petición no se modificarán. + /// + /// ID del objeto a editar + /// Datos de la solicitud. Admite ProductUpdateInput. + /// Permite cancelar la solicitud. + /// Objeto `Product` editado correctamente + /// + Task UpdateAsync(string id, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Editar producto + /// + /// Actualiza la información de un producto existente, asignando los valores de los parámetros enviados. Los parámetros que no se envíen en la petición no se modificarán. + /// + /// ID del objeto a editar + /// Datos de la solicitud. Admite ProductUpdateInput. + /// Permite cancelar la solicitud. + /// Objeto `Product` editado correctamente + /// + Task UpdateAsync(string id, ProductUpdateInput data, CancellationToken cancellationToken = default); + + /// + /// Eliminar producto + /// + /// Elimina el producto de tu organización. Las facturas asociadas al producto **no** se eliminarán. + /// + /// ID del objeto a eliminar + /// Permite cancelar la solicitud. + /// Objeto `Product` eliminado correctamente + /// Task DeleteAsync(string id, CancellationToken cancellationToken = default); - Task UpdateAsync(string id, Dictionary data, CancellationToken cancellationToken = default); + } } diff --git a/Wrappers/IReceiptWrapper.cs b/Wrappers/IReceiptWrapper.cs index 085b480..e2f2f7a 100644 --- a/Wrappers/IReceiptWrapper.cs +++ b/Wrappers/IReceiptWrapper.cs @@ -1,21 +1,396 @@ -using System.Collections.Generic; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; using System.IO; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public interface IReceiptWrapper + /// + /// Operaciones de Receipt para inyección de dependencias. + /// + public partial interface IReceiptWrapper { - Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default); - Task CreateAsync(Dictionary data, CancellationToken cancellationToken = default); + /// + /// Crear recibo + /// + /// Crea un nuevo Recibo, el cual funge como nota de venta. + /// + /// Todos los recibos generan una URL de autofactura que cliente puede + /// visitar para llenar sus datos fiscales en un micrositio con el branding + /// de la organización. + /// + /// + /// Datos de la solicitud. Admite ReceiptInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Receipt` creado + /// + Task CreateAsync(JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Crear recibo + /// + /// Crea un nuevo Recibo, el cual funge como nota de venta. + /// + /// Todos los recibos generan una URL de autofactura que cliente puede + /// visitar para llenar sus datos fiscales en un micrositio con el branding + /// de la organización. + /// + /// + /// Datos de la solicitud. Admite ReceiptInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Receipt` creado + /// + Task CreateAsync(ReceiptInput data, CancellationToken cancellationToken = default); + + /// + /// Listar recibos + /// + /// Regresa una lista paginada de todos los recibos de una organización o realiza una búsqueda de acuerdo a parámetros + /// + /// Parámetros de consulta. Admite ReceiptListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> ListAsync(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Listar recibos + /// + /// Regresa una lista paginada de todos los recibos de una organización o realiza una búsqueda de acuerdo a parámetros + /// + /// Parámetros de consulta. Admite ReceiptListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> ListAsync(ReceiptListParams? query, CancellationToken cancellationToken = default); + + /// + /// Obtener recibo por ID + /// + /// Regresa el objeto 'Receipt' relacionado al `id` especificado. + /// + /// ID del objeto a obtener + /// Permite cancelar la solicitud. + /// Objeto `Receipt` + /// Task RetrieveAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Facturar recibo + /// + /// Crea una factura a partir de un recibo. + /// + /// Sólo pueden facturarse recibos abiertos (`status = "open"`) + /// + /// Si envías `customer`, ese cliente se usará como receptor de la factura y + /// sobrescribirá el cliente asignado al recibo. Si omites `customer`, el + /// recibo debe tener un cliente asignado previamente. + /// + /// Una vez facturado, el `status` del recibo cambiará a `"invoiced_to_customer"`. + /// + /// + /// ID del recibo a facturar + /// Datos de la solicitud. Admite InvoiceReceiptInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado + /// + Task InvoiceAsync(string id, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Facturar recibo + /// + /// Crea una factura a partir de un recibo. + /// + /// Sólo pueden facturarse recibos abiertos (`status = "open"`) + /// + /// Si envías `customer`, ese cliente se usará como receptor de la factura y + /// sobrescribirá el cliente asignado al recibo. Si omites `customer`, el + /// recibo debe tener un cliente asignado previamente. + /// + /// Una vez facturado, el `status` del recibo cambiará a `"invoiced_to_customer"`. + /// + /// + /// ID del recibo a facturar + /// Datos de la solicitud. Admite InvoiceReceiptInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado + /// + Task InvoiceAsync(string id, InvoiceReceiptInput data, CancellationToken cancellationToken = default); + + /// + /// Crear factura global + /// + /// Crea una factura global que incluirá todos los recibos con `status = “open”` de un cierto periodo. + /// + /// La factura global se emite al cliente genérico `PUBLICO EN GENERAL`. + /// Los recibos incluidos quedan asociados a ese cliente y su `status` + /// cambia a `"invoiced_globally"`. + /// + /// Una factura global puede incluir hasta 5,000 recibos abiertos. Si el periodo + /// contiene más, puedes enviar `limit_to_max_receipts: true` y repetir la solicitud + /// con el mismo periodo hasta recibir `null`. + /// + /// + /// Datos de la solicitud. Admite GlobalInvoiceInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado, o `null` si no hay recibos abiertos en el periodo + /// + Task CreateGlobalInvoiceAsync(JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Crear factura global + /// + /// Crea una factura global que incluirá todos los recibos con `status = “open”` de un cierto periodo. + /// + /// La factura global se emite al cliente genérico `PUBLICO EN GENERAL`. + /// Los recibos incluidos quedan asociados a ese cliente y su `status` + /// cambia a `"invoiced_globally"`. + /// + /// Una factura global puede incluir hasta 5,000 recibos abiertos. Si el periodo + /// contiene más, puedes enviar `limit_to_max_receipts: true` y repetir la solicitud + /// con el mismo periodo hasta recibir `null`. + /// + /// + /// Datos de la solicitud. Admite GlobalInvoiceInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado, o `null` si no hay recibos abiertos en el periodo + /// + Task CreateGlobalInvoiceAsync(GlobalInvoiceInput data, CancellationToken cancellationToken = default); + + /// + /// Facturar múltiples recibos + /// + /// Crea una sola factura a partir de múltiples recibos seleccionados por su `key`. + /// + /// Si envías `customer`, ese cliente se usará como receptor de la factura y + /// sobrescribirá el cliente asignado a los recibos incluidos. Si omites + /// `customer`, todos los recibos deben tener asignado el mismo cliente. + /// También se validará el campo `address` de los recibos incluidos. + /// + /// Si `dry_run` es `true`, no crea la factura y regresa un resumen de vista previa. + /// El `dry_run` valida las mismas reglas que la creación real, pero no persiste cambios. + /// + /// + /// Datos de la solicitud. Admite ToInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto `Invoice` creado u objeto resumen cuando `dry_run=true` + /// + Task ToInvoiceAsync(JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Facturar múltiples recibos + /// + /// Crea una sola factura a partir de múltiples recibos seleccionados por su `key`. + /// + /// Si envías `customer`, ese cliente se usará como receptor de la factura y + /// sobrescribirá el cliente asignado a los recibos incluidos. Si omites + /// `customer`, todos los recibos deben tener asignado el mismo cliente. + /// También se validará el campo `address` de los recibos incluidos. + /// + /// Si `dry_run` es `true`, no crea la factura y regresa un resumen de vista previa. + /// El `dry_run` valida las mismas reglas que la creación real, pero no persiste cambios. + /// + /// + /// Datos de la solicitud. Admite ToInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto `Invoice` creado u objeto resumen cuando `dry_run=true` + /// + Task ToInvoiceAsync(ToInvoiceInput data, CancellationToken cancellationToken = default); + + /// + /// Vista previa PDF de factura múltiple + /// + /// Genera una vista previa en PDF para una factura construida a partir de múltiples recibos seleccionados por `key`. + /// + /// La vista previa valida las mismas reglas de cliente que la creación real: + /// si omites `customer`, todos los recibos deben tener asignado el mismo cliente. + /// + /// + /// Datos de la solicitud. Admite ToInvoicePreviewInput. + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// + Task PreviewToInvoicePdfAsync(JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Vista previa PDF de factura múltiple + /// + /// Genera una vista previa en PDF para una factura construida a partir de múltiples recibos seleccionados por `key`. + /// + /// La vista previa valida las mismas reglas de cliente que la creación real: + /// si omites `customer`, todos los recibos deben tener asignado el mismo cliente. + /// + /// + /// Datos de la solicitud. Admite ToInvoicePreviewInput. + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// + Task PreviewToInvoicePdfAsync(ToInvoicePreviewInput data, CancellationToken cancellationToken = default); + + /// + /// Obtener URL del preview de factura de recibos + /// + /// Devuelve un objeto con los metadatos del archivo y una URL temporal para el preview PDF de una factura construida con los recibos seleccionados. + /// + /// Datos de la solicitud. Admite ToInvoicePreviewInput. + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + Task PreviewToInvoicePdfUrlAsync(JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Obtener URL del preview de factura de recibos + /// + /// Devuelve un objeto con los metadatos del archivo y una URL temporal para el preview PDF de una factura construida con los recibos seleccionados. + /// + /// Datos de la solicitud. Admite ToInvoicePreviewInput. + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + Task PreviewToInvoicePdfUrlAsync(ToInvoicePreviewInput data, CancellationToken cancellationToken = default); + + /// + /// Cancelar recibo + /// + /// Marca un recibo como cancelado, cambiando su propiedad `status` a `"canceled"`. + /// + /// Una vez cancelado, el recibo no podrá ser facturado. + /// + /// + /// ID del recibo a cancelar + /// Permite cancelar la solicitud. + /// Objeto 'Receipt' cancelado exitosamente + /// Task CancelAsync(string id, CancellationToken cancellationToken = default); - Task InvoiceAsync(string id, Dictionary data, CancellationToken cancellationToken = default); - Task CreateGlobalInvoiceAsync(Dictionary data, CancellationToken cancellationToken = default); - Task ToInvoiceAsync(Dictionary data, CancellationToken cancellationToken = default); - Task PreviewToInvoicePdfAsync(Dictionary data, CancellationToken cancellationToken = default); - Task SendByEmailAsync(string id, Dictionary data = null, CancellationToken cancellationToken = default); + + /// + /// Enviar recibo por correo electrónico + /// + /// Envía un correo electrónico a la dirección de tu cliente. + /// + /// El correo enviado estará personalizado con el logotipo y los colores de la organización que lo creó, + /// e incluirá un botón para facturar el recibo, así con el recibo en formato PDF adjunto al mensaje. + /// + /// + /// ID del objeto a obtener + /// Datos de la solicitud. Admite SendReceiptByEmailInput. + /// Permite cancelar la solicitud. + /// Objeto genérico de respuesta + /// + Task SendByEmailAsync(string id, JsonObject? data = null, CancellationToken cancellationToken = default); + + /// + /// Enviar recibo por correo electrónico + /// + /// Envía un correo electrónico a la dirección de tu cliente. + /// + /// El correo enviado estará personalizado con el logotipo y los colores de la organización que lo creó, + /// e incluirá un botón para facturar el recibo, así con el recibo en formato PDF adjunto al mensaje. + /// + /// + /// ID del objeto a obtener + /// Datos de la solicitud. Admite SendReceiptByEmailInput. + /// Permite cancelar la solicitud. + /// Objeto genérico de respuesta + /// + Task SendByEmailAsync(string id, SendReceiptByEmailInput data, CancellationToken cancellationToken = default); + + /// + /// Descargar PDF + /// + /// Descarga el recibo digital en formato PDF. + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// Task DownloadPdfAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Obtener enlace de descarga + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar el recibo digital en PDF, sin que el archivo pase por tu servidor. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + Task DownloadPdfUrlAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Asignar o reasignar cliente a recibo + /// + /// Asigna o reasigna un cliente existente (por ID) a un recibo, o crea uno nuevo enviando el objeto del cliente. + /// + /// + /// ID del recibo a actualizar + /// Datos de la solicitud. Admite ReceiptAssignCustomerInput. + /// Permite cancelar la solicitud. + /// Objeto `Receipt` actualizado + /// + Task UpdateCustomerAsync(string id, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Asignar o reasignar cliente a recibo + /// + /// Asigna o reasigna un cliente existente (por ID) a un recibo, o crea uno nuevo enviando el objeto del cliente. + /// + /// + /// ID del recibo a actualizar + /// Datos de la solicitud. Admite ReceiptAssignCustomerInput. + /// Permite cancelar la solicitud. + /// Objeto `Receipt` actualizado + /// + Task UpdateCustomerAsync(string id, ReceiptAssignCustomerInput data, CancellationToken cancellationToken = default); + + /// + /// Facturar múltiples recibos + /// + /// Crea una sola factura a partir de múltiples recibos seleccionados por su `key`. + /// + /// Si envías `customer`, ese cliente se usará como receptor de la factura y + /// sobrescribirá el cliente asignado a los recibos incluidos. Si omites + /// `customer`, todos los recibos deben tener asignado el mismo cliente. + /// También se validará el campo `address` de los recibos incluidos. + /// + /// Si `dry_run` es `true`, no crea la factura y regresa un resumen de vista previa. + /// El `dry_run` valida las mismas reglas que la creación real, pero no persiste cambios. + /// + /// + /// Datos de la solicitud. Admite ToInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto `Invoice` creado u objeto resumen cuando `dry_run=true` + /// + Task SummarizeToInvoiceAsync(JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Facturar múltiples recibos + /// + /// Crea una sola factura a partir de múltiples recibos seleccionados por su `key`. + /// + /// Si envías `customer`, ese cliente se usará como receptor de la factura y + /// sobrescribirá el cliente asignado a los recibos incluidos. Si omites + /// `customer`, todos los recibos deben tener asignado el mismo cliente. + /// También se validará el campo `address` de los recibos incluidos. + /// + /// Si `dry_run` es `true`, no crea la factura y regresa un resumen de vista previa. + /// El `dry_run` valida las mismas reglas que la creación real, pero no persiste cambios. + /// + /// + /// Datos de la solicitud. Admite ToInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto `Invoice` creado u objeto resumen cuando `dry_run=true` + /// + Task SummarizeToInvoiceAsync(ToInvoiceInput data, CancellationToken cancellationToken = default); + } } diff --git a/Wrappers/IRetentionWrapper.cs b/Wrappers/IRetentionWrapper.cs index 31d05c7..1278683 100644 --- a/Wrappers/IRetentionWrapper.cs +++ b/Wrappers/IRetentionWrapper.cs @@ -1,22 +1,289 @@ -using System.Collections.Generic; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; using System.IO; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public interface IRetentionWrapper + /// + /// Operaciones de Retention para inyección de dependencias. + /// + public partial interface IRetentionWrapper { - Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default); - Task CreateAsync(Dictionary data, CancellationToken cancellationToken = default); - Task RetrieveAsync(string id, CancellationToken cancellationToken = default); - Task CancelAsync(string id, Dictionary query = null, CancellationToken cancellationToken = default); - Task SendByEmailAsync(string id, Dictionary data = null, CancellationToken cancellationToken = default); - Task UpdateDraftAsync(string id, Dictionary data, CancellationToken cancellationToken = default); - Task StampDraftAsync(string id, Dictionary options = null, CancellationToken cancellationToken = default); - Task CopyToDraftAsync(string id, CancellationToken cancellationToken = default); - Task DownloadZipAsync(string id, CancellationToken cancellationToken = default); + /// + /// Crear retención + /// + /// Crea una nueva Retención. Si el comprobante es creado en ambiente Live, ésta será **timbrado y enviado al SAT**. + /// + /// Para crear una retención en borrador, envía `status: "draft"`. En ese caso, + /// la retención se guardará sin timbrarse, no se enviará al PAC y podrá estar + /// incompleta. Facturapi asignará `is_ready_to_stamp: true` únicamente cuando + /// el borrador tenga todos los datos requeridos para timbrarse. + /// + /// + /// Datos de la solicitud. Admite RetentionInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Retention` creado + /// + Task CreateAsync(JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Crear retención + /// + /// Crea una nueva Retención. Si el comprobante es creado en ambiente Live, ésta será **timbrado y enviado al SAT**. + /// + /// Para crear una retención en borrador, envía `status: "draft"`. En ese caso, + /// la retención se guardará sin timbrarse, no se enviará al PAC y podrá estar + /// incompleta. Facturapi asignará `is_ready_to_stamp: true` únicamente cuando + /// el borrador tenga todos los datos requeridos para timbrarse. + /// + /// + /// Datos de la solicitud. Admite RetentionInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Retention` creado + /// + Task CreateAsync(RetentionInput data, CancellationToken cancellationToken = default); + + /// + /// Listar retenciones + /// + /// Regresa una lista paginada de todas las retenciones de una organización o realiza una búsqueda de acuerdo a parámetros + /// + /// Parámetros de consulta. Admite RetentionListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> ListAsync(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Listar retenciones + /// + /// Regresa una lista paginada de todas las retenciones de una organización o realiza una búsqueda de acuerdo a parámetros + /// + /// Parámetros de consulta. Admite RetentionListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> ListAsync(RetentionListParams? query, CancellationToken cancellationToken = default); + + /// + /// Obtener retención por ID + /// + /// Regresa el objeto 'Retention' relacionado al `id` especificado. + /// + /// ID del objeto a obtener + /// Permite cancelar la solicitud. + /// Objeto `Retention` + /// + Task RetrieveAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Cancelar retención + /// + /// Realiza una solicitud de cancelación de retención ante el SAT. + /// + /// A diferencia de las facturas comunes, la cancelación de la retención es inmediata y no requiere autorización de parte del receptor. + /// + /// Si el status de la retención es `draft`, este método la eliminará de la + /// base de datos sin llamar al SAT/PAC y sin requerir parámetros de cancelación. + /// + /// + /// ID de la retención a cancelar + /// Parámetros de consulta. Admite CancellationQueryInput. + /// Permite cancelar la solicitud. + /// Objeto `Retention` cancelado exitosamente + /// + Task CancelAsync(string id, JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Cancelar retención + /// + /// Realiza una solicitud de cancelación de retención ante el SAT. + /// + /// A diferencia de las facturas comunes, la cancelación de la retención es inmediata y no requiere autorización de parte del receptor. + /// + /// Si el status de la retención es `draft`, este método la eliminará de la + /// base de datos sin llamar al SAT/PAC y sin requerir parámetros de cancelación. + /// + /// + /// ID de la retención a cancelar + /// Parámetros de consulta. Admite CancellationQueryInput. + /// Permite cancelar la solicitud. + /// Objeto `Retention` cancelado exitosamente + /// + Task CancelAsync(string id, CancellationQueryInput? query, CancellationToken cancellationToken = default); + + /// + /// Editar borrador de retención + /// + /// Actualiza la información de una retención con status `draft`, asignando + /// los valores de los parámetros enviados. Los parámetros que no se envíen + /// en la petición no se modificarán. + /// + /// Facturapi recalculará automáticamente `is_ready_to_stamp` después de cada + /// edición. Si la retención ya no está en status `draft`, la llamada regresará + /// un error. + /// + /// + /// ID de la retención a editar + /// Datos de la solicitud. Admite RetentionUpdateInput. + /// Permite cancelar la solicitud. + /// Objeto `Retention` editado correctamente + /// + Task UpdateDraftAsync(string id, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Editar borrador de retención + /// + /// Actualiza la información de una retención con status `draft`, asignando + /// los valores de los parámetros enviados. Los parámetros que no se envíen + /// en la petición no se modificarán. + /// + /// Facturapi recalculará automáticamente `is_ready_to_stamp` después de cada + /// edición. Si la retención ya no está en status `draft`, la llamada regresará + /// un error. + /// + /// + /// ID de la retención a editar + /// Datos de la solicitud. Admite RetentionUpdateInput. + /// Permite cancelar la solicitud. + /// Objeto `Retention` editado correctamente + /// + Task UpdateDraftAsync(string id, RetentionUpdateInput data, CancellationToken cancellationToken = default); + + /// + /// Timbrar borrador de retención + /// + /// Timbra una retención con status `draft` y la envía al SAT para su validación. + /// + /// Facturapi validará el borrador como una retención completa antes de timbrarlo. + /// Si el borrador está incompleto o no es válido, la llamada regresará un error. + /// + /// + /// ID de la retención a timbrar + /// options + /// Permite cancelar la solicitud. + /// Objeto `Retention` timbrado correctamente + /// + Task StampDraftAsync(string id, JsonObject? options = null, CancellationToken cancellationToken = default); + + /// + /// Copiar a borrador + /// + /// Crea una copia en borrador de la retención especificada. La copia no conserva + /// campos propios del timbrado, cancelación, idempotencia o identidad externa. + /// + /// + /// ID de la retención a copiar + /// Permite cancelar la solicitud. + /// Nuevo objeto `Retention` con status `draft`. + /// + Task CopyToDraftAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Enviar retención por correo electrónico + /// + /// Envía un correo electrónico a la dirección de tu cliente, con los archivos XML y PDF adjuntos al mensaje. + /// + /// ID del objeto a obtener + /// Datos de la solicitud. Admite SendRetentionByEmailInput. + /// Permite cancelar la solicitud. + /// Objeto genérico de respuesta + /// + Task SendByEmailAsync(string id, JsonObject? data = null, CancellationToken cancellationToken = default); + + /// + /// Enviar retención por correo electrónico + /// + /// Envía un correo electrónico a la dirección de tu cliente, con los archivos XML y PDF adjuntos al mensaje. + /// + /// ID del objeto a obtener + /// Datos de la solicitud. Admite SendRetentionByEmailInput. + /// Permite cancelar la solicitud. + /// Objeto genérico de respuesta + /// + Task SendByEmailAsync(string id, SendRetentionByEmailInput data, CancellationToken cancellationToken = default); + + /// + /// Descargar retención + /// + /// Descarga una retención en PDF, XML o ambos en un archivo comprimido ZIP. + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// Task DownloadPdfAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Descargar retención + /// + /// Descarga una retención en PDF, XML o ambos en un archivo comprimido ZIP. + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// Task DownloadXmlAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Descargar retención + /// + /// Descarga una retención en PDF, XML o ambos en un archivo comprimido ZIP. + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// + Task DownloadZipAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Obtener enlace de descarga + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar la retención en PDF, XML o ambos en un archivo comprimido ZIP, sin que el archivo pase por tu servidor. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + Task DownloadPdfUrlAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Obtener enlace de descarga + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar la retención en PDF, XML o ambos en un archivo comprimido ZIP, sin que el archivo pase por tu servidor. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + Task DownloadXmlUrlAsync(string id, CancellationToken cancellationToken = default); + + /// + /// Obtener enlace de descarga + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar la retención en PDF, XML o ambos en un archivo comprimido ZIP, sin que el archivo pase por tu servidor. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + Task DownloadZipUrlAsync(string id, CancellationToken cancellationToken = default); + } } diff --git a/Wrappers/IToolWrapper.cs b/Wrappers/IToolWrapper.cs index 5ada938..2eb1a40 100644 --- a/Wrappers/IToolWrapper.cs +++ b/Wrappers/IToolWrapper.cs @@ -1,11 +1,54 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public interface IToolWrapper + /// + /// Operaciones de Tool para inyección de dependencias. + /// + public partial interface IToolWrapper { + /// + /// Validar RFC + /// + /// Consulta el estado de un RFC en la lista de **EFOS** (Empresas que + /// Facturan Operaciones Simuladas). Al aparecer en esta lista, el RFC es o + /// fue sospechoso de incurrir en simulación de operaciones fiscales + /// (empresas factureras). + /// + /// La respuesta (detallada más abajo) incluye los resultados de esta + /// validación. Se incluye la propiedad + /// booleana `is_valid`, que Facturapi resuelve interpretando la respuesta. + /// Un valor de `true` para esta propiedad indica que el RFC no tiene asuntos + /// por resolver y está libre de problemas; y lo contrario para `false`. + /// + /// Adicionalmente puedes consultar la propiedad data para ver los valores + /// en bruto de la consulta al SAT. + /// + /// + /// taxId + /// Permite cancelar la solicitud. + /// Resultado de la validación + /// Task ValidateTaxIdAsync(string taxId, CancellationToken cancellationToken = default); + + /// + /// Health check (Pulso) + /// + /// Comprueba que la API está disponible. Este endpoint requiere una llave secreta de API. + /// + /// Permite cancelar la solicitud. + /// La API está operando con normalidad. + /// Task HealthCheckAsync(CancellationToken cancellationToken = default); + } } diff --git a/Wrappers/IWebhookWrapper.cs b/Wrappers/IWebhookWrapper.cs index 83db0c0..e940274 100644 --- a/Wrappers/IWebhookWrapper.cs +++ b/Wrappers/IWebhookWrapper.cs @@ -1,16 +1,144 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public interface IWebhookWrapper + /// + /// Operaciones de Webhook para inyección de dependencias. + /// + public partial interface IWebhookWrapper { - Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default); - Task CreateAsync(Dictionary data, CancellationToken cancellationToken = default); + /// + /// Crear Webhook + /// + /// Registra un nuevo webhook en tu organización de Facturapi. + /// Utiliza esta llamada para recibir notificaciones de eventos asíncronos a la API. + /// Los webhooks de ambiente test y ambiente live son independientes. + /// + /// + /// Datos de la solicitud. Admite WebhookCreateInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Webhook` creado + /// + Task CreateAsync(JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Crear Webhook + /// + /// Registra un nuevo webhook en tu organización de Facturapi. + /// Utiliza esta llamada para recibir notificaciones de eventos asíncronos a la API. + /// Los webhooks de ambiente test y ambiente live son independientes. + /// + /// + /// Datos de la solicitud. Admite WebhookCreateInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Webhook` creado + /// + Task CreateAsync(WebhookCreateInput data, CancellationToken cancellationToken = default); + + /// + /// Listar webhooks + /// + /// Retorna una lista de webhooks creados previamente para la organización. + /// + /// Parámetros de consulta. Admite WebhookListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> ListAsync(JsonObject? query = null, CancellationToken cancellationToken = default); + + /// + /// Listar webhooks + /// + /// Retorna una lista de webhooks creados previamente para la organización. + /// + /// Parámetros de consulta. Admite WebhookListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + Task> ListAsync(WebhookListParams? query, CancellationToken cancellationToken = default); + + /// + /// Obtener webhook por ID + /// + /// Regresa el objeto "Webhook" relacionado al `id` especificado. + /// + /// ID del objeto a obtener + /// Permite cancelar la solicitud. + /// Objeto `Webhook` + /// Task RetrieveAsync(string id, CancellationToken cancellationToken = default); - Task UpdateAsync(string id, Dictionary data, CancellationToken cancellationToken = default); + + /// + /// Editar webhook + /// + /// Actualiza la información de un Webhook existente con los parámetros que envíes en la petición. + /// + /// ID del objeto a editar + /// Datos de la solicitud. Admite WebhookUpdateInput. + /// Permite cancelar la solicitud. + /// Objeto `Webhook` editado correctamente + /// + Task UpdateAsync(string id, JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Editar webhook + /// + /// Actualiza la información de un Webhook existente con los parámetros que envíes en la petición. + /// + /// ID del objeto a editar + /// Datos de la solicitud. Admite WebhookUpdateInput. + /// Permite cancelar la solicitud. + /// Objeto `Webhook` editado correctamente + /// + Task UpdateAsync(string id, WebhookUpdateInput data, CancellationToken cancellationToken = default); + + /// + /// Eliminar Webhook + /// + /// Elimina el webhook perteneciente a la organización. + /// + /// ID del objeto a eliminar + /// Permite cancelar la solicitud. + /// Objeto `Webhook` eliminado correctamente + /// Task DeleteAsync(string id, CancellationToken cancellationToken = default); - Task ValidateSignatureAsync(Dictionary data, CancellationToken cancellationToken = default); + + /// + /// Validar evento de webhook + /// + /// Valida la firma de un evento recibido mediante un Webhook. + /// Utiliza esta operación para verificar la autenticidad e integridad de + /// un evento recibido, comparando la firma recibida con la generada por Facturapi. + /// + /// + /// Datos de la solicitud. Admite ValidateWebhookSignatureInput. + /// Permite cancelar la solicitud. + /// Payload original con firma válida + /// + Task>> ValidateSignatureRemotelyAsync(JsonObject data, CancellationToken cancellationToken = default); + + /// + /// Validar evento de webhook + /// + /// Valida la firma de un evento recibido mediante un Webhook. + /// Utiliza esta operación para verificar la autenticidad e integridad de + /// un evento recibido, comparando la firma recibida con la generada por Facturapi. + /// + /// + /// Datos de la solicitud. Admite ValidateWebhookSignatureInput. + /// Permite cancelar la solicitud. + /// Payload original con firma válida + /// + Task>> ValidateSignatureRemotelyAsync(ValidateWebhookSignatureInput data, CancellationToken cancellationToken = default); + } } diff --git a/Wrappers/InvoiceWrapper.cs b/Wrappers/InvoiceWrapper.cs index 269ad43..3fbdef3 100644 --- a/Wrappers/InvoiceWrapper.cs +++ b/Wrappers/InvoiceWrapper.cs @@ -1,247 +1,877 @@ +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable using System; -using Newtonsoft.Json; -using System.Collections.Generic; using System.IO; +using System.Collections.Generic; using System.Net.Http; -using System.Text; -using System.Threading.Tasks; using System.Threading; +using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public class InvoiceWrapper : BaseWrapper, IInvoiceWrapper + /// + /// Operaciones de Invoice. + /// + public partial class InvoiceWrapper : BaseWrapper, IInvoiceWrapper { - internal InvoiceWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) + internal InvoiceWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) {} + + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Datos de la solicitud. Admite InvoiceCreateInput. + /// Parámetros de consulta. Admite InvoiceCreateParams. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + public Task CreateAsync(JsonObject data, JsonObject? options = null, CancellationToken cancellationToken = default) { + return RequestAsync(HttpMethod.Post, $"invoices", options, data, true, cancellationToken); } - public async Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Datos de la solicitud. Admite InvoiceCreateInput. + /// Parámetros de consulta. Admite InvoiceCreateParams. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + public Task CreateAsync(InvoiceCreateInput data, InvoiceCreateParams? options = null, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.ListInvoices(query), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + return RequestAsync(HttpMethod.Post, $"invoices", options, data, true, cancellationToken); + } - var searchResult = JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - return searchResult; - } + /// + /// Listar facturas + /// + /// Regresa una lista paginada de todas las facturas de una organización o realiza una búsqueda de acuerdo a parámetros. + /// + /// Por defecto, los resultados se ordenan por fecha de emisión, usando el campo `date` de forma descendente. + /// + /// + /// Parámetros de consulta. Admite InvoiceListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> ListAsync(JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"invoices", query, null, false, cancellationToken); } - public async Task CreateAsync(Dictionary data, Dictionary options = null, CancellationToken cancellationToken = default) + /// + /// Listar facturas + /// + /// Regresa una lista paginada de todas las facturas de una organización o realiza una búsqueda de acuerdo a parámetros. + /// + /// Por defecto, los resultados se ordenan por fecha de emisión, usando el campo `date` de forma descendente. + /// + /// + /// Parámetros de consulta. Admite InvoiceListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> ListAsync(InvoiceListParams? query, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.CreateInvoice(options), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var invoice = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return invoice; - } + return RequestAsync>(HttpMethod.Get, $"invoices", query, null, false, cancellationToken); } - public async Task RetrieveAsync(string id, CancellationToken cancellationToken = default) + /// + /// Obtener factura por ID + /// + /// Regresa el objeto 'Invoice' relacionado al `id` especificado. + /// + /// ID del objeto a obtener + /// Permite cancelar la solicitud. + /// Objeto `Invoice` + /// + public Task RetrieveAsync(string id, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.RetrieveInvoice(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var invoice = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return invoice; - } + return RequestAsync(HttpMethod.Get, $"invoices/{Uri.EscapeDataString(id)}", null, null, false, cancellationToken); } - public async Task GetPaymentSummaryAsync(string id, double amount, CancellationToken cancellationToken = default) + /// + /// Resumen de pago + /// + /// Devuelve la información necesaria para agregar esta factura como documento relacionado en un + /// Comprobante de Pago (complemento de pago): el número de parcialidad que corresponde según el + /// historial de pagos, el saldo anterior (`last_balance`) y el desglose de impuestos de la factura + /// prorrateado al monto que se pretende pagar. + /// + /// El valor de retorno está listo para usarse como elemento de `related_documents` al + /// [crear una factura de tipo Pago](https://docs.facturapi.io/api/#tag/invoice/operation/createInvoice). + /// + /// El parámetro `amount` debe expresarse en la divisa de la factura y no puede exceder el saldo + /// pendiente (`amount_due`). Cuando el pago se recibe en otra divisa, convierte el monto antes de + /// llamar este método. + /// + /// + /// ID de la factura de ingreso (método de pago PPD) que se desea pagar + /// amount + /// Permite cancelar la solicitud. + /// Resumen del documento relacionado + /// + public Task GetPaymentSummaryAsync(string id, double amount, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.RetrieveInvoicePaymentSummary(id, amount), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var summary = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return summary; - } + return RequestAsync(HttpMethod.Get, $"invoices/{Uri.EscapeDataString(id)}/payment-summary", new Dictionary { ["amount"] = amount }, null, false, cancellationToken); } - public async Task CancelAsync(string id, Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Cancelar factura + /// + /// Realiza una solicitud de cancelación de factura ante el SAT, soportando el esquema de cancelación 2022. + /// + /// Al usar este método pueden ocurrir 3 posibles resultados: + /// + /// - Que la llamada regrese un error con la explicación de por qué no se pudo cancelar. + /// - Que la llamada sea satisfactoria y regrese un objeto `invoice` con la propiedad `status: "canceled"`. + /// - Que la llamada sea satisfactoria, pero que la cancelación requiera de confirmación de parte de tu cliente, en cuyo caso se obtendrá como respuesta el objeto `invoice` con las propiedades `status: "valid"` y `cancellation_status: "pending"`. + /// + /// En el tercer escenario, el valor de `cancellation_status` será actualizado automáticamente por Facturapi cuando tu cliente acepte, rechace o deje expirar la solicitud, de tal manera que al consultar una factura (usando [Obtener Factura](https://docs.facturapi.io/api/#tag/invoice/operation/getInvoice)), la propiedad `cancellation_status` reflejará el estado más reciente de la solicitud. + /// + /// Consulta los valores posibles de `cancellation_status` más abajo. + /// + /// Después de la cancelación la factura ya no tendrá validez, el objeto cambiará su `status` a `"canceled"` y seguirá estando disponible para futuras consultas. + /// + /// Si el status de la factura es `draft`, este método la eliminará de la base de datos. + /// + /// Si el status de la factura es `canceled`, este método regresará un error. + /// + /// + /// ID de la factura a cancelar + /// Parámetros de consulta. Admite CancellationQueryInput. + /// Permite cancelar la solicitud. + /// Solicitud de cancelación exitosa + /// + public Task CancelAsync(string id, JsonObject? query = null, CancellationToken cancellationToken = default) { - using (var response = await client.DeleteAsync(Router.CancelInvoice(id, query), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var invoice = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return invoice; - } + return RequestAsync(HttpMethod.Delete, $"invoices/{Uri.EscapeDataString(id)}", query, null, false, cancellationToken); } - public async Task SendByEmailAsync(string id, Dictionary data = null, CancellationToken cancellationToken = default) + /// + /// Cancelar factura + /// + /// Realiza una solicitud de cancelación de factura ante el SAT, soportando el esquema de cancelación 2022. + /// + /// Al usar este método pueden ocurrir 3 posibles resultados: + /// + /// - Que la llamada regrese un error con la explicación de por qué no se pudo cancelar. + /// - Que la llamada sea satisfactoria y regrese un objeto `invoice` con la propiedad `status: "canceled"`. + /// - Que la llamada sea satisfactoria, pero que la cancelación requiera de confirmación de parte de tu cliente, en cuyo caso se obtendrá como respuesta el objeto `invoice` con las propiedades `status: "valid"` y `cancellation_status: "pending"`. + /// + /// En el tercer escenario, el valor de `cancellation_status` será actualizado automáticamente por Facturapi cuando tu cliente acepte, rechace o deje expirar la solicitud, de tal manera que al consultar una factura (usando [Obtener Factura](https://docs.facturapi.io/api/#tag/invoice/operation/getInvoice)), la propiedad `cancellation_status` reflejará el estado más reciente de la solicitud. + /// + /// Consulta los valores posibles de `cancellation_status` más abajo. + /// + /// Después de la cancelación la factura ya no tendrá validez, el objeto cambiará su `status` a `"canceled"` y seguirá estando disponible para futuras consultas. + /// + /// Si el status de la factura es `draft`, este método la eliminará de la base de datos. + /// + /// Si el status de la factura es `canceled`, este método regresará un error. + /// + /// + /// ID de la factura a cancelar + /// Parámetros de consulta. Admite CancellationQueryInput. + /// Permite cancelar la solicitud. + /// Solicitud de cancelación exitosa + /// + public Task CancelAsync(string id, CancellationQueryInput? query, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.SendByEmail(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - } + return RequestAsync(HttpMethod.Delete, $"invoices/{Uri.EscapeDataString(id)}", query, null, false, cancellationToken); } - private async Task DownloadAsync(string id, string format, CancellationToken cancellationToken) + /// + /// Enviar factura por correo electrónico + /// + /// Envía un correo electrónico a la dirección de tu cliente, con los archivos XML y PDF adjuntos al mensaje. + /// + /// ID del objeto a obtener + /// Datos de la solicitud. Admite SendInvoiceByEmailInput. + /// Permite cancelar la solicitud. + /// Objeto genérico de respuesta + /// + public Task SendByEmailAsync(string id, JsonObject? data = null, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.DownloadInvoice(id, format), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); - var memory = new MemoryStream(); - await responseStream.CopyToAsync(memory, 81920, cancellationToken).ConfigureAwait(false); - memory.Position = 0; - return memory; - } + return RequestAsync(HttpMethod.Post, $"invoices/{Uri.EscapeDataString(id)}/email", null, data, true, cancellationToken); } - public Task DownloadZipAsync(string id, CancellationToken cancellationToken = default) + /// + /// Enviar factura por correo electrónico + /// + /// Envía un correo electrónico a la dirección de tu cliente, con los archivos XML y PDF adjuntos al mensaje. + /// + /// ID del objeto a obtener + /// Datos de la solicitud. Admite SendInvoiceByEmailInput. + /// Permite cancelar la solicitud. + /// Objeto genérico de respuesta + /// + public Task SendByEmailAsync(string id, SendInvoiceByEmailInput data, CancellationToken cancellationToken = default) { - return this.DownloadAsync(id, "zip", cancellationToken); + return RequestAsync(HttpMethod.Post, $"invoices/{Uri.EscapeDataString(id)}/email", null, data, true, cancellationToken); } + /// + /// Descargar factura + /// + /// Descarga tu Factura en PDF, XML o ambos en un archivo comprimido ZIP. + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// public Task DownloadPdfAsync(string id, CancellationToken cancellationToken = default) { - return this.DownloadAsync(id, "pdf", cancellationToken); + return RequestAsync(HttpMethod.Get, $"invoices/{Uri.EscapeDataString(id)}/pdf", null, null, false, cancellationToken); } + /// + /// Descargar factura + /// + /// Descarga tu Factura en PDF, XML o ambos en un archivo comprimido ZIP. + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// public Task DownloadXmlAsync(string id, CancellationToken cancellationToken = default) { - return this.DownloadAsync(id, "xml", cancellationToken); + return RequestAsync(HttpMethod.Get, $"invoices/{Uri.EscapeDataString(id)}/xml", null, null, false, cancellationToken); + } + + /// + /// Descargar factura + /// + /// Descarga tu Factura en PDF, XML o ambos en un archivo comprimido ZIP. + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// + public Task DownloadZipAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"invoices/{Uri.EscapeDataString(id)}/zip", null, null, false, cancellationToken); + } + + /// + /// Obtener enlace de descarga + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar la factura en PDF, XML o ambos en un archivo comprimido ZIP, sin que el archivo pase por tu servidor. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + public Task DownloadPdfUrlAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"invoices/{Uri.EscapeDataString(id)}/download-url/pdf", null, null, false, cancellationToken); + } + + /// + /// Obtener enlace de descarga + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar la factura en PDF, XML o ambos en un archivo comprimido ZIP, sin que el archivo pase por tu servidor. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + public Task DownloadXmlUrlAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"invoices/{Uri.EscapeDataString(id)}/download-url/xml", null, null, false, cancellationToken); + } + + /// + /// Obtener enlace de descarga + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar la factura en PDF, XML o ambos en un archivo comprimido ZIP, sin que el archivo pase por tu servidor. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + public Task DownloadZipUrlAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"invoices/{Uri.EscapeDataString(id)}/download-url/zip", null, null, false, cancellationToken); + } + + /// + /// Solicitar ZIP mensual de facturas + /// + /// Solicita un archivo ZIP con las facturas del mes que coincidan con los filtros indicados. Consulta el estado de la solicitud y descarga el archivo cuando esté listo. + /// + /// Incluye XML y PDF de facturas vigentes y canceladas. Los archivos de facturas canceladas se agrupan en `canceladas/`. + /// + /// Requiere una llave de API de organización en ambiente Live, una suscripción activa y permiso para leer facturas. Las llaves de ambiente Test regresan HTTP 402. + /// + /// Puedes exportar el mes en curso. Consulta `is_current` para saber si el paquete refleja la información vigente; si está desactualizado, solicita nuevamente el ZIP con los mismos filtros. Los IDs anteriores siguen permitiendo descargar su paquete original. + /// + /// + /// Datos de la solicitud. Admite InvoiceZipRequestCreateInput. + /// Permite cancelar la solicitud. + /// Solicitud de ZIP procesada correctamente. + /// + public Task CreateZipRequestAsync(JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"invoices/zip-requests", null, data, true, cancellationToken); + } + + /// + /// Solicitar ZIP mensual de facturas + /// + /// Solicita un archivo ZIP con las facturas del mes que coincidan con los filtros indicados. Consulta el estado de la solicitud y descarga el archivo cuando esté listo. + /// + /// Incluye XML y PDF de facturas vigentes y canceladas. Los archivos de facturas canceladas se agrupan en `canceladas/`. + /// + /// Requiere una llave de API de organización en ambiente Live, una suscripción activa y permiso para leer facturas. Las llaves de ambiente Test regresan HTTP 402. + /// + /// Puedes exportar el mes en curso. Consulta `is_current` para saber si el paquete refleja la información vigente; si está desactualizado, solicita nuevamente el ZIP con los mismos filtros. Los IDs anteriores siguen permitiendo descargar su paquete original. + /// + /// + /// Datos de la solicitud. Admite InvoiceZipRequestCreateInput. + /// Permite cancelar la solicitud. + /// Solicitud de ZIP procesada correctamente. + /// + public Task CreateZipRequestAsync(InvoiceZipRequestCreateInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"invoices/zip-requests", null, data, true, cancellationToken); + } + + /// + /// Listar solicitudes de ZIP mensual + /// + /// Regresa una lista paginada de solicitudes de ZIP. `year` y `month` deben enviarse juntos. `invoice_types` filtra por un tipo o por un arreglo normalizado exacto. + /// + /// Este método requiere una llave de API de organización en ambiente Live, una suscripción activa y permiso para leer facturas. + /// + /// + /// Parámetros de consulta. Admite InvoiceListZipRequestsParams. + /// Permite cancelar la solicitud. + /// Resultado paginado de solicitudes de ZIP. + /// + public Task> ListZipRequestsAsync(JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"invoices/zip-requests", query, null, false, cancellationToken); + } + + /// + /// Listar solicitudes de ZIP mensual + /// + /// Regresa una lista paginada de solicitudes de ZIP. `year` y `month` deben enviarse juntos. `invoice_types` filtra por un tipo o por un arreglo normalizado exacto. + /// + /// Este método requiere una llave de API de organización en ambiente Live, una suscripción activa y permiso para leer facturas. + /// + /// + /// Parámetros de consulta. Admite InvoiceListZipRequestsParams. + /// Permite cancelar la solicitud. + /// Resultado paginado de solicitudes de ZIP. + /// + public Task> ListZipRequestsAsync(InvoiceListZipRequestsParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"invoices/zip-requests", query, null, false, cancellationToken); + } + + /// + /// Recuperar solicitud de ZIP mensual + /// + /// Recupera una solicitud de ZIP. Consulta este método hasta que el status sea `finished` o `failed`. Cuando sea `finished`, descarga el archivo con el método de descarga. + /// + /// Requiere una llave de API de organización en ambiente Live, una suscripción activa y permiso para leer facturas. + /// + /// + /// Identificador de la solicitud de ZIP. + /// Permite cancelar la solicitud. + /// Solicitud de ZIP recuperada correctamente. + /// + public Task RetrieveZipRequestAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"invoices/zip-requests/{Uri.EscapeDataString(id)}", null, null, false, cancellationToken); + } + + /// + /// Descargar ZIP mensual + /// + /// Descarga el ZIP de una solicitud terminada. El nombre del archivo usa el formato `YYYY-MM.zip`. + /// + /// Requiere una llave de API de organización en ambiente Live, una suscripción activa y permiso para leer facturas. + /// + /// + /// Identificador de la solicitud de ZIP. + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// + public Task DownloadZipRequestAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"invoices/zip-requests/{Uri.EscapeDataString(id)}/zip", null, null, false, cancellationToken); } - private async Task DownloadCancellationReceiptAsync(string id, string format, CancellationToken cancellationToken) + /// + /// Obtener URL de descarga del ZIP mensual + /// + /// Devuelve un objeto con los metadatos del archivo y una URL temporal para descargar el ZIP de una solicitud terminada sin que el archivo viaje a través de tu servidor. + /// + /// La URL permite acceder únicamente a ese archivo mientras sea válida: trátala como una credencial y no la almacenes. Requiere una llave de API de organización en ambiente Live, una suscripción activa y permiso para leer facturas. + /// + /// + /// Identificador de la solicitud de ZIP. + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + public Task DownloadZipRequestUrlAsync(string id, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.DownloadCancellationReceipt(id, format), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); - var memory = new MemoryStream(); - await responseStream.CopyToAsync(memory, 81920, cancellationToken).ConfigureAwait(false); - memory.Position = 0; - return memory; - } + return RequestAsync(HttpMethod.Get, $"invoices/zip-requests/{Uri.EscapeDataString(id)}/download-url", null, null, false, cancellationToken); } + /// + /// Descargar acuse de cancelación + /// + /// Descarga en XML o PDF el acuse emitido por el SAT al solicitar la cancelación mediante Facturapi. El acuse contiene el resultado inmediato de la solicitud y no necesariamente acredita que el CFDI ya esté cancelado; consulta el estado de la factura para confirmar el desenlace. + /// + /// ID del objeto a obtener + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// public Task DownloadCancellationReceiptXmlAsync(string id, CancellationToken cancellationToken = default) { - return DownloadCancellationReceiptAsync(id, "xml", cancellationToken); + return RequestAsync(HttpMethod.Get, $"invoices/{Uri.EscapeDataString(id)}/cancellation_receipt/xml", null, null, false, cancellationToken); } + /// + /// Descargar acuse de cancelación + /// + /// Descarga en XML o PDF el acuse emitido por el SAT al solicitar la cancelación mediante Facturapi. El acuse contiene el resultado inmediato de la solicitud y no necesariamente acredita que el CFDI ya esté cancelado; consulta el estado de la factura para confirmar el desenlace. + /// + /// ID del objeto a obtener + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// public Task DownloadCancellationReceiptPdfAsync(string id, CancellationToken cancellationToken = default) { - return DownloadCancellationReceiptAsync(id, "pdf", cancellationToken); + return RequestAsync(HttpMethod.Get, $"invoices/{Uri.EscapeDataString(id)}/cancellation_receipt/pdf", null, null, false, cancellationToken); } - public async Task UpdateStatusAsync(string id, CancellationToken cancellationToken = default) + /// + /// Obtener enlace del acuse de cancelación + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar en XML o PDF el acuse emitido por el SAT al solicitar la cancelación mediante Facturapi. El acuse contiene el resultado inmediato de la solicitud y no necesariamente acredita que el CFDI ya esté cancelado; consulta el estado de la factura para confirmar el desenlace. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + public Task DownloadCancellationReceiptPdfUrlAsync(string id, CancellationToken cancellationToken = default) { - using (var content = new StringContent("", Encoding.UTF8, "application/json")) - using (var response = await client.PutAsync(Router.UpdateStatus(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var invoice = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return invoice; - } + return RequestAsync(HttpMethod.Get, $"invoices/{Uri.EscapeDataString(id)}/cancellation_receipt/download-url/pdf", null, null, false, cancellationToken); } - public async Task UpdateDraftAsync(string id, Dictionary data, CancellationToken cancellationToken = default) + /// + /// Obtener enlace del acuse de cancelación + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar en XML o PDF el acuse emitido por el SAT al solicitar la cancelación mediante Facturapi. El acuse contiene el resultado inmediato de la solicitud y no necesariamente acredita que el CFDI ya esté cancelado; consulta el estado de la factura para confirmar el desenlace. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + public Task DownloadCancellationReceiptXmlUrlAsync(string id, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PutAsync(Router.UpdateDraftInvoice(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var invoice = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return invoice; - } + return RequestAsync(HttpMethod.Get, $"invoices/{Uri.EscapeDataString(id)}/cancellation_receipt/download-url/xml", null, null, false, cancellationToken); } - public async Task StampDraftAsync(string id, Dictionary options = null, CancellationToken cancellationToken = default) + /// + /// Editar borrador de factura + /// + /// Actualiza la información de una factura con status `draft`, asignando + /// los valores de los parámetros enviados. Los parámetros que no se envíen + /// en la petición no se modificarán. + /// + /// En el objeto `invoice` de respuesta, Facturapi asignará automáticamente + /// el campo `is_ready_to_stamp` con el valor `true` si la factura pasa la + /// validación mínima requerida para ser timbrada; de lo contrario, el campo + /// `is_ready_to_stamp` será `false`. + /// + /// + /// ID del objeto a editar + /// Datos de la solicitud. Admite UpdateDraftInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto `Invoice` editado correctamente + /// + public Task UpdateDraftAsync(string id, JsonObject data, CancellationToken cancellationToken = default) { - using (var content = new StringContent("", Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.StampDraftInvoice(id, options), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var invoice = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return invoice; - } + return RequestAsync(HttpMethod.Put, $"invoices/{Uri.EscapeDataString(id)}", null, data, true, cancellationToken); } + /// + /// Editar borrador de factura + /// + /// Actualiza la información de una factura con status `draft`, asignando + /// los valores de los parámetros enviados. Los parámetros que no se envíen + /// en la petición no se modificarán. + /// + /// En el objeto `invoice` de respuesta, Facturapi asignará automáticamente + /// el campo `is_ready_to_stamp` con el valor `true` si la factura pasa la + /// validación mínima requerida para ser timbrada; de lo contrario, el campo + /// `is_ready_to_stamp` será `false`. + /// + /// + /// ID del objeto a editar + /// Datos de la solicitud. Admite UpdateDraftInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto `Invoice` editado correctamente + /// + public Task UpdateDraftAsync(string id, UpdateDraftInvoiceInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"invoices/{Uri.EscapeDataString(id)}", null, data, true, cancellationToken); + } + + /// + /// Timbrar borrador de factura + /// + /// Timbra una factura con status `draft` y la envía al SAT para su validación. + /// + /// Al usar este método, el valor del campo `is_ready_to_stamp` (asignado por Facturapi) + /// deberá ser `true`. De otra forma, la llamada regresará un error. + /// + /// Este método no permite editar la factura, sólo timbrarla. Si necesitas editar información + /// en la factura antes de timbrarla, usa el método [Editar Borrador de Factura](https://docs.facturapi.io/api/#tag/invoice/operation/editDraftInvoice). + /// + /// + /// ID del objeto a timbrar + /// Parámetros de consulta. Admite InvoiceStampDraftParams. + /// Permite cancelar la solicitud. + /// Objeto `Invoice` timbrado correctamente + /// + public Task StampDraftAsync(string id, JsonObject? options = null, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"invoices/{Uri.EscapeDataString(id)}/stamp", options, null, false, cancellationToken); + } + + /// + /// Timbrar borrador de factura + /// + /// Timbra una factura con status `draft` y la envía al SAT para su validación. + /// + /// Al usar este método, el valor del campo `is_ready_to_stamp` (asignado por Facturapi) + /// deberá ser `true`. De otra forma, la llamada regresará un error. + /// + /// Este método no permite editar la factura, sólo timbrarla. Si necesitas editar información + /// en la factura antes de timbrarla, usa el método [Editar Borrador de Factura](https://docs.facturapi.io/api/#tag/invoice/operation/editDraftInvoice). + /// + /// + /// ID del objeto a timbrar + /// Parámetros de consulta. Admite InvoiceStampDraftParams. + /// Permite cancelar la solicitud. + /// Objeto `Invoice` timbrado correctamente + /// + public Task StampDraftAsync(string id, InvoiceStampDraftParams? options, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"invoices/{Uri.EscapeDataString(id)}/stamp", options, null, false, cancellationToken); + } + + /// + /// Actualizar status de factura + /// + /// + /// Consulta el status de una factura timbrada en el SAT y actualiza el objeto invoice + /// con La información más reciente. + /// + /// + /// ID del objeto invoice a actualizar + /// Permite cancelar la solicitud. + /// Objeto `Invoice` actualizado + /// + public Task UpdateStatusAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"invoices/{Uri.EscapeDataString(id)}/status", null, null, false, cancellationToken); + } + + /// + /// Copiar a borrador + /// + /// Crea una copia en borrador de la factura especificada. + /// + /// + /// ID de la factura a copiar + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` con status `draft`. + /// + public Task CopyToDraftAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"invoices/{Uri.EscapeDataString(id)}/copy", null, null, false, cancellationToken); + } + + /// + /// Vista previa de factura en PDF + /// + /// Genera una vista previa en PDF de una factura sin timbrar ni guardar en la organización. + /// + /// Datos de la solicitud. Admite UpdateDraftInvoiceInput. + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// + public Task PreviewPdfAsync(JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"invoices/preview/pdf", null, data, true, cancellationToken); + } + + /// + /// Vista previa de factura en PDF + /// + /// Genera una vista previa en PDF de una factura sin timbrar ni guardar en la organización. + /// + /// Datos de la solicitud. Admite UpdateDraftInvoiceInput. + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// + public Task PreviewPdfAsync(UpdateDraftInvoiceInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"invoices/preview/pdf", null, data, true, cancellationToken); + } + + /// + /// Obtener URL del preview PDF de factura + /// + /// Devuelve un objeto con los metadatos del archivo y una URL temporal para el preview PDF de una factura sin timbrar. + /// + /// Datos de la solicitud. Admite UpdateDraftInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + public Task PreviewPdfUrlAsync(JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"invoices/preview/pdf/download-url", null, data, true, cancellationToken); + } + + /// + /// Obtener URL del preview PDF de factura + /// + /// Devuelve un objeto con los metadatos del archivo y una URL temporal para el preview PDF de una factura sin timbrar. + /// + /// Datos de la solicitud. Admite UpdateDraftInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + public Task PreviewPdfUrlAsync(UpdateDraftInvoiceInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"invoices/preview/pdf/download-url", null, data, true, cancellationToken); + } + + /// + /// Timbrar borrador de factura + /// + /// Timbra una factura con status `draft` y la envía al SAT para su validación. + /// + /// Al usar este método, el valor del campo `is_ready_to_stamp` (asignado por Facturapi) + /// deberá ser `true`. De otra forma, la llamada regresará un error. + /// + /// Este método no permite editar la factura, sólo timbrarla. Si necesitas editar información + /// en la factura antes de timbrarla, usa el método [Editar Borrador de Factura](https://docs.facturapi.io/api/#tag/invoice/operation/editDraftInvoice). + /// + /// + /// id + /// options + /// Permite cancelar la solicitud. + /// Objeto `Invoice` timbrado correctamente + /// [Obsolete("Use StampDraftAsync instead.")] - public Task StampDraft(string id, Dictionary options = null, CancellationToken cancellationToken = default) + public Task StampDraft(string id, JsonObject? options = null, CancellationToken cancellationToken = default) => StampDraftAsync(id, options, cancellationToken); + + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Ingreso + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + public Task CreateIngresoAsync(InvoiceIngresoInput data, CancellationToken cancellationToken = default) { - return this.StampDraftAsync(id, options, cancellationToken); + return CreateAsync(data, null, cancellationToken); } - public async Task CopyToDraftAsync(string id, CancellationToken cancellationToken = default) + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Egreso + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + public Task CreateEgresoAsync(InvoiceEgresoInput data, CancellationToken cancellationToken = default) { - using (var content = new StringContent("", Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.CopyInvoice(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var invoice = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return invoice; - } + return CreateAsync(data, null, cancellationToken); } - public async Task PreviewPdfAsync(Dictionary data, CancellationToken cancellationToken = default) + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Pago + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + public Task CreatePagoAsync(InvoicePagoInput data, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.PreviewPdf(), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); - var memory = new MemoryStream(); - await responseStream.CopyToAsync(memory, 81920, cancellationToken).ConfigureAwait(false); - memory.Position = 0; - return memory; - } + return CreateAsync(data, null, cancellationToken); } - public async Task> CreateZipRequestAsync(Dictionary data, CancellationToken cancellationToken = default) + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Nómina + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + public Task CreateNominaAsync(InvoiceNominaInput data, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.CreateZipRequest(), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - } + return CreateAsync(data, null, cancellationToken); } - public async Task>> ListZipRequestsAsync(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Traslado + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + public Task CreateTrasladoAsync(InvoiceTrasladoInput data, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.ListZipRequests(query), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject>>(resultString, this.jsonSettings); - } + return CreateAsync(data, null, cancellationToken); } - public async Task> RetrieveZipRequestAsync(string id, CancellationToken cancellationToken = default) + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Datos de la factura según su tipo y estado inicial. Omite status para timbrar; usa draft para guardar un borrador. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + public Task CreateDraftIngresoAsync(InvoiceIngresoDraftInput data, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.RetrieveZipRequest(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - } + return CreateAsync(data, null, cancellationToken); } - public async Task DownloadZipRequestAsync(string id, CancellationToken cancellationToken = default) + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Datos de la factura según su tipo y estado inicial. Omite status para timbrar; usa draft para guardar un borrador. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + public Task CreateDraftEgresoAsync(InvoiceEgresoDraftInput data, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.DownloadZipRequest(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); - var memory = new MemoryStream(); - await responseStream.CopyToAsync(memory, 81920, cancellationToken).ConfigureAwait(false); - memory.Position = 0; - return memory; - } + return CreateAsync(data, null, cancellationToken); } + + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Datos de la factura según su tipo y estado inicial. Omite status para timbrar; usa draft para guardar un borrador. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + public Task CreateDraftPagoAsync(InvoicePagoDraftInput data, CancellationToken cancellationToken = default) + { + return CreateAsync(data, null, cancellationToken); + } + + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Datos de la factura según su tipo y estado inicial. Omite status para timbrar; usa draft para guardar un borrador. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + public Task CreateDraftNominaAsync(InvoiceNominaDraftInput data, CancellationToken cancellationToken = default) + { + return CreateAsync(data, null, cancellationToken); + } + + /// + /// Crear factura (CFDI 4.0) + /// + /// Crea una nueva Factura. Si la factura es creada en ambiente Live, ésta será **timbrada y enviada al SAT**. + /// + /// Revisa e infórmate sobre el [rescate de CFDI en intermitencias (Status 202)](https://docs.facturapi.io/docs/guides/invoices/intermitencias). + /// + /// + /// Datos de la factura según su tipo y estado inicial. Omite status para timbrar; usa draft para guardar un borrador. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado Solicitud aceptada; Facturapi intentará recuperar el CFDI hasta cinco veces, una cada 10 minutos + /// + public Task CreateDraftTrasladoAsync(InvoiceTrasladoDraftInput data, CancellationToken cancellationToken = default) + { + return CreateAsync(data, null, cancellationToken); + } + } } diff --git a/Wrappers/NominaCatalogWrapper.cs b/Wrappers/NominaCatalogWrapper.cs index 6fdc470..498168a 100644 --- a/Wrappers/NominaCatalogWrapper.cs +++ b/Wrappers/NominaCatalogWrapper.cs @@ -1,35 +1,79 @@ -using Newtonsoft.Json; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; using System.Net.Http; using System.Threading; using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public class NominaCatalogWrapper : BaseWrapper, INominaCatalogWrapper + /// + /// Operaciones de NominaCatalog. + /// + public partial class NominaCatalogWrapper : BaseWrapper, INominaCatalogWrapper { - internal NominaCatalogWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) + internal NominaCatalogWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) {} + + /// + /// Buscar tipos de deducción de nómina + /// + /// Devuelve tipos de deducción que coinciden con la consulta. + /// + /// Parámetros de consulta. Admite NominaCatalogSearchDeductionsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchDeductions(JsonObject? query = null, CancellationToken cancellationToken = default) { + return RequestAsync>(HttpMethod.Get, $"catalogs/deductions", query, null, false, cancellationToken); } - public Task> SearchDeductions(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Buscar tipos de deducción de nómina + /// + /// Devuelve tipos de deducción que coinciden con la consulta. + /// + /// Parámetros de consulta. Admite NominaCatalogSearchDeductionsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchDeductions(NominaCatalogSearchDeductionsParams? query, CancellationToken cancellationToken = default) { - return SearchCatalogAsync(Router.SearchNominaDeductions(query), cancellationToken); + return RequestAsync>(HttpMethod.Get, $"catalogs/deductions", query, null, false, cancellationToken); } - public Task> SearchPerceptions(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Buscar tipos de percepción de nómina + /// + /// Devuelve tipos de percepción que coinciden con la consulta. + /// + /// Parámetros de consulta. Admite NominaCatalogSearchPerceptionsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchPerceptions(JsonObject? query = null, CancellationToken cancellationToken = default) { - return SearchCatalogAsync(Router.SearchNominaPerceptions(query), cancellationToken); + return RequestAsync>(HttpMethod.Get, $"catalogs/perceptions", query, null, false, cancellationToken); } - private async Task> SearchCatalogAsync(string url, CancellationToken cancellationToken) + /// + /// Buscar tipos de percepción de nómina + /// + /// Devuelve tipos de percepción que coinciden con la consulta. + /// + /// Parámetros de consulta. Admite NominaCatalogSearchPerceptionsParams. + /// Permite cancelar la solicitud. + /// Búsqueda exitosa + /// + public Task> SearchPerceptions(NominaCatalogSearchPerceptionsParams? query, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(url, cancellationToken).ConfigureAwait(false)) - { - await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject>(resultString, jsonSettings); - } + return RequestAsync>(HttpMethod.Get, $"catalogs/perceptions", query, null, false, cancellationToken); } + } } diff --git a/Wrappers/OrganizationWrapper.cs b/Wrappers/OrganizationWrapper.cs index e55ebd2..9575f09 100644 --- a/Wrappers/OrganizationWrapper.cs +++ b/Wrappers/OrganizationWrapper.cs @@ -1,487 +1,970 @@ -using Newtonsoft.Json; -using System.Collections.Generic; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; using System.IO; +using System.Collections.Generic; using System.Net.Http; -using System.Text; -using System.Threading.Tasks; using System.Threading; +using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public class OrganizationWrapper : BaseWrapper, IOrganizationWrapper + /// + /// Operaciones de Organization. + /// + public partial class OrganizationWrapper : BaseWrapper, IOrganizationWrapper { - internal OrganizationWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) - { - } - - public async Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default) - { - using (var response = await client.GetAsync(Router.ListOrganizations(query), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - - var searchResult = JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - return searchResult; - } - } - - public async Task MeAsync(CancellationToken cancellationToken = default) - { - using (var response = await client.GetAsync(Router.OrganizationMe(), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var organization = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return organization; - } - } - - public async Task CheckDomainIsAvailableAsync(string domain, CancellationToken cancellationToken = default) - { - using (var response = await client.GetAsync(Router.CheckDomainAvailability(new Dictionary { ["domain"] = domain }), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var availability = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return availability; - } - } - - public async Task CreateAsync(Dictionary data, CancellationToken cancellationToken = default) - { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.CreateOrganization(), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var organization = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return organization; - } - } - - public async Task RetrieveAsync(string id, CancellationToken cancellationToken = default) - { - using (var response = await client.GetAsync(Router.RetrieveOrganization(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var organization = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return organization; - } - } - - public async Task DeleteAsync(string id, CancellationToken cancellationToken = default) - { - using (var response = await client.DeleteAsync(Router.DeleteOrganization(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var organization = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return organization; - } - } - + internal OrganizationWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) {} + + /// + /// Crear organización + /// + /// Crea una nueva Organización que pertenecerá a tu cuenta de usuario. + /// + /// Después de crear la organización y antes de poder emitir facturas con + /// la organización, deberás de terminar de configurarla llamando a los + /// métodos de [Actualizar datos fiscales](https://docs.facturapi.io/api/#tag/organization/operation/editOrganizationLegal) y + /// [Subir certificados (CSD)](https://docs.facturapi.io/api/#tag/organization/operation/uploadOrganizationCertificate) + /// + /// + /// Después de crear la organización y antes de poder emitir facturas con + /// la organización, deberás de terminar de configurarla llamando a los + /// métodos de [Actualizar datos fiscales](https://docs.facturapi.io/api/#tag/organization/operation/editOrganizationLegal) y + /// [Subir certificados (CSD)](https://docs.facturapi.io/api/#tag/organization/operation/uploadOrganizationCertificate), + /// además de firmar la Carta Manifiesto que autoriza a nuestro PAC a timbrar facturas; + /// puedes hacerlo en [tu dashboard](https://dashboard.facturapi.io/settings/manifiesto) + /// o en [nuestro portal público](https://www.facturapi.io/manifiesto). También puedes incrustar + /// en tu solución el módulo de firma de la carta (sin logos, listo para iframe): https://www.facturapi.io/embedded/manifiesto + /// + /// Recuerda que los folios de tu suscripción podrán ser consumidos por + /// cualquiera de las organizaciones registradas bajo tu cuenta. + /// + /// + /// Datos de la solicitud. Admite OrganizationCreateInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Organization` creado + /// + public Task CreateAsync(JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"organizations", null, data, true, cancellationToken); + } + + /// + /// Crear organización + /// + /// Crea una nueva Organización que pertenecerá a tu cuenta de usuario. + /// + /// Después de crear la organización y antes de poder emitir facturas con + /// la organización, deberás de terminar de configurarla llamando a los + /// métodos de [Actualizar datos fiscales](https://docs.facturapi.io/api/#tag/organization/operation/editOrganizationLegal) y + /// [Subir certificados (CSD)](https://docs.facturapi.io/api/#tag/organization/operation/uploadOrganizationCertificate) + /// + /// + /// Después de crear la organización y antes de poder emitir facturas con + /// la organización, deberás de terminar de configurarla llamando a los + /// métodos de [Actualizar datos fiscales](https://docs.facturapi.io/api/#tag/organization/operation/editOrganizationLegal) y + /// [Subir certificados (CSD)](https://docs.facturapi.io/api/#tag/organization/operation/uploadOrganizationCertificate), + /// además de firmar la Carta Manifiesto que autoriza a nuestro PAC a timbrar facturas; + /// puedes hacerlo en [tu dashboard](https://dashboard.facturapi.io/settings/manifiesto) + /// o en [nuestro portal público](https://www.facturapi.io/manifiesto). También puedes incrustar + /// en tu solución el módulo de firma de la carta (sin logos, listo para iframe): https://www.facturapi.io/embedded/manifiesto + /// + /// Recuerda que los folios de tu suscripción podrán ser consumidos por + /// cualquiera de las organizaciones registradas bajo tu cuenta. + /// + /// + /// Datos de la solicitud. Admite OrganizationCreateInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Organization` creado + /// + public Task CreateAsync(OrganizationCreateInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"organizations", null, data, true, cancellationToken); + } + + /// + /// Listar organizaciones + /// + /// Regresa una lista paginada de todas las organizationes registradas bajo tu cuenta, o realiza una búsqueda de acuerdo a parámetros. + /// + /// Parámetros de consulta. Admite OrganizationListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> ListAsync(JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"organizations", query, null, false, cancellationToken); + } + + /// + /// Listar organizaciones + /// + /// Regresa una lista paginada de todas las organizationes registradas bajo tu cuenta, o realiza una búsqueda de acuerdo a parámetros. + /// + /// Parámetros de consulta. Admite OrganizationListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> ListAsync(OrganizationListParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"organizations", query, null, false, cancellationToken); + } + + /// + /// Obtener organización por ID + /// + /// Regresa el objeto 'Organization' relacionado al `id` especificado. + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Objeto `Organization` + /// + public Task RetrieveAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"organizations/{Uri.EscapeDataString(id)}", null, null, false, cancellationToken); + } + + /// + /// Editar datos fiscales + /// + /// Actualiza los datos fiscales de la organización. + /// + /// Si estás buscando cómo editar el RFC, recuerda que la propiedad + /// `tax_id` se asigna automáticamente al subir los Certificados de Sello + /// Digital. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationLegalInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + public Task UpdateLegalAsync(string id, JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(id)}/legal", null, data, true, cancellationToken); + } + + /// + /// Editar datos fiscales + /// + /// Actualiza los datos fiscales de la organización. + /// + /// Si estás buscando cómo editar el RFC, recuerda que la propiedad + /// `tax_id` se asigna automáticamente al subir los Certificados de Sello + /// Digital. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationLegalInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + public Task UpdateLegalAsync(string id, OrganizationLegalInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(id)}/legal", null, data, true, cancellationToken); + } + + /// + /// Editar personalización + /// + /// Actualiza la información relacionada con la identidad o branding de la organización. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationCustomizationInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + public Task UpdateCustomizationAsync(string id, JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(id)}/customization", null, data, true, cancellationToken); + } + + /// + /// Editar personalización + /// + /// Actualiza la información relacionada con la identidad o branding de la organización. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationCustomizationInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + public Task UpdateCustomizationAsync(string id, OrganizationCustomizationInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(id)}/customization", null, data, true, cancellationToken); + } + + /// + /// Editar config. recibos + /// + /// Actualiza los campos enviados de la configuración de recibos de la organización. + /// Para activar la generación automática de facturas globales, la organización + /// debe tener contratado ese feature. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationReceiptsInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + public Task UpdateReceiptSettingsAsync(string id, JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(id)}/receipts", null, data, true, cancellationToken); + } + + /// + /// Editar config. recibos + /// + /// Actualiza los campos enviados de la configuración de recibos de la organización. + /// Para activar la generación automática de facturas globales, la organización + /// debe tener contratado ese feature. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationReceiptsInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + public Task UpdateReceiptSettingsAsync(string id, OrganizationReceiptsInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(id)}/receipts", null, data, true, cancellationToken); + } + + /// + /// Elegir dominio de autofactura + /// + /// Elige el dominio que utilizará esta organización en su micrositio de + /// autofactura. Una vez elegido el dominio, deberás ponerte en contacto + /// con nosotros si necesitas cambiarlo. + /// + /// El dominio que elijas será el que aparecerá en el campo + /// `self_invoice_url` al crear un nuevo recibo, de la siguiente manera: + /// + /// `https://factura.space/{DOMAIN}/{RECEIPT_KEY}` + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationDomainInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + public Task UpdateDomainAsync(string id, JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(id)}/domain", null, data, true, cancellationToken); + } + + /// + /// Elegir dominio de autofactura + /// + /// Elige el dominio que utilizará esta organización en su micrositio de + /// autofactura. Una vez elegido el dominio, deberás ponerte en contacto + /// con nosotros si necesitas cambiarlo. + /// + /// El dominio que elijas será el que aparecerá en el campo + /// `self_invoice_url` al crear un nuevo recibo, de la siguiente manera: + /// + /// `https://factura.space/{DOMAIN}/{RECEIPT_KEY}` + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationDomainInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + public Task UpdateDomainAsync(string id, OrganizationDomainInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(id)}/domain", null, data, true, cancellationToken); + } + + /// + /// Revisar dominio disponible + /// + /// Revisa si un identificador está disponible para elegir como dominio para el portal de autofactura. + /// + /// domain + /// Permite cancelar la solicitud. + /// Información de disponibilidad de dominio + /// + public Task CheckDomainIsAvailableAsync(string domain, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"organizations/domain-check", new Dictionary { ["domain"] = domain }, null, false, cancellationToken); + } + + /// + /// Subir logotipo + /// + /// Sube el logotipo de la organización que será colocado en el PDF y en + /// los correos que se envían al cliente con la factura adjunta. + /// + /// El archivo debe ser una imagen en formato JPG o PNG y tener un tamaño + /// no mayor a 500 KB. Las dimensiones recomendadas son 800 × 500px. + /// + /// Si la organización ya tiene un logotipo, esta llamada reemplaza el + /// logotipo anterior. + /// + /// + /// ID de la organización + /// Format: binary Contenido binario del archivo con la imagen que se usará como logotipo. Formatos soportados: - jpg - png - svg Usa un Stream; se dispone al finalizar la solicitud. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// public async Task UploadLogoAsync(string id, Stream file, CancellationToken cancellationToken = default) { using (var form = new MultipartFormDataContent()) { form.Add(new StreamContent(file), "file", "logo.jpg"); - using (var response = await client.PutAsync(Router.UploadLogo(id), form, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var organization = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return organization; - } - } - } - + return await RequestMultipartAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(id)}/logo", form, cancellationToken).ConfigureAwait(false); + } + } + + /// + /// Subir certificados (CSD) + /// + /// Sube los archivos del Certificado de Sello Digital (CSD) proporcionado + /// por el SAT. Esta llamada también debe usarse para reemplazar los + /// certificados existentes en caso de solicitar nuevos. + /// + /// Al actualizar tus certificados se leerá el RFC y asignará + /// automáticamente a `legal.tax_id`. + /// + /// + /// ID de la organización + /// Format: binary Contenido binario del archivo con extensión `.cer` del certificado CSD. Usa un Stream; se dispone al finalizar la solicitud. + /// Format: binary Contenido binario del archivo con extensión `.key` del certificado CSD. Usa un Stream; se dispone al finalizar la solicitud. + /// Contraseña de la llave del certificado. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// public async Task UploadCertificateAsync(string id, Stream cerFile, Stream keyFile, string password, CancellationToken cancellationToken = default) { using (var form = new MultipartFormDataContent()) { - form.Add(new StreamContent(cerFile), "cer", "certificate.cer"); + form.Add(new StreamContent(cerFile), "cer", "cer.cer"); form.Add(new StreamContent(keyFile), "key", "key.key"); form.Add(new StringContent(password), "password"); - using (var response = await client.PutAsync(Router.UploadCertificate(id), form, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var organization = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return organization; - } - } - } - - public async Task DeleteCertificateAsync(string id, CancellationToken cancellationToken = default) - { - using (var response = await client.DeleteAsync(Router.DeleteCertificate(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var certificateInfo = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return certificateInfo; - } - } - - public async Task UpdateLegalAsync(string id, Dictionary data, CancellationToken cancellationToken = default) - { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PutAsync(Router.UpdateLegal(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var organization = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return organization; - } - } - - public async Task UpdateReceiptSettingsAsync(string id, Dictionary data, CancellationToken cancellationToken = default) - { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PutAsync(Router.UpdateReceipts(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var organization = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return organization; - } - } - - public async Task UpdateCustomizationAsync(string id, Dictionary data, CancellationToken cancellationToken = default) - { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PutAsync(Router.UpdateCustomization(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var organization = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return organization; - } - } - - public async Task UpdateDomainAsync(string id, Dictionary data, CancellationToken cancellationToken = default) - { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PutAsync(Router.UpdateDomain(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var organization = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return organization; - } - } - - public async Task GetTestApiKeyAsync(string id, CancellationToken cancellationToken = default) - { - using (var response = await client.GetAsync(Router.GetTestApiKey(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return resultString; - } - } - - - public async Task RenewTestApiKeyAsync(string id, CancellationToken cancellationToken = default) - { - using (var content = new StringContent("")) - using (var response = await client.PutAsync(Router.RenewTestApiKey(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return resultString; - } - } - - public async Task ListLiveApiKeysAsync(string id, CancellationToken cancellationToken = default) - { - using (var response = await client.GetAsync(Router.ListAsyncLiveApiKeys(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var listResult = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - - return listResult; - } - } - - public async Task RenewLiveApiKeyAsync(string id, CancellationToken cancellationToken = default) - { - using (var content = new StringContent("")) - using (var response = await client.PutAsync(Router.RenewLiveApiKey(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return resultString; - } - } - - - public async Task> ListSeriesAsync(string id, CancellationToken cancellationToken = default) - { - using (var response = await client.GetAsync(Router.ListSeriesGroup(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - - var searchResult = JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - return searchResult; - } - } - - public async Task CreateSeriesAsync(string id, Dictionary data, CancellationToken cancellationToken = default) - { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.CreateSeriesGroup(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var series = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return series; - } - } - - public async Task UpdateSeriesAsync(string id, string seriesName, Dictionary data, CancellationToken cancellationToken = default) - { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PutAsync(Router.UpdateSeriesGroup(id, seriesName), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var series = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return series; - } - } - - public async Task DeleteSeriesAsync(string id, string seriesName, CancellationToken cancellationToken = default) - { - using (var response = await client.DeleteAsync(Router.DeleteSeriesGroup(id, seriesName), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var series = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return series; - } - } - - public async Task UpdateDefaultSeriesAsync(string organizationId, Dictionary data, CancellationToken cancellationToken = default) - { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PutAsync(Router.UpdateDefaultSeries(organizationId), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var organization = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return organization; - } - } - - public async Task> DeleteLiveApiKeyAsync(string id, string apiKeyId, CancellationToken cancellationToken = default) - { - using (var response = await client.DeleteAsync(Router.DeleteLiveApiKey(id, apiKeyId), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var deserializeJson = JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - return deserializeJson; - } - } - - public async Task UpdateSelfInvoiceSettingsAsync(string organizationId, Dictionary data, CancellationToken cancellationToken = default) - { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PutAsync(Router.UpdateSelfInvoiceSettings(organizationId), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var organization = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return organization; - } - } - - public async Task> ListTeamAccessAsync(string organizationId, CancellationToken cancellationToken = default) - { - using (var response = await client.GetAsync(Router.ListTeamAccess(organizationId), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - } - } - - public async Task RetrieveTeamAccessAsync(string organizationId, string accessId, CancellationToken cancellationToken = default) - { - using (var response = await client.GetAsync(Router.RetrieveTeamAccess(organizationId, accessId), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject(resultString, this.jsonSettings); - } - } - - public async Task UpdateTeamAccessRoleAsync(string organizationId, string accessId, string role, CancellationToken cancellationToken = default) - { - using (var content = new StringContent(JsonConvert.SerializeObject(new Dictionary { ["role"] = role }), Encoding.UTF8, "application/json")) - using (var response = await client.PutAsync(Router.UpdateTeamAccessRole(organizationId, accessId), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject(resultString, this.jsonSettings); - } - } - + return await RequestMultipartAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(id)}/certificate", form, cancellationToken).ConfigureAwait(false); + } + } + + /// + /// Eliminar certificados (CSD) + /// + /// Elimina los certificados (CSD) de tu organización. + /// + /// Esto no afecta a las facturas ya emitidas, pero no podrás emitir nuevas facturas hasta que subas nuevos certificados. + /// + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + public Task DeleteCertificateAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Delete, $"organizations/{Uri.EscapeDataString(id)}/certificate", null, null, false, cancellationToken); + } + + /// + /// Obtener enlace de descarga de Carta Manifiesto + /// + /// Devuelve un enlace temporal para descargar en ZIP la Carta Manifiesto firmada que corresponde al RFC del CSD cargado en la organización. + /// + /// La organización debe tener un CSD cargado y debe existir una Carta Manifiesto firmada para el RFC extraído de ese certificado. El enlace da acceso al archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID de la organización. También puedes usar `me` con una Secret Key de la organización. + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal para descargar la Carta Manifiesto en ZIP, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + public Task DownloadManifiestoZipUrlAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"organizations/{Uri.EscapeDataString(id)}/manifiesto/download-url", null, null, false, cancellationToken); + } + + /// + /// Eliminar organización + /// + /// Elimina la organización de tu cuenta de Facturapi. Una vez eliminada, + /// ya no podrás acceder a sus recursos, tales como clientes, productos, + /// facturas, recibos o retenciones. + /// + /// + /// ID del objeto a eliminar + /// Permite cancelar la solicitud. + /// Objeto `Organization` eliminado correctamente + /// + public Task DeleteAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Delete, $"organizations/{Uri.EscapeDataString(id)}", null, null, false, cancellationToken); + } + + /// + /// Obtener Test Api Key + /// + /// Obtiene la llave secreta de ambiente Test de la organización. + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Test API Key + /// + public Task GetTestApiKeyAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"organizations/{Uri.EscapeDataString(id)}/apikeys/test", null, null, false, cancellationToken); + } + + /// + /// Renovar Test API Key + /// + /// Renueva la llave secreta de ambiente Test de la organización e invalida inmediatamente la anterior. + /// + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Test API Key + /// + public Task RenewTestApiKeyAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(id)}/apikeys/test", null, null, false, cancellationToken); + } + + /// + /// Listar Live API Keys + /// + /// Listar llaves secretas de ambiente Live de la organización. + /// + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Live API Key + /// + public Task> ListLiveApiKeysAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"organizations/{Uri.EscapeDataString(id)}/apikeys/live", null, null, false, cancellationToken); + } + + /// + /// Crear Live API Key + /// + /// Genera una nueva llave secreta de ambiente Live de la organización. + /// Esta operación no invalida las llaves generadas previamente. El endpoint usa `PUT` + /// por compatibilidad histórica, pero su comportamiento es crear una nueva llave. + /// + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Live API Key + /// + public Task RenewLiveApiKeyAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(id)}/apikeys/live", null, null, false, cancellationToken); + } + + /// + /// Revocar Live API Key + /// + /// Revocar Live Api Key de tu organización. + /// + /// + /// ID de la organización + /// ID de la llave secreta a eliminar + /// Permite cancelar la solicitud. + /// Live API Key + /// + public Task> DeleteLiveApiKeyAsync(string id, string apiKeyId, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Delete, $"organizations/{Uri.EscapeDataString(id)}/apikeys/live/{Uri.EscapeDataString(apiKeyId)}", null, null, false, cancellationToken); + } + + /// + /// Listado de series + /// + /// Listado de series creadas para la personalización de organización. La cual lleva control de foliaje para cada tipo de factura si está asignada en las personalización de organización. + /// + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Listado de objetos `Series` creadas previamente + /// + public Task> ListSeriesAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"organizations/{Uri.EscapeDataString(id)}/series-group", null, null, false, cancellationToken); + } + + /// + /// Crear serie + /// + /// Crea una nueva serie de folios para la organización. + /// Las series son útiles para llevar un control de los folios emitidos para cada tipo de factura. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationSeriesCreateInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto de la `Serie` creada + /// + public Task> CreateSeriesAsync(string id, JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Post, $"organizations/{Uri.EscapeDataString(id)}/series-group", null, data, true, cancellationToken); + } + + /// + /// Crear serie + /// + /// Crea una nueva serie de folios para la organización. + /// Las series son útiles para llevar un control de los folios emitidos para cada tipo de factura. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationSeriesCreateInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto de la `Serie` creada + /// + public Task> CreateSeriesAsync(string id, OrganizationSeriesCreateInput data, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Post, $"organizations/{Uri.EscapeDataString(id)}/series-group", null, data, true, cancellationToken); + } + + /// + /// Editar serie + /// + /// Edita el número de foliaje de la serie en ambientes Test y Live de la organización. + /// + /// + /// ID de la organización + /// Nombre de la serie + /// Datos de la solicitud. Admite OrganizationSeriesUpdateInput. + /// Permite cancelar la solicitud. + /// Objeto `Serie` editada + /// + public Task> UpdateSeriesAsync(string id, string seriesName, JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(id)}/series-group/{Uri.EscapeDataString(seriesName)}", null, data, true, cancellationToken); + } + + /// + /// Editar serie + /// + /// Edita el número de foliaje de la serie en ambientes Test y Live de la organización. + /// + /// + /// ID de la organización + /// Nombre de la serie + /// Datos de la solicitud. Admite OrganizationSeriesUpdateInput. + /// Permite cancelar la solicitud. + /// Objeto `Serie` editada + /// + public Task> UpdateSeriesAsync(string id, string seriesName, OrganizationSeriesUpdateInput data, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(id)}/series-group/{Uri.EscapeDataString(seriesName)}", null, data, true, cancellationToken); + } + + /// + /// Establecer serie predeterminada + /// + /// Asigna una serie predeterminada para el tipo de comprobante indicado. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationSeriesDefaultInput. + /// Permite cancelar la solicitud. + /// Serie predeterminada actualizada + /// + public Task UpdateDefaultSeriesAsync(string organizationId, JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(organizationId)}/series-group/default-series", null, data, true, cancellationToken); + } + + /// + /// Establecer serie predeterminada + /// + /// Asigna una serie predeterminada para el tipo de comprobante indicado. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationSeriesDefaultInput. + /// Permite cancelar la solicitud. + /// Serie predeterminada actualizada + /// + public Task UpdateDefaultSeriesAsync(string organizationId, OrganizationSeriesDefaultInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(organizationId)}/series-group/default-series", null, data, true, cancellationToken); + } + + /// + /// Eliminar serie + /// + /// Elimina la serie previamente creada + /// + /// + /// ID de la organización + /// Nombre de la serie + /// Permite cancelar la solicitud. + /// Objeto `Serie` eliminado + /// + public Task> DeleteSeriesAsync(string id, string seriesName, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Delete, $"organizations/{Uri.EscapeDataString(id)}/series-group/{Uri.EscapeDataString(seriesName)}", null, null, false, cancellationToken); + } + + /// + /// Detalle de organización + /// + /// Retorna el detalle de la organización actualmente autenticada. + /// + /// + /// Permite cancelar la solicitud. + /// Objeto `Organization` + /// + public Task MeAsync(CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"organizations/me", null, null, false, cancellationToken); + } + + /// + /// Editar config. autofactura + /// + /// Actualiza la configuración del portal de autofactura de la organización. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationSelfInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + public Task UpdateSelfInvoiceSettingsAsync(string organizationId, JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(organizationId)}/self-invoice", null, data, true, cancellationToken); + } + + /// + /// Editar config. autofactura + /// + /// Actualiza la configuración del portal de autofactura de la organización. + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationSelfInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + public Task UpdateSelfInvoiceSettingsAsync(string organizationId, OrganizationSelfInvoiceInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(organizationId)}/self-invoice", null, data, true, cancellationToken); + } + + /// + /// Listar usuarios con acceso a organización + /// + /// Regresa un arreglo con los usuarios que actualmente tienen acceso a la organización, incluyendo al propietario. Este endpoint no está paginado. + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Lista de accesos de usuarios dentro de la organización, incluyendo accesos implícitos como el del propietario + /// + public Task> ListTeamAccessAsync(string organizationId, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"organizations/{Uri.EscapeDataString(organizationId)}/team", null, null, false, cancellationToken); + } + + /// + /// Obtener acceso de usuario + /// + /// Regresa el detalle del acceso del usuario dentro de la organización usando su `access_id`, incluyendo accesos implícitos como el del propietario. + /// + /// ID de la organización + /// ID del acceso + /// Permite cancelar la solicitud. + /// Detalle del acceso del usuario dentro de la organización, incluyendo accesos implícitos como el del propietario + /// + public Task RetrieveTeamAccessAsync(string organizationId, string accessId, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"organizations/{Uri.EscapeDataString(organizationId)}/team/{Uri.EscapeDataString(accessId)}", null, null, false, cancellationToken); + } + + /// + /// Reasignar rol a usuario + /// + /// ID de la organización + /// ID del acceso + /// role + /// Permite cancelar la solicitud. + /// Acceso del usuario actualizado con el nuevo rol + /// + public Task UpdateTeamAccessRoleAsync(string organizationId, string accessId, string role, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(organizationId)}/team/{Uri.EscapeDataString(accessId)}/role", null, new Dictionary { ["role"] = role }, true, cancellationToken); + } + + /// + /// Eliminar usuario con acceso + /// + /// ID de la organización + /// ID del acceso + /// Permite cancelar la solicitud. + /// Usuario removido de la organización + /// public async Task RemoveTeamAccessAsync(string organizationId, string accessId, CancellationToken cancellationToken = default) { - using (var response = await client.DeleteAsync(Router.RetrieveTeamAccess(organizationId, accessId), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return DeserializeOk(resultString); - } - } - - public async Task> ListSentTeamInvitesAsync(string organizationId, CancellationToken cancellationToken = default) - { - using (var response = await client.GetAsync(Router.ListSentTeamInvites(organizationId), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - } - } - - public async Task InviteUserToTeamAsync(string organizationId, Dictionary data, CancellationToken cancellationToken = default) - { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.ListSentTeamInvites(organizationId), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject(resultString, this.jsonSettings); - } - } - + return (await RequestAsync(HttpMethod.Delete, $"organizations/{Uri.EscapeDataString(organizationId)}/team/{Uri.EscapeDataString(accessId)}", null, null, false, cancellationToken).ConfigureAwait(false)).Ok == true; + } + + /// + /// Listar invitaciones enviadas + /// + /// Regresa invitaciones enviadas desde la organización. + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Lista de invitaciones enviadas y aún vigentes para la organización + /// + public Task> ListSentTeamInvitesAsync(string organizationId, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"organizations/{Uri.EscapeDataString(organizationId)}/team/invites", null, null, false, cancellationToken); + } + + /// + /// Invitar usuario a organización + /// + /// Crea o actualiza una invitación de usuario. Por defecto, el acceso es de administrador con permisos completos; para limitarlo, crea un rol y envía su ID en `role`. + /// + /// Cada organización puede invitar a un usuario sin costo adicional. A partir del segundo usuario invitado, cada usuario adicional tendrá un costo mensual. Este cargo se aplica automáticamente cuando el usuario acepta la invitación. + /// Puedes consultar el precio vigente en nuestra [página de precios](https://www.facturapi.io/pricing). + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationInviteCreateInput. + /// Permite cancelar la solicitud. + /// Invitación creada o actualizada para el correo solicitado + /// + public Task InviteUserToTeamAsync(string organizationId, JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"organizations/{Uri.EscapeDataString(organizationId)}/team/invites", null, data, true, cancellationToken); + } + + /// + /// Invitar usuario a organización + /// + /// Crea o actualiza una invitación de usuario. Por defecto, el acceso es de administrador con permisos completos; para limitarlo, crea un rol y envía su ID en `role`. + /// + /// Cada organización puede invitar a un usuario sin costo adicional. A partir del segundo usuario invitado, cada usuario adicional tendrá un costo mensual. Este cargo se aplica automáticamente cuando el usuario acepta la invitación. + /// Puedes consultar el precio vigente en nuestra [página de precios](https://www.facturapi.io/pricing). + /// + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationInviteCreateInput. + /// Permite cancelar la solicitud. + /// Invitación creada o actualizada para el correo solicitado + /// + public Task InviteUserToTeamAsync(string organizationId, OrganizationInviteCreateInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"organizations/{Uri.EscapeDataString(organizationId)}/team/invites", null, data, true, cancellationToken); + } + + /// + /// Cancelar invitación enviada + /// + /// Elimina una invitación pendiente de la organización. + /// + /// ID de la organización + /// Clave pública de la invitación. + /// Permite cancelar la solicitud. + /// Invitación cancelada + /// public async Task CancelTeamInviteAsync(string organizationId, string inviteKey, CancellationToken cancellationToken = default) { - using (var response = await client.DeleteAsync(Router.CancelTeamInvite(organizationId, inviteKey), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return DeserializeOk(resultString); - } - } - - public async Task> ListReceivedTeamInvitesAsync(CancellationToken cancellationToken = default) - { - using (var response = await client.GetAsync(Router.ListReceivedTeamInvites(), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - } - } - - public async Task RespondTeamInviteAsync(string inviteKey, Dictionary data, CancellationToken cancellationToken = default) - { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.RespondTeamInvite(inviteKey), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return DeserializeOk(resultString); - } - } - - public async Task> ListTeamRolesAsync(string organizationId, CancellationToken cancellationToken = default) - { - using (var response = await client.GetAsync(Router.ListTeamRoles(organizationId), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - } - } - - public async Task> ListTeamRoleTemplatesAsync(string organizationId, CancellationToken cancellationToken = default) - { - using (var response = await client.GetAsync(Router.ListTeamRoleTemplates(organizationId), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - } - } - - public async Task> ListTeamRoleOperationsAsync(string organizationId, CancellationToken cancellationToken = default) - { - using (var response = await client.GetAsync(Router.ListTeamRoleOperations(organizationId), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - } - } - - public async Task RetrieveTeamRoleAsync(string organizationId, string roleId, CancellationToken cancellationToken = default) - { - using (var response = await client.GetAsync(Router.RetrieveTeamRole(organizationId, roleId), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject(resultString, this.jsonSettings); - } - } - - public async Task CreateTeamRoleAsync(string organizationId, Dictionary data, CancellationToken cancellationToken = default) - { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.ListTeamRoles(organizationId), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject(resultString, this.jsonSettings); - } - } - - public async Task UpdateTeamRoleAsync(string organizationId, string roleId, Dictionary data, CancellationToken cancellationToken = default) - { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PutAsync(Router.RetrieveTeamRole(organizationId, roleId), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return JsonConvert.DeserializeObject(resultString, this.jsonSettings); - } - } - + return (await RequestAsync(HttpMethod.Delete, $"organizations/{Uri.EscapeDataString(organizationId)}/team/invites/{Uri.EscapeDataString(inviteKey)}", null, null, false, cancellationToken).ConfigureAwait(false)).Ok == true; + } + + /// + /// Listar invitaciones recibidas + /// + /// Regresa las invitaciones recibidas para el usuario autenticado. + /// + /// Permite cancelar la solicitud. + /// Lista de invitaciones recibidas por el usuario autenticado + /// + public Task> ListReceivedTeamInvitesAsync(CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"organizations/invites/pending", null, null, false, cancellationToken); + } + + /// + /// Responder invitación + /// + /// Acepta o rechaza una invitación usando su `invite_key`. + /// + /// Clave pública de la invitación. + /// Datos de la solicitud. Admite OrganizationInviteRespondInput. + /// Permite cancelar la solicitud. + /// Invitación aceptada o rechazada exitosamente + /// + public async Task RespondTeamInviteAsync(string inviteKey, JsonObject data, CancellationToken cancellationToken = default) + { + return (await RequestAsync(HttpMethod.Post, $"organizations/invites/{Uri.EscapeDataString(inviteKey)}/response", null, data, true, cancellationToken).ConfigureAwait(false)).Ok == true; + } + + /// + /// Responder invitación + /// + /// Acepta o rechaza una invitación usando su `invite_key`. + /// + /// Clave pública de la invitación. + /// Datos de la solicitud. Admite OrganizationInviteRespondInput. + /// Permite cancelar la solicitud. + /// Invitación aceptada o rechazada exitosamente + /// + public async Task RespondTeamInviteAsync(string inviteKey, OrganizationInviteRespondInput data, CancellationToken cancellationToken = default) + { + return (await RequestAsync(HttpMethod.Post, $"organizations/invites/{Uri.EscapeDataString(inviteKey)}/response", null, data, true, cancellationToken).ConfigureAwait(false)).Ok == true; + } + + /// + /// Listar roles de organización + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Lista de roles + /// + public Task> ListTeamRolesAsync(string organizationId, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"organizations/{Uri.EscapeDataString(organizationId)}/team/roles", null, null, false, cancellationToken); + } + + /// + /// Listar plantillas de roles + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Plantillas disponibles + /// + public Task> ListTeamRoleTemplatesAsync(string organizationId, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"organizations/{Uri.EscapeDataString(organizationId)}/team/roles/templates", null, null, false, cancellationToken); + } + + /// + /// Listar operaciones de permisos + /// + /// ID de la organización + /// Permite cancelar la solicitud. + /// Lista de códigos de operación + /// + public Task> ListTeamRoleOperationsAsync(string organizationId, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"organizations/{Uri.EscapeDataString(organizationId)}/team/roles/operations", null, null, false, cancellationToken); + } + + /// + /// Obtener rol de organización + /// + /// ID de la organización + /// ID del rol + /// Permite cancelar la solicitud. + /// Detalle del rol + /// + public Task RetrieveTeamRoleAsync(string organizationId, string roleId, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"organizations/{Uri.EscapeDataString(organizationId)}/team/roles/{Uri.EscapeDataString(roleId)}", null, null, false, cancellationToken); + } + + /// + /// Crear rol de organización + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationPermissionRoleCreateInput. + /// Permite cancelar la solicitud. + /// Rol creado + /// + public Task CreateTeamRoleAsync(string organizationId, JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"organizations/{Uri.EscapeDataString(organizationId)}/team/roles", null, data, true, cancellationToken); + } + + /// + /// Crear rol de organización + /// + /// ID de la organización + /// Datos de la solicitud. Admite OrganizationPermissionRoleCreateInput. + /// Permite cancelar la solicitud. + /// Rol creado + /// + public Task CreateTeamRoleAsync(string organizationId, OrganizationPermissionRoleCreateInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"organizations/{Uri.EscapeDataString(organizationId)}/team/roles", null, data, true, cancellationToken); + } + + /// + /// Actualizar rol de organización + /// + /// ID de la organización + /// ID del rol + /// Datos de la solicitud. Admite OrganizationPermissionRoleUpdateInput. + /// Permite cancelar la solicitud. + /// Rol actualizado + /// + public Task UpdateTeamRoleAsync(string organizationId, string roleId, JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(organizationId)}/team/roles/{Uri.EscapeDataString(roleId)}", null, data, true, cancellationToken); + } + + /// + /// Actualizar rol de organización + /// + /// ID de la organización + /// ID del rol + /// Datos de la solicitud. Admite OrganizationPermissionRoleUpdateInput. + /// Permite cancelar la solicitud. + /// Rol actualizado + /// + public Task UpdateTeamRoleAsync(string organizationId, string roleId, OrganizationPermissionRoleUpdateInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(organizationId)}/team/roles/{Uri.EscapeDataString(roleId)}", null, data, true, cancellationToken); + } + + /// + /// Eliminar rol de organización + /// + /// ID de la organización + /// ID del rol + /// Permite cancelar la solicitud. + /// Rol eliminado + /// public async Task DeleteTeamRoleAsync(string organizationId, string roleId, CancellationToken cancellationToken = default) { - using (var response = await client.DeleteAsync(Router.RetrieveTeamRole(organizationId, roleId), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - return DeserializeOk(resultString); - } - } - - private bool DeserializeOk(string resultString) + return (await RequestAsync(HttpMethod.Delete, $"organizations/{Uri.EscapeDataString(organizationId)}/team/roles/{Uri.EscapeDataString(roleId)}", null, null, false, cancellationToken).ConfigureAwait(false)).Ok == true; + } + + /// + /// Subir certificado FIEL + /// + /// Sube los archivos de la e.firma (FIEL) de la organización. + /// + /// La e.firma (FIEL) no es necesaria para crear CFDI. Para timbrar CFDI + /// solo necesitas cargar el Certificado de Sello Digital (CSD). La FIEL es + /// necesaria para utilizar la descarga masiva de CFDI. + /// + /// + /// ID de la organización. También puedes usar `me` con la Live Secret Key de la organización. + /// Format: binary Contenido binario del archivo con extensión `.cer` de la e.firma (FIEL). Usa un Stream; se dispone al finalizar la solicitud. + /// Format: binary Contenido binario del archivo con extensión `.key` de la e.firma (FIEL). Usa un Stream; se dispone al finalizar la solicitud. + /// Contraseña de la llave privada de la e.firma (FIEL). + /// Permite cancelar la solicitud. + /// Objeto `Organization` modificado + /// + public async Task UploadFielAsync(string id, Stream cerFile, Stream keyFile, string password, CancellationToken cancellationToken = default) { - var result = JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - if (result != null && result.TryGetValue("ok", out var okValue)) + using (var form = new MultipartFormDataContent()) { - if (okValue is bool okBool) - { - return okBool; - } - if (bool.TryParse(okValue.ToString(), out var parsed)) - { - return parsed; - } + form.Add(new StreamContent(cerFile), "cer", "cer.cer"); + form.Add(new StreamContent(keyFile), "key", "key.key"); + form.Add(new StringContent(password), "password"); + return await RequestMultipartAsync(HttpMethod.Put, $"organizations/{Uri.EscapeDataString(id)}/fiel", form, cancellationToken).ConfigureAwait(false); } - - return false; } + } } diff --git a/Wrappers/ProductWrapper.cs b/Wrappers/ProductWrapper.cs index 2bb3f72..3caf396 100644 --- a/Wrappers/ProductWrapper.cs +++ b/Wrappers/ProductWrapper.cs @@ -1,74 +1,149 @@ -using Newtonsoft.Json; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; using System.Net.Http; -using System.Text; -using System.Threading.Tasks; using System.Threading; +using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public class ProductWrapper : BaseWrapper, IProductWrapper + /// + /// Operaciones de Product. + /// + public partial class ProductWrapper : BaseWrapper, IProductWrapper { - internal ProductWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) + internal ProductWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) {} + + /// + /// Crear producto + /// + /// Registra un nuevo producto o servicio en tu catálogo de Facturapi. + /// + /// Puedes usar el ID del producto para crear facturas sin tener que enviar todos los datos del producto cada vez. + /// + /// Ten en cuenta que los productos que crees en ambiente _Test_ **no se + /// comparten** con el ambiente _Live_. + /// + /// + /// Datos de la solicitud. Admite ProductCreateInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Product` creado + /// + public Task CreateAsync(JsonObject data, CancellationToken cancellationToken = default) { + return RequestAsync(HttpMethod.Post, $"products", null, data, true, cancellationToken); } - public async Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Crear producto + /// + /// Registra un nuevo producto o servicio en tu catálogo de Facturapi. + /// + /// Puedes usar el ID del producto para crear facturas sin tener que enviar todos los datos del producto cada vez. + /// + /// Ten en cuenta que los productos que crees en ambiente _Test_ **no se + /// comparten** con el ambiente _Live_. + /// + /// + /// Datos de la solicitud. Admite ProductCreateInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Product` creado + /// + public Task CreateAsync(ProductCreateInput data, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.ListProducts(query), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + return RequestAsync(HttpMethod.Post, $"products", null, data, true, cancellationToken); + } - var searchResult = JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - return searchResult; - } + /// + /// Listar productos + /// + /// Regresa una lista paginada de todos los productos de una organización o realiza una búsqueda de acuerdo a parámetros + /// + /// Parámetros de consulta. Admite ProductListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> ListAsync(JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"products", query, null, false, cancellationToken); + } + + /// + /// Listar productos + /// + /// Regresa una lista paginada de todos los productos de una organización o realiza una búsqueda de acuerdo a parámetros + /// + /// Parámetros de consulta. Admite ProductListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> ListAsync(ProductListParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"products", query, null, false, cancellationToken); + } + + /// + /// Obtener producto por ID + /// + /// Regresa el objeto `Product` relacionado al `id` especificado. + /// + /// ID del objeto a obtener + /// Permite cancelar la solicitud. + /// Objeto `Product` + /// + public Task RetrieveAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"products/{Uri.EscapeDataString(id)}", null, null, false, cancellationToken); } - public async Task CreateAsync(Dictionary data, CancellationToken cancellationToken = default) + /// + /// Editar producto + /// + /// Actualiza la información de un producto existente, asignando los valores de los parámetros enviados. Los parámetros que no se envíen en la petición no se modificarán. + /// + /// ID del objeto a editar + /// Datos de la solicitud. Admite ProductUpdateInput. + /// Permite cancelar la solicitud. + /// Objeto `Product` editado correctamente + /// + public Task UpdateAsync(string id, JsonObject data, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.CreateProduct(), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var customer = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return customer; - } + return RequestAsync(HttpMethod.Put, $"products/{Uri.EscapeDataString(id)}", null, data, true, cancellationToken); } - public async Task RetrieveAsync(string id, CancellationToken cancellationToken = default) + /// + /// Editar producto + /// + /// Actualiza la información de un producto existente, asignando los valores de los parámetros enviados. Los parámetros que no se envíen en la petición no se modificarán. + /// + /// ID del objeto a editar + /// Datos de la solicitud. Admite ProductUpdateInput. + /// Permite cancelar la solicitud. + /// Objeto `Product` editado correctamente + /// + public Task UpdateAsync(string id, ProductUpdateInput data, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.RetrieveProduct(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var product = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return product; - } + return RequestAsync(HttpMethod.Put, $"products/{Uri.EscapeDataString(id)}", null, data, true, cancellationToken); } - public async Task DeleteAsync(string id, CancellationToken cancellationToken = default) + /// + /// Eliminar producto + /// + /// Elimina el producto de tu organización. Las facturas asociadas al producto **no** se eliminarán. + /// + /// ID del objeto a eliminar + /// Permite cancelar la solicitud. + /// Objeto `Product` eliminado correctamente + /// + public Task DeleteAsync(string id, CancellationToken cancellationToken = default) { - using (var response = await client.DeleteAsync(Router.DeleteProduct(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var product = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return product; - } + return RequestAsync(HttpMethod.Delete, $"products/{Uri.EscapeDataString(id)}", null, null, false, cancellationToken); } - public async Task UpdateAsync(string id, Dictionary data, CancellationToken cancellationToken = default) - { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PutAsync(Router.UpdateProduct(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var product = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return product; - } - } } } diff --git a/Wrappers/ReceiptWrapper.cs b/Wrappers/ReceiptWrapper.cs index eb93fc3..1692e62 100644 --- a/Wrappers/ReceiptWrapper.cs +++ b/Wrappers/ReceiptWrapper.cs @@ -1,126 +1,475 @@ -using Newtonsoft.Json; -using System.Collections.Generic; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; using System.IO; +using System.Collections.Generic; using System.Net.Http; -using System.Text; -using System.Threading.Tasks; using System.Threading; +using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public class ReceiptWrapper : BaseWrapper, IReceiptWrapper + /// + /// Operaciones de Receipt. + /// + public partial class ReceiptWrapper : BaseWrapper, IReceiptWrapper { - internal ReceiptWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) + internal ReceiptWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) {} + + /// + /// Crear recibo + /// + /// Crea un nuevo Recibo, el cual funge como nota de venta. + /// + /// Todos los recibos generan una URL de autofactura que cliente puede + /// visitar para llenar sus datos fiscales en un micrositio con el branding + /// de la organización. + /// + /// + /// Datos de la solicitud. Admite ReceiptInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Receipt` creado + /// + public Task CreateAsync(JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"receipts", null, data, true, cancellationToken); + } + + /// + /// Crear recibo + /// + /// Crea un nuevo Recibo, el cual funge como nota de venta. + /// + /// Todos los recibos generan una URL de autofactura que cliente puede + /// visitar para llenar sus datos fiscales en un micrositio con el branding + /// de la organización. + /// + /// + /// Datos de la solicitud. Admite ReceiptInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Receipt` creado + /// + public Task CreateAsync(ReceiptInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"receipts", null, data, true, cancellationToken); + } + + /// + /// Listar recibos + /// + /// Regresa una lista paginada de todos los recibos de una organización o realiza una búsqueda de acuerdo a parámetros + /// + /// Parámetros de consulta. Admite ReceiptListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> ListAsync(JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"receipts", query, null, false, cancellationToken); + } + + /// + /// Listar recibos + /// + /// Regresa una lista paginada de todos los recibos de una organización o realiza una búsqueda de acuerdo a parámetros + /// + /// Parámetros de consulta. Admite ReceiptListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> ListAsync(ReceiptListParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"receipts", query, null, false, cancellationToken); + } + + /// + /// Obtener recibo por ID + /// + /// Regresa el objeto 'Receipt' relacionado al `id` especificado. + /// + /// ID del objeto a obtener + /// Permite cancelar la solicitud. + /// Objeto `Receipt` + /// + public Task RetrieveAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"receipts/{Uri.EscapeDataString(id)}", null, null, false, cancellationToken); + } + + /// + /// Facturar recibo + /// + /// Crea una factura a partir de un recibo. + /// + /// Sólo pueden facturarse recibos abiertos (`status = "open"`) + /// + /// Si envías `customer`, ese cliente se usará como receptor de la factura y + /// sobrescribirá el cliente asignado al recibo. Si omites `customer`, el + /// recibo debe tener un cliente asignado previamente. + /// + /// Una vez facturado, el `status` del recibo cambiará a `"invoiced_to_customer"`. + /// + /// + /// ID del recibo a facturar + /// Datos de la solicitud. Admite InvoiceReceiptInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado + /// + public Task InvoiceAsync(string id, JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"receipts/{Uri.EscapeDataString(id)}/invoice", null, data, true, cancellationToken); + } + + /// + /// Facturar recibo + /// + /// Crea una factura a partir de un recibo. + /// + /// Sólo pueden facturarse recibos abiertos (`status = "open"`) + /// + /// Si envías `customer`, ese cliente se usará como receptor de la factura y + /// sobrescribirá el cliente asignado al recibo. Si omites `customer`, el + /// recibo debe tener un cliente asignado previamente. + /// + /// Una vez facturado, el `status` del recibo cambiará a `"invoiced_to_customer"`. + /// + /// + /// ID del recibo a facturar + /// Datos de la solicitud. Admite InvoiceReceiptInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado + /// + public Task InvoiceAsync(string id, InvoiceReceiptInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"receipts/{Uri.EscapeDataString(id)}/invoice", null, data, true, cancellationToken); + } + + /// + /// Crear factura global + /// + /// Crea una factura global que incluirá todos los recibos con `status = “open”` de un cierto periodo. + /// + /// La factura global se emite al cliente genérico `PUBLICO EN GENERAL`. + /// Los recibos incluidos quedan asociados a ese cliente y su `status` + /// cambia a `"invoiced_globally"`. + /// + /// Una factura global puede incluir hasta 5,000 recibos abiertos. Si el periodo + /// contiene más, puedes enviar `limit_to_max_receipts: true` y repetir la solicitud + /// con el mismo periodo hasta recibir `null`. + /// + /// + /// Datos de la solicitud. Admite GlobalInvoiceInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado, o `null` si no hay recibos abiertos en el periodo + /// + public Task CreateGlobalInvoiceAsync(JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"receipts/global-invoice", null, data, true, cancellationToken); + } + + /// + /// Crear factura global + /// + /// Crea una factura global que incluirá todos los recibos con `status = “open”` de un cierto periodo. + /// + /// La factura global se emite al cliente genérico `PUBLICO EN GENERAL`. + /// Los recibos incluidos quedan asociados a ese cliente y su `status` + /// cambia a `"invoiced_globally"`. + /// + /// Una factura global puede incluir hasta 5,000 recibos abiertos. Si el periodo + /// contiene más, puedes enviar `limit_to_max_receipts: true` y repetir la solicitud + /// con el mismo periodo hasta recibir `null`. + /// + /// + /// Datos de la solicitud. Admite GlobalInvoiceInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Invoice` creado, o `null` si no hay recibos abiertos en el periodo + /// + public Task CreateGlobalInvoiceAsync(GlobalInvoiceInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"receipts/global-invoice", null, data, true, cancellationToken); + } + + /// + /// Facturar múltiples recibos + /// + /// Crea una sola factura a partir de múltiples recibos seleccionados por su `key`. + /// + /// Si envías `customer`, ese cliente se usará como receptor de la factura y + /// sobrescribirá el cliente asignado a los recibos incluidos. Si omites + /// `customer`, todos los recibos deben tener asignado el mismo cliente. + /// También se validará el campo `address` de los recibos incluidos. + /// + /// Si `dry_run` es `true`, no crea la factura y regresa un resumen de vista previa. + /// El `dry_run` valida las mismas reglas que la creación real, pero no persiste cambios. + /// + /// + /// Datos de la solicitud. Admite ToInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto `Invoice` creado u objeto resumen cuando `dry_run=true` + /// + public Task ToInvoiceAsync(JsonObject data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"receipts/to-invoice", null, data, true, cancellationToken); + } + + /// + /// Facturar múltiples recibos + /// + /// Crea una sola factura a partir de múltiples recibos seleccionados por su `key`. + /// + /// Si envías `customer`, ese cliente se usará como receptor de la factura y + /// sobrescribirá el cliente asignado a los recibos incluidos. Si omites + /// `customer`, todos los recibos deben tener asignado el mismo cliente. + /// También se validará el campo `address` de los recibos incluidos. + /// + /// Si `dry_run` es `true`, no crea la factura y regresa un resumen de vista previa. + /// El `dry_run` valida las mismas reglas que la creación real, pero no persiste cambios. + /// + /// + /// Datos de la solicitud. Admite ToInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto `Invoice` creado u objeto resumen cuando `dry_run=true` + /// + public Task ToInvoiceAsync(ToInvoiceInput data, CancellationToken cancellationToken = default) { + return RequestAsync(HttpMethod.Post, $"receipts/to-invoice", null, data, true, cancellationToken); } - public async Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Vista previa PDF de factura múltiple + /// + /// Genera una vista previa en PDF para una factura construida a partir de múltiples recibos seleccionados por `key`. + /// + /// La vista previa valida las mismas reglas de cliente que la creación real: + /// si omites `customer`, todos los recibos deben tener asignado el mismo cliente. + /// + /// + /// Datos de la solicitud. Admite ToInvoicePreviewInput. + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// + public Task PreviewToInvoicePdfAsync(JsonObject data, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.ListReceipts(query), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + return RequestAsync(HttpMethod.Post, $"receipts/to-invoice/preview", null, data, true, cancellationToken); + } - var searchResult = JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - return searchResult; - } + /// + /// Vista previa PDF de factura múltiple + /// + /// Genera una vista previa en PDF para una factura construida a partir de múltiples recibos seleccionados por `key`. + /// + /// La vista previa valida las mismas reglas de cliente que la creación real: + /// si omites `customer`, todos los recibos deben tener asignado el mismo cliente. + /// + /// + /// Datos de la solicitud. Admite ToInvoicePreviewInput. + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// + public Task PreviewToInvoicePdfAsync(ToInvoicePreviewInput data, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"receipts/to-invoice/preview", null, data, true, cancellationToken); } - public async Task CreateAsync(Dictionary data, CancellationToken cancellationToken = default) + /// + /// Obtener URL del preview de factura de recibos + /// + /// Devuelve un objeto con los metadatos del archivo y una URL temporal para el preview PDF de una factura construida con los recibos seleccionados. + /// + /// Datos de la solicitud. Admite ToInvoicePreviewInput. + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + public Task PreviewToInvoicePdfUrlAsync(JsonObject data, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.CreateReceipt(), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var customer = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return customer; - } + return RequestAsync(HttpMethod.Post, $"receipts/to-invoice/preview/download-url", null, data, true, cancellationToken); } - public async Task RetrieveAsync(string id, CancellationToken cancellationToken = default) + /// + /// Obtener URL del preview de factura de recibos + /// + /// Devuelve un objeto con los metadatos del archivo y una URL temporal para el preview PDF de una factura construida con los recibos seleccionados. + /// + /// Datos de la solicitud. Admite ToInvoicePreviewInput. + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + public Task PreviewToInvoicePdfUrlAsync(ToInvoicePreviewInput data, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.RetrieveReceipt(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var customer = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return customer; - } + return RequestAsync(HttpMethod.Post, $"receipts/to-invoice/preview/download-url", null, data, true, cancellationToken); } - public async Task CancelAsync(string id, CancellationToken cancellationToken = default) + /// + /// Cancelar recibo + /// + /// Marca un recibo como cancelado, cambiando su propiedad `status` a `"canceled"`. + /// + /// Una vez cancelado, el recibo no podrá ser facturado. + /// + /// + /// ID del recibo a cancelar + /// Permite cancelar la solicitud. + /// Objeto 'Receipt' cancelado exitosamente + /// + public Task CancelAsync(string id, CancellationToken cancellationToken = default) { - using (var response = await client.DeleteAsync(Router.CancelReceipt(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var customer = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return customer; - } + return RequestAsync(HttpMethod.Delete, $"receipts/{Uri.EscapeDataString(id)}", null, null, false, cancellationToken); } - public async Task InvoiceAsync(string id, Dictionary data, CancellationToken cancellationToken = default) + /// + /// Enviar recibo por correo electrónico + /// + /// Envía un correo electrónico a la dirección de tu cliente. + /// + /// El correo enviado estará personalizado con el logotipo y los colores de la organización que lo creó, + /// e incluirá un botón para facturar el recibo, así con el recibo en formato PDF adjunto al mensaje. + /// + /// + /// ID del objeto a obtener + /// Datos de la solicitud. Admite SendReceiptByEmailInput. + /// Permite cancelar la solicitud. + /// Objeto genérico de respuesta + /// + public Task SendByEmailAsync(string id, JsonObject? data = null, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.InvoiceReceipt(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - } + return RequestAsync(HttpMethod.Post, $"receipts/{Uri.EscapeDataString(id)}/email", null, data, true, cancellationToken); } - public async Task CreateGlobalInvoiceAsync(Dictionary data, CancellationToken cancellationToken = default) + /// + /// Enviar recibo por correo electrónico + /// + /// Envía un correo electrónico a la dirección de tu cliente. + /// + /// El correo enviado estará personalizado con el logotipo y los colores de la organización que lo creó, + /// e incluirá un botón para facturar el recibo, así con el recibo en formato PDF adjunto al mensaje. + /// + /// + /// ID del objeto a obtener + /// Datos de la solicitud. Admite SendReceiptByEmailInput. + /// Permite cancelar la solicitud. + /// Objeto genérico de respuesta + /// + public Task SendByEmailAsync(string id, SendReceiptByEmailInput data, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.CreateGlobalInvoice(), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - } + return RequestAsync(HttpMethod.Post, $"receipts/{Uri.EscapeDataString(id)}/email", null, data, true, cancellationToken); } - public async Task ToInvoiceAsync(Dictionary data, CancellationToken cancellationToken = default) + /// + /// Descargar PDF + /// + /// Descarga el recibo digital en formato PDF. + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// + public Task DownloadPdfAsync(string id, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.ToInvoice(), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - } + return RequestAsync(HttpMethod.Get, $"receipts/{Uri.EscapeDataString(id)}/pdf", null, null, false, cancellationToken); } - public async Task PreviewToInvoicePdfAsync(Dictionary data, CancellationToken cancellationToken = default) + /// + /// Obtener enlace de descarga + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar el recibo digital en PDF, sin que el archivo pase por tu servidor. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + public Task DownloadPdfUrlAsync(string id, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.PreviewToInvoicePdf(), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); - var memory = new MemoryStream(); - await responseStream.CopyToAsync(memory, 81920, cancellationToken).ConfigureAwait(false); - memory.Position = 0; - return memory; - } + return RequestAsync(HttpMethod.Get, $"receipts/{Uri.EscapeDataString(id)}/download-url/pdf", null, null, false, cancellationToken); } - public async Task SendByEmailAsync(string id, Dictionary data = null, CancellationToken cancellationToken = default) + /// + /// Asignar o reasignar cliente a recibo + /// + /// Asigna o reasigna un cliente existente (por ID) a un recibo, o crea uno nuevo enviando el objeto del cliente. + /// + /// + /// ID del recibo a actualizar + /// Datos de la solicitud. Admite ReceiptAssignCustomerInput. + /// Permite cancelar la solicitud. + /// Objeto `Receipt` actualizado + /// + public Task UpdateCustomerAsync(string id, JsonObject data, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.SendReceiptByEmail(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - } + return RequestAsync(HttpMethod.Put, $"receipts/{Uri.EscapeDataString(id)}", null, data, true, cancellationToken); } - public async Task DownloadPdfAsync(string id, CancellationToken cancellationToken = default) + /// + /// Asignar o reasignar cliente a recibo + /// + /// Asigna o reasigna un cliente existente (por ID) a un recibo, o crea uno nuevo enviando el objeto del cliente. + /// + /// + /// ID del recibo a actualizar + /// Datos de la solicitud. Admite ReceiptAssignCustomerInput. + /// Permite cancelar la solicitud. + /// Objeto `Receipt` actualizado + /// + public Task UpdateCustomerAsync(string id, ReceiptAssignCustomerInput data, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.DownloadReceiptPdf(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); - var memory = new MemoryStream(); - await responseStream.CopyToAsync(memory, 81920, cancellationToken).ConfigureAwait(false); - memory.Position = 0; - return memory; - } + return RequestAsync(HttpMethod.Put, $"receipts/{Uri.EscapeDataString(id)}", null, data, true, cancellationToken); } + + /// + /// Facturar múltiples recibos + /// + /// Crea una sola factura a partir de múltiples recibos seleccionados por su `key`. + /// + /// Si envías `customer`, ese cliente se usará como receptor de la factura y + /// sobrescribirá el cliente asignado a los recibos incluidos. Si omites + /// `customer`, todos los recibos deben tener asignado el mismo cliente. + /// También se validará el campo `address` de los recibos incluidos. + /// + /// Si `dry_run` es `true`, no crea la factura y regresa un resumen de vista previa. + /// El `dry_run` valida las mismas reglas que la creación real, pero no persiste cambios. + /// + /// + /// Datos de la solicitud. Admite ToInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto `Invoice` creado u objeto resumen cuando `dry_run=true` + /// + public Task SummarizeToInvoiceAsync(JsonObject data, CancellationToken cancellationToken = default) + { + var requestBody = new Dictionary(data); + requestBody["dry_run"] = true; + return RequestAsync(HttpMethod.Post, $"receipts/to-invoice", null, requestBody, true, cancellationToken); + } + + /// + /// Facturar múltiples recibos + /// + /// Crea una sola factura a partir de múltiples recibos seleccionados por su `key`. + /// + /// Si envías `customer`, ese cliente se usará como receptor de la factura y + /// sobrescribirá el cliente asignado a los recibos incluidos. Si omites + /// `customer`, todos los recibos deben tener asignado el mismo cliente. + /// También se validará el campo `address` de los recibos incluidos. + /// + /// Si `dry_run` es `true`, no crea la factura y regresa un resumen de vista previa. + /// El `dry_run` valida las mismas reglas que la creación real, pero no persiste cambios. + /// + /// + /// Datos de la solicitud. Admite ToInvoiceInput. + /// Permite cancelar la solicitud. + /// Objeto `Invoice` creado u objeto resumen cuando `dry_run=true` + /// + public Task SummarizeToInvoiceAsync(ToInvoiceInput data, CancellationToken cancellationToken = default) + { + var requestBody = new Dictionary(data); + requestBody["dry_run"] = true; + return RequestAsync(HttpMethod.Post, $"receipts/to-invoice", null, requestBody, true, cancellationToken); + } + } } diff --git a/Wrappers/RetentionWrapper.cs b/Wrappers/RetentionWrapper.cs index 157f0c9..7ecdec9 100644 --- a/Wrappers/RetentionWrapper.cs +++ b/Wrappers/RetentionWrapper.cs @@ -1,136 +1,349 @@ -using Newtonsoft.Json; -using System.Collections.Generic; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; using System.IO; +using System.Collections.Generic; using System.Net.Http; -using System.Text; -using System.Threading.Tasks; using System.Threading; +using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public class RetentionWrapper : BaseWrapper, IRetentionWrapper + /// + /// Operaciones de Retention. + /// + public partial class RetentionWrapper : BaseWrapper, IRetentionWrapper { - internal RetentionWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) + internal RetentionWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) {} + + /// + /// Crear retención + /// + /// Crea una nueva Retención. Si el comprobante es creado en ambiente Live, ésta será **timbrado y enviado al SAT**. + /// + /// Para crear una retención en borrador, envía `status: "draft"`. En ese caso, + /// la retención se guardará sin timbrarse, no se enviará al PAC y podrá estar + /// incompleta. Facturapi asignará `is_ready_to_stamp: true` únicamente cuando + /// el borrador tenga todos los datos requeridos para timbrarse. + /// + /// + /// Datos de la solicitud. Admite RetentionInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Retention` creado + /// + public Task CreateAsync(JsonObject data, CancellationToken cancellationToken = default) { + return RequestAsync(HttpMethod.Post, $"retentions", null, data, true, cancellationToken); } - public async Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Crear retención + /// + /// Crea una nueva Retención. Si el comprobante es creado en ambiente Live, ésta será **timbrado y enviado al SAT**. + /// + /// Para crear una retención en borrador, envía `status: "draft"`. En ese caso, + /// la retención se guardará sin timbrarse, no se enviará al PAC y podrá estar + /// incompleta. Facturapi asignará `is_ready_to_stamp: true` únicamente cuando + /// el borrador tenga todos los datos requeridos para timbrarse. + /// + /// + /// Datos de la solicitud. Admite RetentionInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Retention` creado + /// + public Task CreateAsync(RetentionInput data, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.ListRetentions(query), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + return RequestAsync(HttpMethod.Post, $"retentions", null, data, true, cancellationToken); + } - var searchResult = JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - return searchResult; - } + /// + /// Listar retenciones + /// + /// Regresa una lista paginada de todas las retenciones de una organización o realiza una búsqueda de acuerdo a parámetros + /// + /// Parámetros de consulta. Admite RetentionListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> ListAsync(JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"retentions", query, null, false, cancellationToken); } - public async Task CreateAsync(Dictionary data, CancellationToken cancellationToken = default) + /// + /// Listar retenciones + /// + /// Regresa una lista paginada de todas las retenciones de una organización o realiza una búsqueda de acuerdo a parámetros + /// + /// Parámetros de consulta. Admite RetentionListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> ListAsync(RetentionListParams? query, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.CreateRetention(), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var customer = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return customer; - } + return RequestAsync>(HttpMethod.Get, $"retentions", query, null, false, cancellationToken); } - public async Task RetrieveAsync(string id, CancellationToken cancellationToken = default) + /// + /// Obtener retención por ID + /// + /// Regresa el objeto 'Retention' relacionado al `id` especificado. + /// + /// ID del objeto a obtener + /// Permite cancelar la solicitud. + /// Objeto `Retention` + /// + public Task RetrieveAsync(string id, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.RetrieveRetention(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var customer = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return customer; - } + return RequestAsync(HttpMethod.Get, $"retentions/{Uri.EscapeDataString(id)}", null, null, false, cancellationToken); } - public async Task CancelAsync(string id, Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Cancelar retención + /// + /// Realiza una solicitud de cancelación de retención ante el SAT. + /// + /// A diferencia de las facturas comunes, la cancelación de la retención es inmediata y no requiere autorización de parte del receptor. + /// + /// Si el status de la retención es `draft`, este método la eliminará de la + /// base de datos sin llamar al SAT/PAC y sin requerir parámetros de cancelación. + /// + /// + /// ID de la retención a cancelar + /// Parámetros de consulta. Admite CancellationQueryInput. + /// Permite cancelar la solicitud. + /// Objeto `Retention` cancelado exitosamente + /// + public Task CancelAsync(string id, JsonObject? query = null, CancellationToken cancellationToken = default) { - using (var response = await client.DeleteAsync(Router.CancelRetention(id, query), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var responseString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var retention = JsonConvert.DeserializeObject(responseString, this.jsonSettings); - return retention; - } + return RequestAsync(HttpMethod.Delete, $"retentions/{Uri.EscapeDataString(id)}", query, null, false, cancellationToken); } - public async Task SendByEmailAsync(string id, Dictionary data = null, CancellationToken cancellationToken = default) + /// + /// Cancelar retención + /// + /// Realiza una solicitud de cancelación de retención ante el SAT. + /// + /// A diferencia de las facturas comunes, la cancelación de la retención es inmediata y no requiere autorización de parte del receptor. + /// + /// Si el status de la retención es `draft`, este método la eliminará de la + /// base de datos sin llamar al SAT/PAC y sin requerir parámetros de cancelación. + /// + /// + /// ID de la retención a cancelar + /// Parámetros de consulta. Admite CancellationQueryInput. + /// Permite cancelar la solicitud. + /// Objeto `Retention` cancelado exitosamente + /// + public Task CancelAsync(string id, CancellationQueryInput? query, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.SendRetentionByEmail(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - } + return RequestAsync(HttpMethod.Delete, $"retentions/{Uri.EscapeDataString(id)}", query, null, false, cancellationToken); } - public async Task UpdateDraftAsync(string id, Dictionary data, CancellationToken cancellationToken = default) + /// + /// Editar borrador de retención + /// + /// Actualiza la información de una retención con status `draft`, asignando + /// los valores de los parámetros enviados. Los parámetros que no se envíen + /// en la petición no se modificarán. + /// + /// Facturapi recalculará automáticamente `is_ready_to_stamp` después de cada + /// edición. Si la retención ya no está en status `draft`, la llamada regresará + /// un error. + /// + /// + /// ID de la retención a editar + /// Datos de la solicitud. Admite RetentionUpdateInput. + /// Permite cancelar la solicitud. + /// Objeto `Retention` editado correctamente + /// + public Task UpdateDraftAsync(string id, JsonObject data, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PutAsync(Router.UpdateDraftRetention(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var retention = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return retention; - } + return RequestAsync(HttpMethod.Put, $"retentions/{Uri.EscapeDataString(id)}", null, data, true, cancellationToken); } - public async Task StampDraftAsync(string id, Dictionary options = null, CancellationToken cancellationToken = default) + /// + /// Editar borrador de retención + /// + /// Actualiza la información de una retención con status `draft`, asignando + /// los valores de los parámetros enviados. Los parámetros que no se envíen + /// en la petición no se modificarán. + /// + /// Facturapi recalculará automáticamente `is_ready_to_stamp` después de cada + /// edición. Si la retención ya no está en status `draft`, la llamada regresará + /// un error. + /// + /// + /// ID de la retención a editar + /// Datos de la solicitud. Admite RetentionUpdateInput. + /// Permite cancelar la solicitud. + /// Objeto `Retention` editado correctamente + /// + public Task UpdateDraftAsync(string id, RetentionUpdateInput data, CancellationToken cancellationToken = default) { - using (var content = new StringContent("", Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.StampDraftRetention(id, options), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var retention = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return retention; - } + return RequestAsync(HttpMethod.Put, $"retentions/{Uri.EscapeDataString(id)}", null, data, true, cancellationToken); } - public async Task CopyToDraftAsync(string id, CancellationToken cancellationToken = default) + /// + /// Timbrar borrador de retención + /// + /// Timbra una retención con status `draft` y la envía al SAT para su validación. + /// + /// Facturapi validará el borrador como una retención completa antes de timbrarlo. + /// Si el borrador está incompleto o no es válido, la llamada regresará un error. + /// + /// + /// ID de la retención a timbrar + /// options + /// Permite cancelar la solicitud. + /// Objeto `Retention` timbrado correctamente + /// + public Task StampDraftAsync(string id, JsonObject? options = null, CancellationToken cancellationToken = default) { - using (var content = new StringContent("", Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.CopyRetention(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var retention = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return retention; - } + return RequestAsync(HttpMethod.Post, $"retentions/{Uri.EscapeDataString(id)}/stamp", null, null, false, cancellationToken); } - private async Task DownloadAsync(string id, string format, CancellationToken cancellationToken) + /// + /// Copiar a borrador + /// + /// Crea una copia en borrador de la retención especificada. La copia no conserva + /// campos propios del timbrado, cancelación, idempotencia o identidad externa. + /// + /// + /// ID de la retención a copiar + /// Permite cancelar la solicitud. + /// Nuevo objeto `Retention` con status `draft`. + /// + public Task CopyToDraftAsync(string id, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.DownloadRetention(id, format), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); - var memory = new MemoryStream(); - await responseStream.CopyToAsync(memory, 81920, cancellationToken).ConfigureAwait(false); - memory.Position = 0; - return memory; - } + return RequestAsync(HttpMethod.Post, $"retentions/{Uri.EscapeDataString(id)}/copy", null, null, false, cancellationToken); } - public Task DownloadZipAsync(string id, CancellationToken cancellationToken = default) + /// + /// Enviar retención por correo electrónico + /// + /// Envía un correo electrónico a la dirección de tu cliente, con los archivos XML y PDF adjuntos al mensaje. + /// + /// ID del objeto a obtener + /// Datos de la solicitud. Admite SendRetentionByEmailInput. + /// Permite cancelar la solicitud. + /// Objeto genérico de respuesta + /// + public Task SendByEmailAsync(string id, JsonObject? data = null, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Post, $"retentions/{Uri.EscapeDataString(id)}/email", null, data, true, cancellationToken); + } + + /// + /// Enviar retención por correo electrónico + /// + /// Envía un correo electrónico a la dirección de tu cliente, con los archivos XML y PDF adjuntos al mensaje. + /// + /// ID del objeto a obtener + /// Datos de la solicitud. Admite SendRetentionByEmailInput. + /// Permite cancelar la solicitud. + /// Objeto genérico de respuesta + /// + public Task SendByEmailAsync(string id, SendRetentionByEmailInput data, CancellationToken cancellationToken = default) { - return this.DownloadAsync(id, "zip", cancellationToken); + return RequestAsync(HttpMethod.Post, $"retentions/{Uri.EscapeDataString(id)}/email", null, data, true, cancellationToken); } + /// + /// Descargar retención + /// + /// Descarga una retención en PDF, XML o ambos en un archivo comprimido ZIP. + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// public Task DownloadPdfAsync(string id, CancellationToken cancellationToken = default) { - return this.DownloadAsync(id, "pdf", cancellationToken); + return RequestAsync(HttpMethod.Get, $"retentions/{Uri.EscapeDataString(id)}/pdf", null, null, false, cancellationToken); } + /// + /// Descargar retención + /// + /// Descarga una retención en PDF, XML o ambos en un archivo comprimido ZIP. + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// public Task DownloadXmlAsync(string id, CancellationToken cancellationToken = default) { - return this.DownloadAsync(id, "xml", cancellationToken); + return RequestAsync(HttpMethod.Get, $"retentions/{Uri.EscapeDataString(id)}/xml", null, null, false, cancellationToken); } + + /// + /// Descargar retención + /// + /// Descarga una retención en PDF, XML o ambos en un archivo comprimido ZIP. + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar. + /// + public Task DownloadZipAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"retentions/{Uri.EscapeDataString(id)}/zip", null, null, false, cancellationToken); + } + + /// + /// Obtener enlace de descarga + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar la retención en PDF, XML o ambos en un archivo comprimido ZIP, sin que el archivo pase por tu servidor. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + public Task DownloadPdfUrlAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"retentions/{Uri.EscapeDataString(id)}/download-url/pdf", null, null, false, cancellationToken); + } + + /// + /// Obtener enlace de descarga + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar la retención en PDF, XML o ambos en un archivo comprimido ZIP, sin que el archivo pase por tu servidor. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + public Task DownloadXmlUrlAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"retentions/{Uri.EscapeDataString(id)}/download-url/xml", null, null, false, cancellationToken); + } + + /// + /// Obtener enlace de descarga + /// + /// Devuelve un objeto con los metadatos del archivo y un enlace temporal para descargar la retención en PDF, XML o ambos en un archivo comprimido ZIP, sin que el archivo pase por tu servidor. + /// + /// El enlace da acceso a ese archivo mientras siga vigente: trátalo como una credencial y no lo almacenes. + /// + /// + /// ID del objeto a descargar + /// Permite cancelar la solicitud. + /// Objeto con una URL temporal de descarga, su fecha de expiración, el tipo de contenido y el nombre del archivo. + /// + public Task DownloadZipUrlAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"retentions/{Uri.EscapeDataString(id)}/download-url/zip", null, null, false, cancellationToken); + } + } } diff --git a/Wrappers/ToolWrapper.cs b/Wrappers/ToolWrapper.cs index cf3eb2c..ffbf52d 100644 --- a/Wrappers/ToolWrapper.cs +++ b/Wrappers/ToolWrapper.cs @@ -1,54 +1,63 @@ -using Newtonsoft.Json; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; using System.Net.Http; -using System.Threading.Tasks; using System.Threading; +using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public class ToolWrapper : BaseWrapper, IToolWrapper + /// + /// Operaciones de Tool. + /// + public partial class ToolWrapper : BaseWrapper, IToolWrapper { - internal ToolWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) - { - } + internal ToolWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) {} - public async Task ValidateTaxIdAsync(string taxId, CancellationToken cancellationToken = default) + /// + /// Validar RFC + /// + /// Consulta el estado de un RFC en la lista de **EFOS** (Empresas que + /// Facturan Operaciones Simuladas). Al aparecer en esta lista, el RFC es o + /// fue sospechoso de incurrir en simulación de operaciones fiscales + /// (empresas factureras). + /// + /// La respuesta (detallada más abajo) incluye los resultados de esta + /// validación. Se incluye la propiedad + /// booleana `is_valid`, que Facturapi resuelve interpretando la respuesta. + /// Un valor de `true` para esta propiedad indica que el RFC no tiene asuntos + /// por resolver y está libre de problemas; y lo contrario para `false`. + /// + /// Adicionalmente puedes consultar la propiedad data para ver los valores + /// en bruto de la consulta al SAT. + /// + /// + /// taxId + /// Permite cancelar la solicitud. + /// Resultado de la validación + /// + public Task ValidateTaxIdAsync(string taxId, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.ValidateTaxId( - new Dictionary() - { - ["tax_id"] = taxId - } - ), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - - var result = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return result; - } + return RequestAsync(HttpMethod.Get, $"tools/tax_id_validation", new Dictionary { ["tax_id"] = taxId }, null, false, cancellationToken); } + /// + /// Health check (Pulso) + /// + /// Comprueba que la API está disponible. Este endpoint requiere una llave secreta de API. + /// + /// Permite cancelar la solicitud. + /// La API está operando con normalidad. + /// public async Task HealthCheckAsync(CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.HealthCheck(), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var result = JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - if (result != null && result.TryGetValue("ok", out var okValue)) - { - if (okValue is bool okBool) - { - return okBool; - } - if (bool.TryParse(okValue.ToString(), out var parsed)) - { - return parsed; - } - } - return false; - } + return (await RequestAsync(HttpMethod.Get, $"check", null, null, false, cancellationToken).ConfigureAwait(false)).Ok == true; } + } } diff --git a/Wrappers/WebhookWrapper.Signatures.cs b/Wrappers/WebhookWrapper.Signatures.cs new file mode 100644 index 0000000..b3db496 --- /dev/null +++ b/Wrappers/WebhookWrapper.Signatures.cs @@ -0,0 +1,55 @@ +#nullable enable +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Security.Cryptography; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Facturapi.Wrappers +{ + public partial interface IWebhookWrapper + { + /// Verifica localmente la firma HMAC SHA-256 y devuelve el evento. Prefiere el payload JSON original. + Task ValidateSignatureAsync(Dictionary data, CancellationToken cancellationToken = default); + /// Verifica los bytes UTF-8 del payload JSON original, sin realizar solicitudes HTTP. + Task ValidateSignatureAsync(string secret, string signature, string payload, CancellationToken cancellationToken = default); + } + + public partial class WebhookWrapper + { + /// Verifica localmente una firma. El diccionario debe incluir secret, signature y payload. + public Task ValidateSignatureAsync(Dictionary data, CancellationToken cancellationToken = default) + { + if (data == null) throw new ArgumentNullException(nameof(data)); + if (!data.TryGetValue("secret", out var secret) || !(secret is string secretText)) throw new ArgumentException("A webhook secret is required.", nameof(data)); + if (!data.TryGetValue("signature", out var signature) || !(signature is string signatureText)) throw new ArgumentException("A webhook signature is required.", nameof(data)); + if (!data.TryGetValue("payload", out var payload) || payload == null) throw new ArgumentException("A webhook payload is required.", nameof(data)); + return ValidateSignatureAsync(secretText, signatureText, payload is string json ? json : JsonConvert.SerializeObject(payload), cancellationToken); + } + + /// Verifica la firma hexadecimal en tiempo constante y devuelve el evento firmado. + public Task ValidateSignatureAsync(string secret, string signature, string payload, CancellationToken cancellationToken = default) + { + cancellationToken.ThrowIfCancellationRequested(); + if (secret == null) throw new ArgumentNullException(nameof(secret)); + if (payload == null) throw new ArgumentNullException(nameof(payload)); + if (signature == null || signature.Length != 64) throw new ArgumentException("Invalid webhook signature.", nameof(signature)); + using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret))) + { + var digest = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload)); + var difference = 0; + for (var index = 0; index < digest.Length; index++) + { + byte supplied; + try { supplied = Convert.ToByte(signature.Substring(index * 2, 2), 16); } + catch (FormatException exception) { throw new ArgumentException("Invalid webhook signature.", nameof(signature), exception); } + difference |= digest[index] ^ supplied; + } + if (difference != 0) throw new ArgumentException("Invalid webhook signature.", nameof(signature)); + } + return Task.FromResult(JsonConvert.DeserializeObject(payload, jsonSettings) ?? throw new JsonSerializationException("Invalid webhook event JSON.")); + } + } +} diff --git a/Wrappers/WebhookWrapper.cs b/Wrappers/WebhookWrapper.cs index 94f5776..aa64038 100644 --- a/Wrappers/WebhookWrapper.cs +++ b/Wrappers/WebhookWrapper.cs @@ -1,86 +1,176 @@ -using Newtonsoft.Json; +// Generated by pnpm generate:sdk. Do not edit directly. +#nullable enable +using System; +using System.IO; using System.Collections.Generic; using System.Net.Http; -using System.Text; -using System.Threading.Tasks; using System.Threading; +using System.Threading.Tasks; +#nullable disable +using JsonObject = System.Collections.Generic.Dictionary; +#nullable enable namespace Facturapi.Wrappers { - public class WebhookWrapper : BaseWrapper, IWebhookWrapper + /// + /// Operaciones de Webhook. + /// + public partial class WebhookWrapper : BaseWrapper, IWebhookWrapper { - internal WebhookWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) + internal WebhookWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) {} + + /// + /// Crear Webhook + /// + /// Registra un nuevo webhook en tu organización de Facturapi. + /// Utiliza esta llamada para recibir notificaciones de eventos asíncronos a la API. + /// Los webhooks de ambiente test y ambiente live son independientes. + /// + /// + /// Datos de la solicitud. Admite WebhookCreateInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Webhook` creado + /// + public Task CreateAsync(JsonObject data, CancellationToken cancellationToken = default) { + return RequestAsync(HttpMethod.Post, $"webhooks", null, data, true, cancellationToken); } - public async Task> ListAsync(Dictionary query = null, CancellationToken cancellationToken = default) + /// + /// Crear Webhook + /// + /// Registra un nuevo webhook en tu organización de Facturapi. + /// Utiliza esta llamada para recibir notificaciones de eventos asíncronos a la API. + /// Los webhooks de ambiente test y ambiente live son independientes. + /// + /// + /// Datos de la solicitud. Admite WebhookCreateInput. + /// Permite cancelar la solicitud. + /// Nuevo objeto `Webhook` creado + /// + public Task CreateAsync(WebhookCreateInput data, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.ListWebhooks(query), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + return RequestAsync(HttpMethod.Post, $"webhooks", null, data, true, cancellationToken); + } - var searchResult = JsonConvert.DeserializeObject>(resultString, this.jsonSettings); - return searchResult; - } + /// + /// Listar webhooks + /// + /// Retorna una lista de webhooks creados previamente para la organización. + /// + /// Parámetros de consulta. Admite WebhookListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> ListAsync(JsonObject? query = null, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"webhooks", query, null, false, cancellationToken); + } + + /// + /// Listar webhooks + /// + /// Retorna una lista de webhooks creados previamente para la organización. + /// + /// Parámetros de consulta. Admite WebhookListParams. + /// Permite cancelar la solicitud. + /// Resultado de la búsqueda + /// + public Task> ListAsync(WebhookListParams? query, CancellationToken cancellationToken = default) + { + return RequestAsync>(HttpMethod.Get, $"webhooks", query, null, false, cancellationToken); + } + + /// + /// Obtener webhook por ID + /// + /// Regresa el objeto "Webhook" relacionado al `id` especificado. + /// + /// ID del objeto a obtener + /// Permite cancelar la solicitud. + /// Objeto `Webhook` + /// + public Task RetrieveAsync(string id, CancellationToken cancellationToken = default) + { + return RequestAsync(HttpMethod.Get, $"webhooks/{Uri.EscapeDataString(id)}", null, null, false, cancellationToken); } - public async Task CreateAsync(Dictionary data, CancellationToken cancellationToken = default) + /// + /// Editar webhook + /// + /// Actualiza la información de un Webhook existente con los parámetros que envíes en la petición. + /// + /// ID del objeto a editar + /// Datos de la solicitud. Admite WebhookUpdateInput. + /// Permite cancelar la solicitud. + /// Objeto `Webhook` editado correctamente + /// + public Task UpdateAsync(string id, JsonObject data, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.CreateWebhook(), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var webhook = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return webhook; - } + return RequestAsync(HttpMethod.Put, $"webhooks/{Uri.EscapeDataString(id)}", null, data, true, cancellationToken); } - public async Task RetrieveAsync(string id, CancellationToken cancellationToken = default) + /// + /// Editar webhook + /// + /// Actualiza la información de un Webhook existente con los parámetros que envíes en la petición. + /// + /// ID del objeto a editar + /// Datos de la solicitud. Admite WebhookUpdateInput. + /// Permite cancelar la solicitud. + /// Objeto `Webhook` editado correctamente + /// + public Task UpdateAsync(string id, WebhookUpdateInput data, CancellationToken cancellationToken = default) { - using (var response = await client.GetAsync(Router.RetrieveWebhook(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var webhook = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return webhook; - } + return RequestAsync(HttpMethod.Put, $"webhooks/{Uri.EscapeDataString(id)}", null, data, true, cancellationToken); } - public async Task UpdateAsync(string id, Dictionary data, CancellationToken cancellationToken = default) + /// + /// Eliminar Webhook + /// + /// Elimina el webhook perteneciente a la organización. + /// + /// ID del objeto a eliminar + /// Permite cancelar la solicitud. + /// Objeto `Webhook` eliminado correctamente + /// + public Task DeleteAsync(string id, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PutAsync(Router.UpdateWebhook(id), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var webhook = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return webhook; - } + return RequestAsync(HttpMethod.Delete, $"webhooks/{Uri.EscapeDataString(id)}", null, null, false, cancellationToken); } - public async Task DeleteAsync(string id, CancellationToken cancellationToken = default) + /// + /// Validar evento de webhook + /// + /// Valida la firma de un evento recibido mediante un Webhook. + /// Utiliza esta operación para verificar la autenticidad e integridad de + /// un evento recibido, comparando la firma recibida con la generada por Facturapi. + /// + /// + /// Datos de la solicitud. Admite ValidateWebhookSignatureInput. + /// Permite cancelar la solicitud. + /// Payload original con firma válida + /// + public Task>> ValidateSignatureRemotelyAsync(JsonObject data, CancellationToken cancellationToken = default) { - using (var response = await client.DeleteAsync(Router.DeleteWebhook(id), cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var webhook = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return webhook; - } + return RequestAsync>>(HttpMethod.Post, $"webhooks/validate-signature", null, data, true, cancellationToken); } - public async Task ValidateSignatureAsync(Dictionary data, CancellationToken cancellationToken = default) + /// + /// Validar evento de webhook + /// + /// Valida la firma de un evento recibido mediante un Webhook. + /// Utiliza esta operación para verificar la autenticidad e integridad de + /// un evento recibido, comparando la firma recibida con la generada por Facturapi. + /// + /// + /// Datos de la solicitud. Admite ValidateWebhookSignatureInput. + /// Permite cancelar la solicitud. + /// Payload original con firma válida + /// + public Task>> ValidateSignatureRemotelyAsync(ValidateWebhookSignatureInput data, CancellationToken cancellationToken = default) { - using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")) - using (var response = await client.PostAsync(Router.ValidateSignature(), content, cancellationToken).ConfigureAwait(false)) - { - await this.ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false); - var resultString = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var webhook = JsonConvert.DeserializeObject(resultString, this.jsonSettings); - return webhook; - } + return RequestAsync>>(HttpMethod.Post, $"webhooks/validate-signature", null, data, true, cancellationToken); } } diff --git a/openapi/generated.json b/openapi/generated.json index 3525915..319e3e9 100644 --- a/openapi/generated.json +++ b/openapi/generated.json @@ -1,12 +1,128 @@ [ ".gitattributes", "Models/Address.cs", + "Models/ApiEvent.cs", + "Models/ApiEventData.JsonConverter.cs", + "Models/ApiEventData.cs", + "Models/CartaPorteAutotransporte.cs", + "Models/CartaPorteCantidadTransporta.cs", + "Models/CartaPorteCarroFerroviario.cs", + "Models/CartaPorteContenedorFerroviario.cs", + "Models/CartaPorteContenedorMaritimo.cs", + "Models/CartaPorteContenedorMaritimoRemolquesCCPItem.cs", + "Models/CartaPorteDataProperties.cs", + "Models/CartaPorteDataPropertiesFiguraTransporteItem.cs", + "Models/CartaPorteDataPropertiesFiguraTransporteItemPartesTransporteItem.cs", + "Models/CartaPorteDataPropertiesUbicacionesItem.cs", + "Models/CartaPorteDerechosDePaso.cs", + "Models/CartaPorteDetalleMercancia.cs", + "Models/CartaPorteDocumentacionAduanera.cs", + "Models/CartaPorteDomicilio.cs", + "Models/CartaPorteGuiaIdentificacion.cs", + "Models/CartaPorteIdentificacionVehicular.cs", + "Models/CartaPorteMercancia.cs", + "Models/CartaPorteMercancias.cs", + "Models/CartaPorteRemolque.cs", + "Models/CartaPorteSeguros.cs", + "Models/CartaPorteTransporteAereo.cs", + "Models/CartaPorteTransporteFerroviario.cs", + "Models/CartaPorteTransporteMaritimo.cs", + "Models/CatalogItem.cs", + "Models/Certificate.cs", + "Models/CheckApiHealthResponse.cs", + "Models/ComercioExteriorDataProperties.cs", + "Models/ComercioExteriorDataPropertiesDestinatarioItem.cs", + "Models/ComercioExteriorDataPropertiesPropietarioItem.cs", + "Models/ComercioExteriorDataPropertiesReceptor.cs", + "Models/ComercioExteriorDescripcionesEspecificas.cs", + "Models/ComercioExteriorDomicilio.cs", + "Models/ComercioExteriorEmisor.cs", + "Models/ComercioExteriorMercancia.cs", + "Models/ComercioExteriorMercancias.cs", + "Models/CompletionStep.cs", + "Models/CreateInvoiceResponse.cs", + "Models/CreateToInvoiceFromReceiptsResponse.cs", + "Models/CreateToInvoiceFromReceiptsResponseTaxes.cs", "Models/Customer.cs", "Models/CustomerEditLinkEmailResult.cs", + "Models/CustomerInfo.cs", + "Models/Customization.cs", + "Models/CustomizationDefaultSeries.cs", + "Models/CustomizationPdfExtra.cs", + "Models/CustomizationPdfExtraPayrollOptions.cs", + "Models/DomainAvailability.cs", + "Models/Efos.cs", + "Models/EfosData.cs", + "Models/EfosDetalle.cs", + "Models/ErrorDetail.cs", + "Models/FielCertificate.cs", + "Models/GenericError.cs", + "Models/Global.cs", + "Models/HidroYPetroComplement.cs", + "Models/IeduComplement.cs", + "Models/Inputs/CancellationQueryInput.cs", + "Models/Inputs/CancellationWithSubstitutionInput.cs", + "Models/Inputs/CartaPorteAutotransporteInput.cs", + "Models/Inputs/CartaPorteCantidadTransportaInput.cs", + "Models/Inputs/CartaPorteCarroFerroviarioInput.cs", + "Models/Inputs/CartaPorteContenedorFerroviarioInput.cs", + "Models/Inputs/CartaPorteContenedorMaritimoInput.cs", + "Models/Inputs/CartaPorteContenedorMaritimoInputRemolquesCCPItem.cs", + "Models/Inputs/CartaPorteDataPropertiesInput.cs", + "Models/Inputs/CartaPorteDataPropertiesInputFiguraTransporteItem.cs", + "Models/Inputs/CartaPorteDataPropertiesInputFiguraTransporteItemPartesTransporteItem.cs", + "Models/Inputs/CartaPorteDataPropertiesInputUbicacionesItem.cs", + "Models/Inputs/CartaPorteDerechosDePasoInput.cs", + "Models/Inputs/CartaPorteDetalleMercanciaInput.cs", + "Models/Inputs/CartaPorteDocumentacionAduaneraInput.cs", + "Models/Inputs/CartaPorteDomicilioInput.cs", + "Models/Inputs/CartaPorteGuiaIdentificacionInput.cs", + "Models/Inputs/CartaPorteIdentificacionVehicularInput.cs", + "Models/Inputs/CartaPorteInput.cs", + "Models/Inputs/CartaPorteMercanciaInput.cs", + "Models/Inputs/CartaPorteMercanciasInput.cs", + "Models/Inputs/CartaPorteRemolqueInput.cs", + "Models/Inputs/CartaPorteSegurosInput.cs", + "Models/Inputs/CartaPorteTransporteAereoInput.cs", + "Models/Inputs/CartaPorteTransporteFerroviarioInput.cs", + "Models/Inputs/CartaPorteTransporteMaritimoInput.cs", + "Models/Inputs/CartaporteCatalogSearchAirTransportCodesParams.cs", + "Models/Inputs/CartaporteCatalogSearchCustomsDocumentsParams.cs", + "Models/Inputs/CartaporteCatalogSearchHazardousMaterialsParams.cs", + "Models/Inputs/CartaporteCatalogSearchMarineContainersParams.cs", + "Models/Inputs/CartaporteCatalogSearchNavalAuthorizationsParams.cs", + "Models/Inputs/CartaporteCatalogSearchPackagingTypesParams.cs", + "Models/Inputs/CartaporteCatalogSearchPortStationsParams.cs", + "Models/Inputs/CartaporteCatalogSearchRightsOfPassageParams.cs", + "Models/Inputs/CartaporteCatalogSearchTrailerTypesParams.cs", + "Models/Inputs/CartaporteCatalogSearchTransportConfigsParams.cs", + "Models/Inputs/CatalogGetProductCategoryParams.cs", + "Models/Inputs/CatalogSearchCountriesParams.cs", + "Models/Inputs/CatalogSearchInvoiceUsesParams.cs", + "Models/Inputs/CatalogSearchProductsParams.cs", + "Models/Inputs/CatalogSearchTaxSystemsParams.cs", + "Models/Inputs/CatalogSearchUnitsParams.cs", + "Models/Inputs/CatalogSearchZipCodesParams.cs", + "Models/Inputs/ComercioExteriorCatalogSearchTariffFractionsParams.cs", + "Models/Inputs/ComercioExteriorDataInput.cs", + "Models/Inputs/ComercioExteriorDataInputDestinatarioItem.cs", + "Models/Inputs/ComercioExteriorDataInputPropietarioItem.cs", + "Models/Inputs/ComercioExteriorDescripcionesEspecificasInput.cs", + "Models/Inputs/ComercioExteriorDomicilioInput.cs", + "Models/Inputs/ComercioExteriorEmisorInput.cs", + "Models/Inputs/ComercioExteriorInput.cs", + "Models/Inputs/ComercioExteriorMercanciaInput.cs", + "Models/Inputs/ComercioExteriorMercanciasInput.cs", + "Models/Inputs/ComercioExteriorReceptorInput.cs", + "Models/Inputs/CustomComplementInput.cs", + "Models/Inputs/CustomerComercioExteriorInput.cs", + "Models/Inputs/CustomerCreateCommonInput.cs", + "Models/Inputs/CustomerCreateInput.cs", "Models/Inputs/CustomerCreateParams.cs", "Models/Inputs/CustomerCreateWithEditLinkInput.cs", "Models/Inputs/CustomerCreateWithEditLinkInputAddress.cs", - "Models/Inputs/CustomerEditLinkEmailInput.cs", + "Models/Inputs/CustomerEditableInput.cs", + "Models/Inputs/CustomerEditableInputAddress.cs", "Models/Inputs/CustomerForeignAddressInput.cs", "Models/Inputs/CustomerForeignCreateInput.cs", "Models/Inputs/CustomerGenericCreateInput.cs", @@ -20,10 +136,242 @@ "Models/Inputs/CustomerUpdateWithEditLinkInput.cs", "Models/Inputs/CustomerUpdateWithEditLinkInputAddress.cs", "Models/Inputs/DateRangeInput.cs", + "Models/Inputs/GlobalInvoiceCommonInput.cs", + "Models/Inputs/GlobalInvoiceInput.cs", + "Models/Inputs/HidroYPetroComplementInput.cs", + "Models/Inputs/IeduComplementInput.cs", + "Models/Inputs/InvoiceCommonEditInput.cs", + "Models/Inputs/InvoiceCommonEditInputAddress.cs", + "Models/Inputs/InvoiceCommonInput.cs", + "Models/Inputs/InvoiceCommonInputAddress.cs", + "Models/Inputs/InvoiceComplementInput.cs", + "Models/Inputs/InvoiceCreateInput.cs", + "Models/Inputs/InvoiceCreateInputGlobal.cs", + "Models/Inputs/InvoiceCreateParams.cs", + "Models/Inputs/InvoiceDraftCommonInput.cs", + "Models/Inputs/InvoiceEgresoDraftInput.cs", + "Models/Inputs/InvoiceEgresoEditInput.cs", + "Models/Inputs/InvoiceEgresoInput.cs", + "Models/Inputs/InvoiceGetPaymentSummaryParams.cs", + "Models/Inputs/InvoiceIngresoDraftInput.cs", + "Models/Inputs/InvoiceIngresoEditInput.cs", + "Models/Inputs/InvoiceIngresoInput.cs", + "Models/Inputs/InvoiceItemEgresoInput.cs", + "Models/Inputs/InvoiceItemInput.cs", + "Models/Inputs/InvoiceItemInputThirdParty.cs", + "Models/Inputs/InvoiceItemProductEgresoInput.cs", + "Models/Inputs/InvoiceItemProductInput.cs", + "Models/Inputs/InvoiceItemProductTrasladoInput.cs", + "Models/Inputs/InvoiceItemThirdPartyInput.cs", + "Models/Inputs/InvoiceItemTrasladoInput.cs", + "Models/Inputs/InvoiceItemTrasladoInputThirdParty.cs", + "Models/Inputs/InvoiceListParams.cs", + "Models/Inputs/InvoiceListZipRequestsParams.cs", + "Models/Inputs/InvoiceNominaDraftInput.cs", + "Models/Inputs/InvoiceNominaEditInput.cs", + "Models/Inputs/InvoiceNominaInput.cs", + "Models/Inputs/InvoicePagoDraftInput.cs", + "Models/Inputs/InvoicePagoEditInput.cs", + "Models/Inputs/InvoicePagoInput.cs", + "Models/Inputs/InvoiceReceiptInput.cs", + "Models/Inputs/InvoiceStampDraftParams.cs", + "Models/Inputs/InvoiceTrasladoDraftInput.cs", + "Models/Inputs/InvoiceTrasladoEditInput.cs", + "Models/Inputs/InvoiceTrasladoInput.cs", + "Models/Inputs/InvoiceZipRequestCreateInput.cs", + "Models/Inputs/InvoiceableCommonEditInput.cs", + "Models/Inputs/InvoiceableCommonEditInputPdfOptions.cs", + "Models/Inputs/InvoiceableCommonEditInputPdfOptionsPayrollOptions.cs", + "Models/Inputs/InvoiceableCommonInput.cs", + "Models/Inputs/InvoiceableCommonInputPdfOptions.cs", + "Models/Inputs/InvoiceableCommonInputPdfOptionsPayrollOptions.cs", + "Models/Inputs/LeyendasFiscalesDataInput.cs", + "Models/Inputs/LeyendasFiscalesDataInputLeyendasItem.cs", + "Models/Inputs/LeyendasFiscalesInput.cs", + "Models/Inputs/LocalTaxInput.cs", + "Models/Inputs/NamespaceInput.cs", + "Models/Inputs/NominaAccionesInput.cs", + "Models/Inputs/NominaCatalogSearchDeductionsParams.cs", + "Models/Inputs/NominaCatalogSearchPerceptionsParams.cs", + "Models/Inputs/NominaCompensacionInput.cs", + "Models/Inputs/NominaComplementDataInput.cs", + "Models/Inputs/NominaComplementDataInputOtrosPagosItem.cs", + "Models/Inputs/NominaComplementDataNestedInput.cs", + "Models/Inputs/NominaComplementInput.cs", + "Models/Inputs/NominaDeduccionInput.cs", + "Models/Inputs/NominaEmisorInput.cs", + "Models/Inputs/NominaEmisorInputEntidadSncf.cs", + "Models/Inputs/NominaEntidadSncfInput.cs", + "Models/Inputs/NominaHorasExtraInput.cs", + "Models/Inputs/NominaIncapacidadInput.cs", + "Models/Inputs/NominaJubilacionInput.cs", + "Models/Inputs/NominaOtroPagoInput.cs", + "Models/Inputs/NominaPercepcionInput.cs", + "Models/Inputs/NominaPercepcionNestedInput.cs", + "Models/Inputs/NominaPercepcionesInput.cs", + "Models/Inputs/NominaReceptorInput.cs", + "Models/Inputs/NominaReceptorNestedInput.cs", + "Models/Inputs/NominaSeparacionInput.cs", + "Models/Inputs/NominaSubContratacionInput.cs", + "Models/Inputs/OrganizationCertsInput.cs", + "Models/Inputs/OrganizationCheckDomainIsAvailableParams.cs", + "Models/Inputs/OrganizationCreateInput.cs", + "Models/Inputs/OrganizationCustomizationInput.cs", + "Models/Inputs/OrganizationCustomizationInputPdfExtra.cs", + "Models/Inputs/OrganizationCustomizationInputPdfExtraPayrollOptions.cs", + "Models/Inputs/OrganizationDomainInput.cs", + "Models/Inputs/OrganizationFielInput.cs", + "Models/Inputs/OrganizationInviteCreateInput.cs", + "Models/Inputs/OrganizationInviteRespondInput.cs", + "Models/Inputs/OrganizationLegalInput.cs", + "Models/Inputs/OrganizationLegalInputAddress.cs", + "Models/Inputs/OrganizationListParams.cs", + "Models/Inputs/OrganizationLogoInput.cs", + "Models/Inputs/OrganizationPermissionRoleCreateInput.cs", + "Models/Inputs/OrganizationPermissionRoleUpdateInput.cs", + "Models/Inputs/OrganizationReceiptsInput.cs", + "Models/Inputs/OrganizationSelfInvoiceInput.cs", + "Models/Inputs/OrganizationSeriesCreateInput.cs", + "Models/Inputs/OrganizationSeriesDefaultInput.cs", + "Models/Inputs/OrganizationSeriesUpdateInput.cs", + "Models/Inputs/OrganizationUserAccessRoleUpdateInput.cs", + "Models/Inputs/PagoComplementInput.cs", + "Models/Inputs/PartInput.cs", + "Models/Inputs/PaymentInput.cs", + "Models/Inputs/PaymentInputRelatedDocumentsItem.cs", + "Models/Inputs/PaymentInputRelatedDocumentsItemTaxesItem.cs", + "Models/Inputs/ProductCreateInput.cs", + "Models/Inputs/ProductListParams.cs", + "Models/Inputs/ProductUpdateInput.cs", + "Models/Inputs/ReceiptAssignCustomerInput.cs", + "Models/Inputs/ReceiptInput.cs", + "Models/Inputs/ReceiptInputAddress.cs", + "Models/Inputs/ReceiptListParams.cs", + "Models/Inputs/RelatedDocumentInput.cs", + "Models/Inputs/RetentionInput.cs", + "Models/Inputs/RetentionInputPeriodo.cs", + "Models/Inputs/RetentionInputTotales.cs", + "Models/Inputs/RetentionInputTotalesImpRetenidosItem.cs", + "Models/Inputs/RetentionListParams.cs", + "Models/Inputs/RetentionUpdateInput.cs", + "Models/Inputs/SendEditLinkByEmailInput.cs", + "Models/Inputs/SendInvoiceByEmailInput.cs", + "Models/Inputs/SendReceiptByEmailInput.cs", + "Models/Inputs/SendRetentionByEmailInput.cs", + "Models/Inputs/TaxInput.cs", + "Models/Inputs/ToInvoiceInput.cs", + "Models/Inputs/ToInvoicePreviewInput.cs", + "Models/Inputs/ToolValidateTaxIdParams.cs", + "Models/Inputs/UpdateDraftInvoiceInput.cs", + "Models/Inputs/ValidateWebhookSignatureInput.cs", + "Models/Inputs/WebhookCreateInput.cs", + "Models/Inputs/WebhookListParams.cs", + "Models/Inputs/WebhookUpdateInput.cs", + "Models/Invoice.cs", + "Models/InvoiceCancellation.cs", + "Models/InvoiceComplementProperties.cs", + "Models/InvoiceDraft.cs", + "Models/InvoiceFailed.cs", + "Models/InvoiceItem.cs", + "Models/InvoiceItemPart.cs", + "Models/InvoiceItemThirdParty.cs", + "Models/InvoicePending.cs", + "Models/InvoiceStamped.cs", + "Models/InvoiceZipRequest.cs", + "Models/Legal.cs", + "Models/LegalAddress.cs", + "Models/LeyendasFiscalesData.cs", + "Models/LeyendasFiscalesDataLeyendasItem.cs", + "Models/LiveApiKey.cs", + "Models/LocalTax.cs", + "Models/Namespace.cs", + "Models/NominaAccionesProperties.cs", + "Models/NominaCompensacionProperties.cs", + "Models/NominaComplementDataProperties.cs", + "Models/NominaComplementDataPropertiesOtrosPagosItem.cs", + "Models/NominaDeduccionProperties.cs", + "Models/NominaEmisorProperties.cs", + "Models/NominaEmisorPropertiesEntidadSncf.cs", + "Models/NominaHorasExtraProperties.cs", + "Models/NominaIncapacidadProperties.cs", + "Models/NominaJubilacionProperties.cs", + "Models/NominaPercepcionProperties.cs", + "Models/NominaPercepcionesProperties.cs", + "Models/NominaReceptorProperties.cs", + "Models/NominaSeparacionProperties.cs", + "Models/NominaSubContratacionProperties.cs", + "Models/OkResponse.cs", + "Models/OneOf2.cs", + "Models/OneOf3.cs", + "Models/OneOf4.cs", + "Models/OneOf6.cs", + "Models/OneOf7.cs", + "Models/Organization.cs", + "Models/OrganizationDeleteCerts.cs", + "Models/OrganizationInvite.cs", + "Models/OrganizationPendingAddOnsUpdate.cs", + "Models/OrganizationPendingPlanUpdate.cs", + "Models/OrganizationReceipts.cs", + "Models/OrganizationSeriesDeletion.cs", + "Models/OrganizationTeamRole.cs", + "Models/OrganizationTeamRoleTemplate.cs", + "Models/OrganizationUserAccess.cs", + "Models/Payment.cs", + "Models/PaymentRelated.cs", + "Models/PaymentRelatedDocumentsItem.cs", + "Models/PaymentRelatedDocumentsItemTaxesItem.cs", + "Models/PaymentSummary.cs", + "Models/PaymentSummaryTax.cs", + "Models/Product.cs", + "Models/ProductCategory.cs", + "Models/ProductCategoryDetail.cs", + "Models/ProductCategoryList.cs", + "Models/ProductInfo.cs", + "Models/Receipt.cs", + "Models/ReceiptInvoiceSummaryTax.cs", + "Models/RelatedResourceMessage.cs", + "Models/Retention.cs", + "Models/RetentionPeriod.cs", + "Models/RetentionRetainedTax.cs", + "Models/RetentionTotals.cs", + "Models/SearchCartaPorteNavalAuthorizationsResponseDataItem.cs", "Models/SearchResult.cs", + "Models/SelfInvoiceSettings.cs", + "Models/SendInvoiceByEmailResponse.cs", + "Models/SendReceiptByEmailResponse.cs", + "Models/SendRetentionByEmailResponse.cs", + "Models/SeriesGroup.cs", + "Models/SignedDownloadUrl.cs", + "Models/Stamp.cs", + "Models/Tax.cs", + "Models/TaxIdValidation.cs", "Models/TaxInfoError.cs", "Models/TaxInfoValidation.cs", - "Router/CustomerRouter.cs", + "Models/ToInvoiceSummary.cs", + "Models/Webhook.cs", + "Models/ZipCode.cs", + "Wrappers/CartaporteCatalogWrapper.cs", + "Wrappers/CatalogWrapper.cs", + "Wrappers/ComercioExteriorCatalogWrapper.cs", "Wrappers/CustomerWrapper.cs", - "Wrappers/ICustomerWrapper.cs" + "Wrappers/ICartaporteCatalogWrapper.cs", + "Wrappers/ICatalogWrapper.cs", + "Wrappers/IComercioExteriorCatalogWrapper.cs", + "Wrappers/ICustomerWrapper.cs", + "Wrappers/IInvoiceWrapper.cs", + "Wrappers/INominaCatalogWrapper.cs", + "Wrappers/IOrganizationWrapper.cs", + "Wrappers/IProductWrapper.cs", + "Wrappers/IReceiptWrapper.cs", + "Wrappers/IRetentionWrapper.cs", + "Wrappers/IToolWrapper.cs", + "Wrappers/IWebhookWrapper.cs", + "Wrappers/InvoiceWrapper.cs", + "Wrappers/NominaCatalogWrapper.cs", + "Wrappers/OrganizationWrapper.cs", + "Wrappers/ProductWrapper.cs", + "Wrappers/ReceiptWrapper.cs", + "Wrappers/RetentionWrapper.cs", + "Wrappers/ToolWrapper.cs", + "Wrappers/WebhookWrapper.cs" ] diff --git a/scripts/generate-sdk.mjs b/scripts/generate-sdk.mjs index 30db1ce..adce32b 100644 --- a/scripts/generate-sdk.mjs +++ b/scripts/generate-sdk.mjs @@ -18,7 +18,7 @@ const contract = await compileContract( ); const outputs = new Map([ ...renderModels(contract), - ...renderResources(contract), + ...renderResources(contract, config), ]); for (const [filename, content] of outputs) outputs.set(filename, content.replace(/[ \t]+$/gm, "")); @@ -88,5 +88,5 @@ for (const [filename, content] of outputs) { } } console.log( - `${process.argv.includes("--check") ? "Verified" : "Generated"} Customers: ${contract.methods.length} operations, ${contract.models.length} models.`, + `${process.argv.includes("--check") ? "Verified" : "Generated"} SDK: ${contract.operationCount} operations, ${contract.methods.length} bindings, ${contract.models.length} models.`, ); diff --git a/scripts/sdk/compiler.mjs b/scripts/sdk/compiler.mjs index cfd8df3..a06f260 100644 --- a/scripts/sdk/compiler.mjs +++ b/scripts/sdk/compiler.mjs @@ -3,9 +3,10 @@ import openapiTS, { astToString } from "openapi-typescript"; import ts from "typescript"; export const pascal = (value) => - value.replace(/(^|[_-])([a-z])/g, (_, prefix, letter) => - letter.toUpperCase(), - ); + value + .replace(/[^a-zA-Z0-9_]/g, "_") + .replace(/(^|_)([a-zA-Z0-9])/g, (_, prefix, letter) => letter.toUpperCase()) + .replace(/^[0-9]/, (digit) => "Value" + digit); export const camel = (value) => pascal(value).replace(/^./, (letter) => letter.toLowerCase()); @@ -15,14 +16,7 @@ export async function compileContract(spec, config) { const operations = new Map(); for (const [path, item] of Object.entries(spec.paths)) { for (const [verb, operation] of Object.entries(item)) { - if ( - !operation.operationId || - !( - path === "/" + config.resource || - path.startsWith("/" + config.resource + "/") - ) - ) - continue; + if (!operation.operationId) continue; assert( !operations.has(operation.operationId), `Duplicate operation: ${operation.operationId}`, @@ -30,29 +24,27 @@ export async function compileContract(spec, config) { operations.set(operation.operationId, { ...operation, path, verb }); } } - assert.deepEqual( - [...operations.keys()].sort(), - Object.values(config.methods).sort(), - "Every Customers operation must have a method binding.", - ); const filename = "/contract.ts"; const content = - "type Integer = number & { readonly __integer: unique symbol };\n" + + "type Integer = number & { readonly __integer: unique symbol }; type Binary = string & { readonly __binary: unique symbol };\n" + astToString( await openapiTS(spec, { defaultNonNullable: false, + emptyObjectsUnknown: true, transform(schema) { const type = - schema.format === "date-time" - ? ts.factory.createTypeReferenceNode("Date") - : schema.type === "integer" || - (Array.isArray(schema.type) && - schema.type.includes("integer") && - schema.type.every( - (type) => type === "integer" || type === "null", - )) - ? ts.factory.createTypeReferenceNode("Integer") - : null; + schema.format === "binary" + ? ts.factory.createTypeReferenceNode("Binary") + : schema.format === "date-time" + ? ts.factory.createTypeReferenceNode("Date") + : schema.type === "integer" || + (Array.isArray(schema.type) && + schema.type.includes("integer") && + schema.type.every( + (type) => type === "integer" || type === "null", + )) + ? ts.factory.createTypeReferenceNode("Integer") + : null; if (type) return Array.isArray(schema.type) && schema.type.includes("null") ? ts.factory.createUnionTypeNode([ @@ -107,14 +99,21 @@ export async function compileContract(spec, config) { ), ); const models = new Map(); + const named = new Map(); const names = new Map(); for (const symbol of checker.getPropertiesOfType(schemas)) { - names.set( - checker.getNonNullableType(at(symbol)), - config.modelNames[symbol.name] || symbol.name, - ); + // Prefer deliberate SDK aliases over structurally identical schema aliases. + if ( + !names.has(checker.getNonNullableType(at(symbol))) || + config.modelNames[symbol.name] + ) + names.set( + checker.getNonNullableType(at(symbol)), + config.modelNames[symbol.name] || symbol.name, + ); + named.set(symbol.name, at(symbol)); } - const compiled = new Map(); + const compiled = { input: new Map(), output: new Map() }; const prose = (symbol) => [ ts.displayPartsToString(symbol.getDocumentationComment(checker)), @@ -124,16 +123,104 @@ export async function compileContract(spec, config) { .map((tag) => ts.displayPartsToString(tag.text)), ] .filter(Boolean) - .join("\n"); + .join("\n") + .replaceAll("(enum property replaced by openapi-typescript)", "") + .replaceAll("discriminator enum property added by openapi-typescript", "") + .trim(); + const merge = (fields) => { + const nullable = fields.some( + (field) => field.nullable || field.kind === "null", + ); + fields = fields + .flatMap((field) => (field.kind === "union" ? field.variants : [field])) + .filter((field) => !["null", "never"].includes(field.kind)); + if (!fields.length) return { kind: "null", nullable: true }; + if ( + fields.every((field) => ["string", "inputDate"].includes(field.kind)) && + fields.some((field) => field.kind === "inputDate") + ) + return { kind: "inputDate", nullable }; + if ( + fields.every((field) => field.kind === fields[0].kind) && + [ + "string", + "integer", + "number", + "boolean", + "date", + "inputDate", + "binary", + ].includes(fields[0].kind) + ) + return { + kind: fields[0].kind, + nullable, + ...(fields.every((field) => field.values) + ? { values: [...new Set(fields.flatMap((field) => field.values))] } + : {}), + }; + if (fields.every((field) => field.kind === "array")) + return { + kind: "array", + nullable, + item: merge(fields.map((field) => field.item)), + }; + const variants = [ + ...new Map( + fields.map((field) => [ + JSON.stringify({ ...field, nullable: false }), + field, + ]), + ).values(), + ]; + if (variants.length === 1) return { ...variants[0], nullable }; + return { + kind: "union", + nullable, + variants: variants.map((field) => ({ ...field, nullable: false })), + }; + }; function compile(type, hint, input) { + if ( + type.flags & + (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.NonPrimitive) + ) + return { kind: "any", nullable: true }; + if (type.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)) + return { kind: "null", nullable: true }; + if (checker.typeToString(type) === "never") return { kind: "never" }; const nullable = type.isUnion() && type.types.some((item) => item.flags & ts.TypeFlags.Null); type = checker.getNonNullableType(type); if (type.aliasSymbol?.name === "Integer") return { kind: "integer", nullable }; - if (type.symbol?.name === "Date") - return { kind: input ? "string" : "date", nullable }; + if ( + type.symbol?.name === "Date" || + (type.isIntersection() && + type.types.some((part) => part.symbol?.name === "Date")) + ) + return { kind: input ? "inputDate" : "date", nullable }; + if (type.aliasSymbol?.name === "Binary") + return { kind: "binary", nullable }; + if ( + type.isIntersection() && + type.types.some((part) => part.flags & ts.TypeFlags.NumberLike) + ) + return { + kind: checker.getPropertyOfType(type, "__integer") + ? "integer" + : "number", + nullable, + }; + if ( + type.isIntersection() && + type.types.some((part) => part.flags & ts.TypeFlags.StringLike) + ) + return { + kind: checker.getPropertyOfType(type, "__binary") ? "binary" : "string", + nullable, + }; if ( type.flags & ts.TypeFlags.BooleanLike || (type.isUnion() && @@ -143,27 +230,30 @@ export async function compileContract(spec, config) { if (type.flags & ts.TypeFlags.NumberLike) return { kind: "number", nullable }; if ( - type.flags & ts.TypeFlags.String || + type.flags & ts.TypeFlags.StringLike || (type.isUnion() && - type.types.every((item) => item.flags & ts.TypeFlags.StringLike) && - type.types.some((item) => !item.isStringLiteral())) + type.types.every((item) => item.flags & ts.TypeFlags.StringLike)) ) - return { kind: "string", nullable }; - if ( - type.isStringLiteral() || - (type.isUnion() && type.types.every((item) => item.isStringLiteral())) - ) { - // Literal constraints remain visible in docs; strings preserve compatibility - // with catalog values and allow response enums to evolve without parse errors. return { kind: "string", nullable, - values: (type.isUnion() ? type.types : [type]).map( - (item) => item.value, - ), + ...(type.isStringLiteral() || + (type.isUnion() && type.types.every((item) => item.isStringLiteral())) + ? { + values: (type.isUnion() ? type.types : [type]).map( + (item) => item.value, + ), + } + : {}), }; - } - if (checker.isArrayType(type)) + if ( + type.flags & + (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.NonPrimitive) + ) + return { kind: "any", nullable }; + if (type.flags & ts.TypeFlags.Never) + return { kind: nullable ? "null" : "never", nullable }; + if (checker.isArrayType(type) || checker.isTupleType(type)) return { kind: "array", nullable, @@ -173,117 +263,369 @@ export async function compileContract(spec, config) { input, ), }; - assert( - !( - type.flags & - (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Never) - ), - `Unsupported open type at ${hint}`, - ); - assert( - !type.isUnion(), - `Unsupported union at ${hint}: ${checker.typeToString(type)}. Add an explicit binding instead of widening the type.`, - ); - assert( - !checker.getIndexTypeOfType(type, ts.IndexKind.String), - `Unsupported open dictionary at ${hint}`, + const cache = compiled[input ? "input" : "output"]; + if (cache.has(type)) return { ...cache.get(type), nullable }; + const alternatives = (type.isUnion() ? type.types : [type]).filter( + (variant) => checker.typeToString(variant) !== "never", ); - assert( - checker.getPropertiesOfType(type).length > 0, - `Unsupported open type at ${hint}`, - ); - if (compiled.has(type)) - return { kind: "model", ref: compiled.get(type), nullable }; - const name = + // C# has no structural object unions. Expose their documented superset; + // named input variants below retain their own required constructor fields. + if ( + type.isUnion() && + !alternatives.every( + (variant) => + checker.getPropertiesOfType(variant).length > 0 && + !checker.isArrayType(variant) && + !( + variant.flags & + (ts.TypeFlags.StringLike | + ts.TypeFlags.NumberLike | + ts.TypeFlags.BooleanLike) + ), + ) + ) { + return merge( + alternatives.map((variant, index) => + compile(variant, hint + "Variant" + (index + 1), input), + ), + ); + } + const properties = new Map(); + for (const variant of alternatives) + for (const symbol of checker.getPropertiesOfType(variant)) { + if ( + input && + symbol.declarations?.some((declaration) => + declaration.modifiers?.some( + (modifier) => modifier.kind === ts.SyntaxKind.ReadonlyKeyword, + ), + ) + ) + continue; + if (!properties.has(symbol.name)) properties.set(symbol.name, []); + properties.get(symbol.name).push(symbol); + } + const additional = checker.getIndexTypeOfType(type, ts.IndexKind.String); + if (!properties.size) + return additional + ? { + kind: "map", + nullable, + item: compile(additional, hint + "Value", input), + } + : { kind: "map", nullable, item: { kind: "any" } }; + const base = config.modelNames[names.get(type) || hint] || names.get(type) || hint; + const name = + input && !base.includes("Input") && !base.endsWith("Params") + ? base + "Input" + : base; assert.match(name, /^[A-Za-z][A-Za-z0-9]*$/, `Invalid model name: ${name}`); - assert(!models.has(name), `Conflicting generated model: ${name}`); - compiled.set(type, name); - const model = { + if ( + !input && + properties.has("data") && + (properties.has("total_results") || properties.has("page")) + ) { + const data = compile(at(properties.get("data")[0]), name + "Data", false); + assert.equal(data.kind, "array", `Expected paginated data for ${name}`); + const result = { kind: "pagination", item: data.item }; + cache.set(type, result); + return { ...result, nullable }; + } + const ref = { kind: "model", ref: name }; + cache.set(type, ref); + const model = models.get(name) || { name, input, description: - spec.components.schemas[name]?.description || - spec.components.schemas[name]?.title || + spec.components.schemas[names.get(type)]?.description || + spec.components.schemas[names.get(type)]?.title || name, properties: [], }; + assert.equal( + model.input, + input, + `Separate input/output model names for ${name}`, + ); models.set(name, model); - model.properties = checker.getPropertiesOfType(type).map((symbol) => ({ - name: symbol.name, - required: !(symbol.flags & ts.SymbolFlags.Optional), - description: prose(symbol), - ...compile(at(symbol), name + pascal(symbol.name), input), + const fields = [...properties].map(([key, symbols]) => ({ + ...merge( + symbols.map((symbol) => compile(at(symbol), name + pascal(key), input)), + ), + name: key, + required: + symbols.length === alternatives.length && + symbols.every((symbol) => !(symbol.flags & ts.SymbolFlags.Optional)), + description: [...new Set(symbols.map(prose).filter(Boolean))].join("\n"), })); - return { kind: "model", ref: name, nullable }; - } - for (const name of config.inputs) - compile(property(schemas, name), name, true); - compile(property(schemas, "Customer"), "Customer", false); - const methods = []; - for (const [name, id] of Object.entries(config.methods)) { - const operation = operations.get(id); - const type = property(operationTypes, id); - const parameters = property(type, "parameters"); - const query = property(parameters, "query"); - const hasQuery = !( - checker.getNonNullableType(query).flags & ts.TypeFlags.Never - ); - const method = { name, id, ...operation }; - if (hasQuery) - method.query = compile(query, "Customer" + pascal(name) + "Params", true); - if (name === "sendEditLinkByEmail") - method.body = compile( - property( - property(property(type, "requestBody"), "content"), - "application/json", - ), - "CustomerEditLinkEmailInput", - true, + if (!input) { + model.variantMappings ||= {}; + for (const discriminator of fields.filter( + (field) => field.values?.length === 1, + )) { + model.variantMappings[discriminator.name] ||= {}; + model.variantMappings[discriminator.name][discriminator.values[0]] ||= + {}; + for (const field of fields.filter( + (field) => + field.name !== discriminator.name && field.kind !== "union", + )) + model.variantMappings[discriminator.name][discriminator.values[0]][ + field.name + ] = field; + } + } + for (const field of fields) { + const previous = model.properties.find( + (property) => property.name === field.name, ); - const responses = property(type, "responses"); - const success = checker - .getPropertiesOfType(responses) - .filter((symbol) => /^2\d\d$/.test(symbol.name)); - assert(success.length > 0, `Missing success response for ${id}`); - assert( - success.every( - (response) => - property(property(at(response), "content"), "application/json") === - property(property(at(success[0]), "content"), "application/json"), - ), - `Bind the response variants for ${id}`, + if (previous) { + const type = merge([ + Object.fromEntries( + Object.entries(previous).filter( + ([key]) => !["name", "required", "description"].includes(key), + ), + ), + Object.fromEntries( + Object.entries(field).filter( + ([key]) => !["name", "required", "description"].includes(key), + ), + ), + ]); + Object.assign(previous, type, { + required: previous.required && field.required, + }); + } else model.properties.push(field); + } + if (additional) + model.additional = compile(additional, name + "Value", input); + return { ...ref, nullable }; + } + // Compile all explicitly named input variants, including complements. + for (const [name, type] of named) + if (name.endsWith("Input") || (config.inputs || []).includes(name)) + compile(type, name, true); + for (const [name, binding] of Object.entries(config.variants || {})) { + const root = checker.getNonNullableType(named.get(binding.schema)); + assert(root.isUnion(), `Expected an input union for ${name}`); + const matches = root.types.filter((variant) => + Object.entries(binding.match).every(([key, expected]) => { + const symbol = checker.getPropertyOfType(variant, key); + if (!symbol) return false; + const type = checker.getNonNullableType(at(symbol)); + const values = (type.isUnion() ? type.types : [type]).map((type) => + type.isStringLiteral() ? type.value : undefined, + ); + return ( + values.length === (Array.isArray(expected) ? expected.length : 1) && + values.every((value) => + (Array.isArray(expected) ? expected : [expected]).includes(value), + ) + ); + }), ); - method.response = compile( - property(property(at(success[0]), "content"), "application/json"), - name === "validateTaxInfo" - ? "TaxInfoValidation" - : name === "sendEditLinkByEmail" - ? "CustomerEditLinkEmailResult" - : "Customer" + pascal(name) + "Result", - false, + assert.equal( + matches.length, + 1, + `Select exactly one public input variant for ${name}`, ); - const body = operation.requestBody?.$ref - ? operation.requestBody.$ref + const variant = compile(matches[0], name, true); + assert.equal(variant.kind, "model"); + const model = models.get(variant.ref); + model.description = + spec.components.schemas[binding.schema].description || name; + if (binding.parent) model.parent = compile(root, binding.schema, true).ref; + } + const methods = []; + const used = new Set(); + const dereference = (value) => + value?.$ref + ? value.$ref .slice(2) .split("/") - .reduce((target, part) => target[part], spec) - : operation.requestBody; - method.bodyRequired = body && body.required !== false; - method.responseDescription = - operation.responses[success[0].name].description; - method.parameters = [ - ...(spec.paths[operation.path].parameters || []), - ...(operation.parameters || []), - ].map((parameter) => - parameter.$ref - ? parameter.$ref - .slice(2) - .split("/") - .reduce((target, part) => target[part], spec) - : parameter, + .reduce( + (target, part) => + target[part.replaceAll("~1", "/").replaceAll("~0", "~")], + spec, + ) + : value; + for (const [resource, definition] of Object.entries(config.resources)) + for (const [name, binding] of Object.entries(definition.methods)) { + if (binding.alias) { + methods.push({ resource, name, ...binding }); + continue; + } + assert( + operations.has(binding.operation), + `Unknown public operation: ${binding.operation}`, + ); + used.add(binding.operation); + const operation = operations.get(binding.operation); + const type = property(operationTypes, binding.operation); + const method = { + resource, + name, + ...operation, + ...binding, + httpPath: operation.path, + fixedPath: binding.path || {}, + }; + method.parameters = [ + ...(spec.paths[operation.path].parameters || []), + ...(operation.parameters || []), + ].map(dereference); + for (const [key, value] of Object.entries(binding.path || {})) { + const parameter = method.parameters.find( + (parameter) => parameter.in === "path" && parameter.name === key, + ); + assert( + parameter, + `Unknown fixed path parameter for ${method.name}: ${key}`, + ); + assert( + !parameter.schema.enum || parameter.schema.enum.includes(value), + `Unsupported fixed format for ${method.name}: ${value}`, + ); + } + const parameters = property(type, "parameters"); + const query = property(parameters, "query"); + if (!(checker.getNonNullableType(query).flags & ts.TypeFlags.Never)) + method.query = compile( + binding.querySchema ? named.get(binding.querySchema) : query, + resource + name.replace(/Async$/, "") + "Params", + true, + ); + const body = dereference(operation.requestBody); + if (body) { + const content = property(property(type, "requestBody"), "content"); + const mediaType = Object.keys(body.content)[0]; + method.mediaType = mediaType; + method.body = compile( + binding.bodySchema + ? named.get(binding.bodySchema) + : property(content, mediaType), + pascal(binding.operation) + "Input", + true, + ); + method.bodyRequired = body.required !== false; + } + const responses = property(type, "responses"); + const success = checker + .getPropertiesOfType(responses) + .filter((symbol) => /^2\d\d$/.test(symbol.name)); + assert( + success.length, + `Missing success response for ${binding.operation}`, + ); + method.responseDescription = [ + ...new Set( + success.map( + (response) => + dereference(operation.responses[response.name]).description, + ), + ), + ].join("\n"); + const resultTypes = success.map((response) => { + const resolved = dereference(operation.responses[response.name]); + if (!resolved.content) return { kind: "void" }; + const mediaType = + Object.keys(resolved.content).find( + (type) => type === "application/json", + ) || Object.keys(resolved.content)[0]; + return compile( + property(property(at(response), "content"), mediaType), + pascal(binding.operation) + "Response", + false, + ); + }); + method.response = binding.responseSchema + ? compile( + named.get(binding.responseSchema), + binding.responseSchema, + false, + ) + : merge(resultTypes); + methods.push(method); + } + assert.deepEqual( + [...operations.keys()].sort(), + [...used].sort(), + "Every public operation must have an SDK method binding.", + ); + for (const name of config.outputModels || []) + compile(named.get(name), name, false); + // Preserve one generic pagination contract shared by every collection. + if (named.has("SearchResult")) { + const result = compile(named.get("SearchResult"), "SearchResult", false); + models.get(result.ref).generic = true; + models.get(result.ref).properties.push({ + name: "data", + required: true, + kind: "array", + item: { kind: "parameter", ref: "T" }, + description: "Elementos de la página.", + }); + } + const families = []; + for (const [schemaName, schema] of Object.entries(spec.components.schemas)) { + const alternatives = schema.oneOf || schema.anyOf; + if ( + !(schema.discriminator || schemaName === "CustomerCreateInput") || + !alternatives?.every((alternative) => alternative.$ref) + ) + continue; + const parent = compiled.input.get( + checker.getNonNullableType(named.get(schemaName)), + ); + const members = alternatives.map((alternative) => + compiled.input.get( + checker.getNonNullableType( + named.get(alternative.$ref.split("/").at(-1)), + ), + ), ); - methods.push(method); + if ( + parent?.kind === "model" && + members.every((member) => member?.kind === "model") + ) + families.push({ + parent: parent.ref, + members: members.map((member) => member.ref), + }); } - return { models: [...models.values()], methods }; + families.sort((left, right) => right.members.length - left.members.length); + const replaced = new Map(); + for (const family of families) { + if (family.members.every((name) => !models.get(name).parent)) { + for (const name of family.members) + models.get(name).parent = family.parent; + } else replaced.set(family.parent, family.members); + } + function replaceFamilies(field) { + if (field.kind === "model" && replaced.has(field.ref)) + return { + kind: "union", + nullable: field.nullable, + variants: replaced + .get(field.ref) + .map((ref) => ({ kind: "model", ref })), + }; + if (field.item) return { ...field, item: replaceFamilies(field.item) }; + if (field.variants) + return { ...field, variants: field.variants.map(replaceFamilies) }; + return field; + } + for (const model of models.values()) + model.properties = model.properties.map((field) => ({ + ...replaceFamilies(field), + name: field.name, + required: field.required, + description: field.description, + })); + for (const method of methods) + if (method.body) method.body = replaceFamilies(method.body); + for (const name of replaced.keys()) models.delete(name); + + return { models: [...models.values()], methods, operationCount: used.size }; } diff --git a/scripts/sdk/compiler.test.mjs b/scripts/sdk/compiler.test.mjs index 7ac1c03..8cb7774 100644 --- a/scripts/sdk/compiler.test.mjs +++ b/scripts/sdk/compiler.test.mjs @@ -76,7 +76,11 @@ function fixture() { } const binding = { ...config, - methods: { retrieve: "getCustomer" }, + outputModels: [], + variants: {}, + resources: { + Customer: { methods: { RetrieveAsync: { operation: "getCustomer" } } }, + }, inputs: ["CustomerUpdateInput"], }; @@ -146,20 +150,129 @@ test("requires a public method for every resource operation", async () => { }; await assert.rejects( compileContract(spec, binding), - /Every Customers operation/, + /Every public operation/, ); }); -test("fails on unsupported open types instead of generating an untyped model", async () => { +test("preserves deliberately open payloads without inventing a schema", async () => { const spec = fixture(); - spec.components.schemas.Base.properties.unknown = {}; - await assert.rejects(compileContract(spec, binding), /Unsupported open type/); + spec.components.schemas.Base.properties.metadata = { + type: "object", + additionalProperties: true, + }; + const contract = await compileContract(spec, binding); + const metadata = contract.models + .find((model) => model.name === "Customer") + .properties.find((field) => field.name === "metadata"); + assert.equal(metadata.kind, "map"); }); -test("fails on an unsupported union instead of flattening incompatible variants", async () => { +test("represents heterogeneous alternatives without a JSON envelope", async () => { const spec = fixture(); - spec.components.schemas.Base.properties.variant = { + spec.components.schemas.CustomerUpdateInput.properties.variant = { oneOf: [{ type: "string" }, { type: "integer" }], }; - await assert.rejects(compileContract(spec, binding), /Unsupported union/); + const contract = await compileContract(spec, binding); + const variant = contract.models + .find((model) => model.name === "CustomerUpdateInput") + .properties.find((field) => field.name === "variant"); + assert.equal(variant.kind, "union"); + assert.deepEqual(variant.variants.map((value) => value.kind).sort(), [ + "integer", + "string", + ]); + assert.match([...renderModels(contract).values()].join("\n"), /OneOf { + const spec = fixture(); + spec.components.schemas.Customer = { + oneOf: [ + { + type: "object", + properties: { + uuid: { type: "string" }, + status: { type: "string", const: "valid" }, + }, + }, + { + type: "object", + properties: { + uuid: { type: "null" }, + status: { type: "string", const: "draft" }, + }, + }, + ], + }; + const customer = (await compileContract(spec, binding)).models.find( + (model) => model.name === "Customer", + ); + assert.equal( + customer.properties.find((field) => field.name === "uuid").kind, + "string", + ); + assert.equal( + customer.properties.find((field) => field.name === "uuid").nullable, + true, + ); + assert.equal( + customer.properties.find((field) => field.name === "status").kind, + "string", + ); +}); + +test("normalizes numeric intersections and omits read-only request fields", async () => { + const spec = fixture(); + spec.components.schemas.CustomerUpdateInput.properties.days = { + allOf: [{ type: "number" }, { type: "integer" }], + }; + spec.components.schemas.CustomerUpdateInput.properties.created_at = { + type: "string", + format: "date-time", + readOnly: true, + }; + const input = (await compileContract(spec, binding)).models.find( + (model) => model.name === "CustomerUpdateInput", + ); + assert.equal( + input.properties.find((field) => field.name === "days").kind, + "integer", + ); + assert.equal( + input.properties.some((field) => field.name === "created_at"), + false, + ); +}); + +test("retains constructor requirements while making named input variants assignable to their family", async () => { + const spec = fixture(); + spec.components.schemas.CustomerNationalCreateInput = { + type: "object", + required: ["legal_name", "tax_id"], + properties: { legal_name: { type: "string" }, tax_id: { type: "string" } }, + }; + spec.components.schemas.CustomerForeignCreateInput = { + type: "object", + required: ["legal_name"], + properties: { legal_name: { type: "string" }, country: { type: "string" } }, + }; + spec.components.schemas.CustomerCreateInput = { + anyOf: [ + { $ref: "#/components/schemas/CustomerNationalCreateInput" }, + { $ref: "#/components/schemas/CustomerForeignCreateInput" }, + ], + }; + const contract = await compileContract(spec, binding); + const national = contract.models.find( + (model) => model.name === "CustomerNationalCreateInput", + ); + assert.equal(national.parent, "CustomerCreateInput"); + assert.equal( + national.properties.find((field) => field.name === "tax_id").required, + true, + ); + assert.match( + renderModels(contract).get("Models/Inputs/CustomerNationalCreateInput.cs"), + /: base\(@legalName\)/, + ); }); diff --git a/scripts/sdk/config.json b/scripts/sdk/config.json index fb3dc27..1881981 100644 --- a/scripts/sdk/config.json +++ b/scripts/sdk/config.json @@ -1,13 +1,721 @@ { - "resource": "customers", - "methods": { - "create": "createCustomer", - "list": "listCustomers", - "retrieve": "getCustomer", - "update": "editCustomer", - "delete": "deleteCustomer", - "validateTaxInfo": "validateCustomerTaxInfo", - "sendEditLinkByEmail": "sendEditLinkByEmail" + "resources": { + "Customer": { + "methods": { + "CreateAsync": { + "operation": "createCustomer", + "signature": "Dictionary data, Dictionary queryParams = null, CancellationToken cancellationToken = default" + }, + "ListAsync": { + "operation": "listCustomers", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "RetrieveAsync": { + "operation": "getCustomer", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "UpdateAsync": { + "operation": "editCustomer", + "bodySchema": "CustomerUpdateInput", + "signature": "string id, Dictionary data, Dictionary queryParams = null, CancellationToken cancellationToken = default" + }, + "DeleteAsync": { + "operation": "deleteCustomer", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "ValidateTaxInfoAsync": { + "operation": "validateCustomerTaxInfo", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "SendEditLinkByEmailAsync": { + "operation": "sendEditLinkByEmail", + "signature": "string id, Dictionary data, CancellationToken cancellationToken = default" + } + } + }, + "Invoice": { + "methods": { + "CreateAsync": { + "operation": "createInvoice", + "signature": "Dictionary data, Dictionary options = null, CancellationToken cancellationToken = default", + "responseSchema": "Invoice" + }, + "ListAsync": { + "operation": "listInvoices", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "RetrieveAsync": { + "operation": "getInvoice", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "GetPaymentSummaryAsync": { + "operation": "getInvoicePaymentSummary", + "signature": "string id, double amount, CancellationToken cancellationToken = default", + "queryFields": { + "amount": "amount" + } + }, + "CancelAsync": { + "operation": "cancelInvoice", + "querySchema": "CancellationQueryInput", + "signature": "string id, Dictionary query = null, CancellationToken cancellationToken = default" + }, + "SendByEmailAsync": { + "operation": "sendInvoiceByEmail", + "signature": "string id, Dictionary data = null, CancellationToken cancellationToken = default" + }, + "DownloadPdfAsync": { + "operation": "downloadInvoice", + "path": { + "format": "pdf" + }, + "signature": "string id, CancellationToken cancellationToken = default" + }, + "DownloadXmlAsync": { + "operation": "downloadInvoice", + "path": { + "format": "xml" + }, + "signature": "string id, CancellationToken cancellationToken = default" + }, + "DownloadZipAsync": { + "operation": "downloadInvoice", + "path": { + "format": "zip" + }, + "signature": "string id, CancellationToken cancellationToken = default" + }, + "DownloadPdfUrlAsync": { + "operation": "getInvoiceDownloadUrl", + "path": { + "format": "pdf" + } + }, + "DownloadXmlUrlAsync": { + "operation": "getInvoiceDownloadUrl", + "path": { + "format": "xml" + } + }, + "DownloadZipUrlAsync": { + "operation": "getInvoiceDownloadUrl", + "path": { + "format": "zip" + } + }, + "CreateZipRequestAsync": { + "operation": "createInvoiceZipRequest", + "signature": "Dictionary data, CancellationToken cancellationToken = default" + }, + "ListZipRequestsAsync": { + "operation": "listInvoiceZipRequests", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "RetrieveZipRequestAsync": { + "operation": "retrieveInvoiceZipRequest", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "DownloadZipRequestAsync": { + "operation": "downloadInvoiceZipRequest", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "DownloadZipRequestUrlAsync": { + "operation": "getInvoiceZipRequestDownloadUrl" + }, + "DownloadCancellationReceiptXmlAsync": { + "operation": "downloadCancellationReceipt", + "path": { + "format": "xml" + }, + "signature": "string id, CancellationToken cancellationToken = default" + }, + "DownloadCancellationReceiptPdfAsync": { + "operation": "downloadCancellationReceipt", + "path": { + "format": "pdf" + }, + "signature": "string id, CancellationToken cancellationToken = default" + }, + "DownloadCancellationReceiptPdfUrlAsync": { + "operation": "getCancellationReceiptDownloadUrl", + "path": { + "format": "pdf" + } + }, + "DownloadCancellationReceiptXmlUrlAsync": { + "operation": "getCancellationReceiptDownloadUrl", + "path": { + "format": "xml" + } + }, + "UpdateDraftAsync": { + "operation": "updateDraftInvoice", + "signature": "string id, Dictionary data, CancellationToken cancellationToken = default", + "responseSchema": "Invoice" + }, + "StampDraftAsync": { + "operation": "stampDraftInvoice", + "signature": "string id, Dictionary options = null, CancellationToken cancellationToken = default" + }, + "UpdateStatusAsync": { + "operation": "updateInvoiceStatus", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "CopyToDraftAsync": { + "operation": "copyToDraftInvoice", + "signature": "string id, CancellationToken cancellationToken = default", + "responseSchema": "Invoice" + }, + "PreviewPdfAsync": { + "operation": "previewInvoicePdf", + "signature": "Dictionary data, CancellationToken cancellationToken = default" + }, + "PreviewPdfUrlAsync": { + "operation": "previewInvoicePdfUrl" + }, + "StampDraft": { + "alias": "StampDraftAsync", + "signature": "string id, Dictionary options = null, CancellationToken cancellationToken = default" + } + } + }, + "Organization": { + "methods": { + "CreateAsync": { + "operation": "createOrganization", + "signature": "Dictionary data, CancellationToken cancellationToken = default" + }, + "ListAsync": { + "operation": "listOrganizations", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "RetrieveAsync": { + "operation": "getOrganization", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "UpdateLegalAsync": { + "operation": "editOrganizationLegal", + "signature": "string id, Dictionary data, CancellationToken cancellationToken = default" + }, + "UpdateCustomizationAsync": { + "operation": "editOrganizationCustomization", + "signature": "string id, Dictionary data, CancellationToken cancellationToken = default" + }, + "UpdateReceiptSettingsAsync": { + "operation": "editOrganizationReceiptsSettings", + "signature": "string id, Dictionary data, CancellationToken cancellationToken = default" + }, + "UpdateDomainAsync": { + "operation": "editOrganizationDomain", + "signature": "string id, Dictionary data, CancellationToken cancellationToken = default" + }, + "CheckDomainIsAvailableAsync": { + "operation": "checkDomainAvailability", + "signature": "string domain, CancellationToken cancellationToken = default", + "queryFields": { + "domain": "domain" + } + }, + "UploadLogoAsync": { + "operation": "uploadOrganizationLogo", + "signature": "string id, Stream file, CancellationToken cancellationToken = default", + "multipart": { + "file": "file" + } + }, + "UploadCertificateAsync": { + "operation": "uploadOrganizationCertificate", + "signature": "string id, Stream cerFile, Stream keyFile, string password, CancellationToken cancellationToken = default", + "multipart": { + "cer": "cerFile", + "key": "keyFile", + "password": "password" + } + }, + "DeleteCertificateAsync": { + "operation": "deleteOrganizationCertificate", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "DownloadManifiestoZipUrlAsync": { + "operation": "getOrganizationManifiestoDownloadUrl" + }, + "DeleteAsync": { + "operation": "deleteOrganization", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "GetTestApiKeyAsync": { + "operation": "getTestApiKey", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "RenewTestApiKeyAsync": { + "operation": "renewTestApiKey", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "ListLiveApiKeysAsync": { + "operation": "listLiveApiKeys", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "RenewLiveApiKeyAsync": { + "operation": "renewLiveApiKey", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "DeleteLiveApiKeyAsync": { + "operation": "deleteLiveApiKey", + "signature": "string id, string apiKeyId, CancellationToken cancellationToken = default" + }, + "ListSeriesAsync": { + "operation": "getSeriesGroup", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "CreateSeriesAsync": { + "operation": "createSeriesGroup", + "signature": "string id, Dictionary data, CancellationToken cancellationToken = default" + }, + "UpdateSeriesAsync": { + "operation": "updateSeriesGroup", + "signature": "string id, string seriesName, Dictionary data, CancellationToken cancellationToken = default" + }, + "UpdateDefaultSeriesAsync": { + "operation": "updateDefaultSeries", + "signature": "string organizationId, Dictionary data, CancellationToken cancellationToken = default" + }, + "DeleteSeriesAsync": { + "operation": "deleteSeriesGroup", + "signature": "string id, string seriesName, CancellationToken cancellationToken = default" + }, + "MeAsync": { + "operation": "meOrganization", + "signature": "CancellationToken cancellationToken = default" + }, + "UpdateSelfInvoiceSettingsAsync": { + "operation": "editOrganizationSelfInvoiceSettings", + "signature": "string organizationId, Dictionary data, CancellationToken cancellationToken = default" + }, + "ListTeamAccessAsync": { + "operation": "getOrganizationTeam", + "signature": "string organizationId, CancellationToken cancellationToken = default" + }, + "RetrieveTeamAccessAsync": { + "operation": "getOrganizationTeamUser", + "signature": "string organizationId, string accessId, CancellationToken cancellationToken = default" + }, + "UpdateTeamAccessRoleAsync": { + "operation": "updateOrganizationTeamUserRole", + "signature": "string organizationId, string accessId, string role, CancellationToken cancellationToken = default", + "bodyFields": { + "role": "role" + } + }, + "RemoveTeamAccessAsync": { + "operation": "removeOrganizationUserAccess", + "signature": "string organizationId, string accessId, CancellationToken cancellationToken = default", + "resultProperty": "ok" + }, + "ListSentTeamInvitesAsync": { + "operation": "listOrganizationTeamInvites", + "signature": "string organizationId, CancellationToken cancellationToken = default" + }, + "InviteUserToTeamAsync": { + "operation": "createOrganizationTeamInvite", + "signature": "string organizationId, Dictionary data, CancellationToken cancellationToken = default" + }, + "CancelTeamInviteAsync": { + "operation": "deleteOrganizationTeamInvite", + "signature": "string organizationId, string inviteKey, CancellationToken cancellationToken = default", + "resultProperty": "ok" + }, + "ListReceivedTeamInvitesAsync": { + "operation": "listPendingOrganizationInvites", + "signature": "CancellationToken cancellationToken = default" + }, + "RespondTeamInviteAsync": { + "operation": "respondOrganizationInvite", + "signature": "string inviteKey, Dictionary data, CancellationToken cancellationToken = default", + "resultProperty": "ok" + }, + "ListTeamRolesAsync": { + "operation": "listOrganizationPermissionRoles", + "signature": "string organizationId, CancellationToken cancellationToken = default" + }, + "ListTeamRoleTemplatesAsync": { + "operation": "listOrganizationPermissionRoleTemplates", + "signature": "string organizationId, CancellationToken cancellationToken = default" + }, + "ListTeamRoleOperationsAsync": { + "operation": "listOrganizationPermissionOperations", + "signature": "string organizationId, CancellationToken cancellationToken = default" + }, + "RetrieveTeamRoleAsync": { + "operation": "getOrganizationPermissionRole", + "signature": "string organizationId, string roleId, CancellationToken cancellationToken = default" + }, + "CreateTeamRoleAsync": { + "operation": "createOrganizationPermissionRole", + "signature": "string organizationId, Dictionary data, CancellationToken cancellationToken = default" + }, + "UpdateTeamRoleAsync": { + "operation": "updateOrganizationPermissionRole", + "signature": "string organizationId, string roleId, Dictionary data, CancellationToken cancellationToken = default" + }, + "DeleteTeamRoleAsync": { + "operation": "deleteOrganizationPermissionRole", + "signature": "string organizationId, string roleId, CancellationToken cancellationToken = default", + "resultProperty": "ok" + }, + "UploadFielAsync": { + "operation": "uploadOrganizationFiel", + "multipart": { + "cer": "cerFile", + "key": "keyFile", + "password": "password" + }, + "signature": "string id, Stream cerFile, Stream keyFile, string password, CancellationToken cancellationToken = default" + } + } + }, + "Product": { + "methods": { + "CreateAsync": { + "operation": "createProduct", + "signature": "Dictionary data, CancellationToken cancellationToken = default" + }, + "ListAsync": { + "operation": "listProducts", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "RetrieveAsync": { + "operation": "getProduct", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "UpdateAsync": { + "operation": "editProduct", + "signature": "string id, Dictionary data, CancellationToken cancellationToken = default" + }, + "DeleteAsync": { + "operation": "deleteProduct", + "signature": "string id, CancellationToken cancellationToken = default" + } + } + }, + "Receipt": { + "methods": { + "CreateAsync": { + "operation": "createReceipt", + "signature": "Dictionary data, CancellationToken cancellationToken = default" + }, + "ListAsync": { + "operation": "listReceipts", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "RetrieveAsync": { + "operation": "getReceipt", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "InvoiceAsync": { + "operation": "invoiceReceipt", + "signature": "string id, Dictionary data, CancellationToken cancellationToken = default" + }, + "CreateGlobalInvoiceAsync": { + "operation": "createGlobalInvoice", + "signature": "Dictionary data, CancellationToken cancellationToken = default" + }, + "ToInvoiceAsync": { + "operation": "createToInvoiceFromReceipts", + "signature": "Dictionary data, CancellationToken cancellationToken = default" + }, + "PreviewToInvoicePdfAsync": { + "operation": "previewToInvoiceFromReceipts", + "signature": "Dictionary data, CancellationToken cancellationToken = default" + }, + "PreviewToInvoicePdfUrlAsync": { + "operation": "previewToInvoiceFromReceiptsUrl" + }, + "CancelAsync": { + "operation": "cancelReceipt", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "SendByEmailAsync": { + "operation": "sendReceiptByEmail", + "signature": "string id, Dictionary data = null, CancellationToken cancellationToken = default" + }, + "DownloadPdfAsync": { + "operation": "downloadReceiptPdf", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "DownloadPdfUrlAsync": { + "operation": "getReceiptDownloadUrl" + }, + "UpdateCustomerAsync": { + "operation": "assignReceiptCustomer" + }, + "SummarizeToInvoiceAsync": { + "operation": "createToInvoiceFromReceipts", + "responseSchema": "ToInvoiceSummary", + "bodyFlags": { + "dry_run": true + } + } + } + }, + "Retention": { + "methods": { + "CreateAsync": { + "operation": "createRetention", + "signature": "Dictionary data, CancellationToken cancellationToken = default" + }, + "ListAsync": { + "operation": "listRetentions", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "RetrieveAsync": { + "operation": "getRetention", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "CancelAsync": { + "operation": "cancelRetention", + "querySchema": "CancellationQueryInput", + "signature": "string id, Dictionary query = null, CancellationToken cancellationToken = default" + }, + "UpdateDraftAsync": { + "operation": "updateDraftRetention", + "signature": "string id, Dictionary data, CancellationToken cancellationToken = default" + }, + "StampDraftAsync": { + "operation": "stampDraftRetention", + "signature": "string id, Dictionary options = null, CancellationToken cancellationToken = default" + }, + "CopyToDraftAsync": { + "operation": "copyToDraftRetention", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "SendByEmailAsync": { + "operation": "sendRetentionByEmail", + "signature": "string id, Dictionary data = null, CancellationToken cancellationToken = default" + }, + "DownloadPdfAsync": { + "operation": "downloadRetention", + "path": { + "format": "pdf" + }, + "signature": "string id, CancellationToken cancellationToken = default" + }, + "DownloadXmlAsync": { + "operation": "downloadRetention", + "path": { + "format": "xml" + }, + "signature": "string id, CancellationToken cancellationToken = default" + }, + "DownloadZipAsync": { + "operation": "downloadRetention", + "path": { + "format": "zip" + }, + "signature": "string id, CancellationToken cancellationToken = default" + }, + "DownloadPdfUrlAsync": { + "operation": "getRetentionDownloadUrl", + "path": { + "format": "pdf" + } + }, + "DownloadXmlUrlAsync": { + "operation": "getRetentionDownloadUrl", + "path": { + "format": "xml" + } + }, + "DownloadZipUrlAsync": { + "operation": "getRetentionDownloadUrl", + "path": { + "format": "zip" + } + } + } + }, + "CartaporteCatalog": { + "methods": { + "SearchAirTransportCodes": { + "operation": "searchCartaPorteAirTransportCodes", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "SearchTransportConfigs": { + "operation": "searchCartaPorteTransportConfigs", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "SearchRightsOfPassage": { + "operation": "searchCartaPorteRightsOfPassage", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "SearchCustomsDocuments": { + "operation": "searchCartaPorteCustomsDocuments", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "SearchPackagingTypes": { + "operation": "searchCartaPortePackagingTypes", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "SearchTrailerTypes": { + "operation": "searchCartaPorteTrailerTypes", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "SearchHazardousMaterials": { + "operation": "searchCartaPorteHazardousMaterials", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "SearchNavalAuthorizations": { + "operation": "searchCartaPorteNavalAuthorizations", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "SearchPortStations": { + "operation": "searchCartaPortePortStations", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "SearchMarineContainers": { + "operation": "searchCartaPorteMarineContainers", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + } + } + }, + "Catalog": { + "methods": { + "SearchProducts": { + "operation": "searchProducts", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "SearchUnits": { + "operation": "searchUnits", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "ListProductCategories": { + "operation": "listProductCategories" + }, + "GetProductCategory": { + "operation": "getProductCategory" + }, + "SearchZipCodes": { + "operation": "searchZipCodes" + }, + "GetZipCode": { + "operation": "getZipCode" + }, + "SearchCountries": { + "operation": "searchCountries" + }, + "SearchTaxSystems": { + "operation": "searchTaxSystems" + }, + "SearchInvoiceUses": { + "operation": "searchInvoiceUses" + } + } + }, + "ComercioExteriorCatalog": { + "methods": { + "SearchTariffFractions": { + "operation": "searchComercioExteriorTariffFractions" + } + } + }, + "Tool": { + "methods": { + "ValidateTaxIdAsync": { + "operation": "validateTaxId", + "signature": "string taxId, CancellationToken cancellationToken = default", + "queryFields": { + "tax_id": "taxId" + } + }, + "HealthCheckAsync": { + "operation": "checkApiHealth", + "signature": "CancellationToken cancellationToken = default", + "resultProperty": "ok" + } + } + }, + "Webhook": { + "methods": { + "CreateAsync": { + "operation": "createWebhook", + "signature": "Dictionary data, CancellationToken cancellationToken = default" + }, + "ListAsync": { + "operation": "listWebhooks", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "RetrieveAsync": { + "operation": "getWebhook", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "UpdateAsync": { + "operation": "editWebhook", + "signature": "string id, Dictionary data, CancellationToken cancellationToken = default" + }, + "DeleteAsync": { + "operation": "deleteWebhook", + "signature": "string id, CancellationToken cancellationToken = default" + }, + "ValidateSignatureRemotelyAsync": { + "operation": "validateWebhookSignature" + } + } + }, + "NominaCatalog": { + "methods": { + "SearchDeductions": { + "operation": "searchNominaDeductions", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + }, + "SearchPerceptions": { + "operation": "searchNominaPerceptions", + "signature": "Dictionary query = null, CancellationToken cancellationToken = default" + } + } + } + }, + "modelNames": { + "CustomerAddress": "Address", + "OrganizationSeriesGroup": "SeriesGroup", + "OrganizationPermissionRole": "OrganizationTeamRole", + "OrganizationPermissionRoleTemplate": "OrganizationTeamRoleTemplate", + "TaxIdValidationResult": "TaxIdValidation", + "NamespaceProperties": "Namespace", + "ThirdParty": "InvoiceItemThirdParty", + "Parts": "InvoiceItemPart", + "BaseTax": "Tax", + "InvoiceItemProduct": "ProductInfo", + "OrganizationLegal": "Legal", + "OrganizationPendingStepsItem": "CompletionStep", + "OrganizationCustomization": "Customization", + "OrganizationSelfInvoice": "SelfInvoiceSettings", + "OrganizationCertificate": "Certificate", + "OrganizationFiel": "FielCertificate", + "ListLiveApiKeysResponseItem": "LiveApiKey", + "DeleteLiveApiKeyResponseItem": "LiveApiKey", + "CheckDomainAvailabilityResponse": "DomainAvailability", + "ValidateCustomerTaxInfoResponse": "TaxInfoValidation", + "TaxInfoValidationErrorsItem": "TaxInfoError", + "GetInvoicePaymentSummaryResponse": "PaymentSummary", + "PaymentSummaryTaxesItem": "PaymentSummaryTax", + "SearchKeyDescriptionResultDataItem": "CatalogItem", + "RetentionPeriodo": "RetentionPeriod", + "RetentionTotales": "RetentionTotals", + "RetentionTotalsImpRetenidosItem": "RetentionRetainedTax", + "TaxInfoValidationEfos": "Efos", + "EfosData": "EfosData", + "EfosDataDetallesItem": "EfosDetalle", + "InvoiceGlobal": "Global", + "RelatedDocument": "PaymentRelated", + "PaymentProperties": "Payment", + "InvoicePdfExtra": "PdfExtra", + "SendEditLinkByEmailResponse": "CustomerEditLinkEmailResult", + "TaxIdValidationEfosData": "EfosData", + "InvoiceStamp": "Stamp", + "InvoiceAddress": "Address", + "ProductCatalogResult": "CatalogItem", + "UnitCatalogResult": "CatalogItem", + "CatalogEntry": "CatalogItem", + "TaxIdValidationEfos": "Efos" }, "inputs": [ "CustomerNationalCreateInput", @@ -15,11 +723,133 @@ "CustomerGenericCreateInput", "CustomerCreateWithEditLinkInput", "CustomerUpdateInput", - "CustomerUpdateWithEditLinkInput" + "CustomerUpdateWithEditLinkInput", + "CancellationQueryInput" ], - "modelNames": { - "CustomerAddress": "Address", - "ValidateCustomerTaxInfoResponse": "TaxInfoValidation", - "TaxInfoValidationErrorsItem": "TaxInfoValidationError" + "outputModels": [ + "ApiEvent", + "InvoiceStamped", + "InvoiceDraft", + "InvoicePending", + "InvoiceFailed", + "PaymentProperties", + "GenericError", + "ErrorDetail" + ], + "convenience": { + "Customer": { + "CreateNationalAsync": { + "method": "CreateAsync", + "schema": "CustomerNationalCreateInput" + }, + "CreateForeignAsync": { + "method": "CreateAsync", + "schema": "CustomerForeignCreateInput" + }, + "CreateGenericAsync": { + "method": "CreateAsync", + "schema": "CustomerGenericCreateInput" + }, + "CreateWithEditLinkAsync": { + "method": "CreateAsync", + "schema": "CustomerCreateWithEditLinkInput", + "query": { + "createEditLink": true + } + }, + "UpdateWithEditLinkAsync": { + "method": "UpdateAsync", + "schema": "CustomerUpdateWithEditLinkInput", + "query": { + "createEditLink": true + } + } + }, + "Invoice": { + "CreateIngresoAsync": { + "method": "CreateAsync", + "schema": "InvoiceIngresoInput" + }, + "CreateEgresoAsync": { + "method": "CreateAsync", + "schema": "InvoiceEgresoInput" + }, + "CreatePagoAsync": { + "method": "CreateAsync", + "schema": "InvoicePagoInput" + }, + "CreateNominaAsync": { + "method": "CreateAsync", + "schema": "InvoiceNominaInput" + }, + "CreateTrasladoAsync": { + "method": "CreateAsync", + "schema": "InvoiceTrasladoInput" + }, + "CreateDraftIngresoAsync": { + "method": "CreateAsync", + "schema": "InvoiceIngresoDraftInput" + }, + "CreateDraftEgresoAsync": { + "method": "CreateAsync", + "schema": "InvoiceEgresoDraftInput" + }, + "CreateDraftPagoAsync": { + "method": "CreateAsync", + "schema": "InvoicePagoDraftInput" + }, + "CreateDraftNominaAsync": { + "method": "CreateAsync", + "schema": "InvoiceNominaDraftInput" + }, + "CreateDraftTrasladoAsync": { + "method": "CreateAsync", + "schema": "InvoiceTrasladoDraftInput" + } + } + }, + "variants": { + "CancellationWithSubstitutionInput": { + "schema": "CancellationQueryInput", + "match": { + "motive": ["01", "04"] + }, + "parent": true + }, + "InvoiceIngresoDraftInput": { + "schema": "InvoiceCreateInput", + "match": { + "type": "I", + "status": "draft" + } + }, + "InvoiceEgresoDraftInput": { + "schema": "InvoiceCreateInput", + "match": { + "type": "E", + "status": "draft" + } + }, + "InvoicePagoDraftInput": { + "schema": "InvoiceCreateInput", + "match": { + "type": "P", + "status": "draft" + } + }, + "InvoiceNominaDraftInput": { + "schema": "InvoiceCreateInput", + "match": { + "type": "N", + "status": "draft" + } + }, + "InvoiceTrasladoDraftInput": { + "schema": "InvoiceCreateInput", + "match": { + "type": "T", + "status": "draft" + } + } } } diff --git a/scripts/sdk/render-models.mjs b/scripts/sdk/render-models.mjs index 24905db..0d6506c 100644 --- a/scripts/sdk/render-models.mjs +++ b/scripts/sdk/render-models.mjs @@ -1,7 +1,12 @@ import { pascal, camel } from "./compiler.mjs"; - +export const csIdentifier = (value) => "@" + value; export const banner = "// Generated by pnpm generate:sdk. Do not edit directly.\n"; +export const xml = (value = "") => + value + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">"); export function text(value = "") { return value .replace( @@ -14,27 +19,40 @@ export function text(value = "") { export function doc(value, indent = "") { return `${indent}/// \n${text(value) .split("\n") - .map( - (line) => - `${indent}/// ${line.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">")}`, - ) + .map((line) => `${indent}/// ${xml(line)}`) .join("\n")}\n${indent}/// \n`; } export function fieldType(field, optional = true) { const type = - field.kind === "model" + field.kind === "model" || field.kind === "parameter" ? field.ref : field.kind === "array" - ? `${fieldType(field.item, false)}[]` - : { - string: "string", - date: "DateTime", - boolean: "bool", - integer: "int", - number: "double", - }[field.kind]; - return ["boolean", "integer", "number", "date"].includes(field.kind) && - (field.nullable || (optional && !field.required)) + ? `List<${fieldType(field.item, false)}>` + : field.kind === "pagination" + ? `SearchResult<${fieldType(field.item, false)}>` + : field.kind === "map" + ? `Dictionary` + : field.kind === "union" + ? `OneOf<${[...new Set(field.variants.map((variant) => fieldType(variant, false).replace(/\?$/, "")))].join(", ")}>` + : field.kind === "inputDate" + ? "OneOf" + : { + string: "string", + date: "DateTime", + boolean: "bool", + integer: "int", + number: "decimal", + binary: "Stream", + any: "object", + null: "object", + never: "object", + void: "void", + }[field.kind]; + if (type === "void") return type; + return field.kind === "any" || + field.kind === "null" || + field.nullable || + (optional && !field.required) ? type + "?" : type; } @@ -49,55 +67,225 @@ export function description(field) { .filter(Boolean) .join("\n"); } - export function renderModels(contract) { const outputs = new Map(); for (const model of contract.models) { - const name = - model.name === "CustomerSearchResult" - ? "SearchResult" - : model.name === "TaxInfoValidationError" - ? "TaxInfoError" - : model.name; + const parent = contract.models.find( + (candidate) => candidate.name === model.parent, + ); let content = banner + - "using System;\nusing System.Collections.Generic;\nusing Newtonsoft.Json;\n\nnamespace Facturapi\n{\n"; + "#nullable enable\nusing System;\nusing System.IO;\nusing System.Collections.Generic;\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Linq;\n\nnamespace Facturapi\n{\n"; + const discriminated = Object.entries(model.variantMappings || {}).flatMap( + ([key, cases]) => { + return model.properties + .filter((field) => field.kind === "union") + .flatMap((field) => { + const variants = new Set( + field.variants.map((variant) => + fieldType(variant, false).replace(/\?$/, ""), + ), + ); + const values = Object.entries(cases).filter( + ([, fields]) => fields[field.name], + ); + const targets = new Set( + values.map(([, fields]) => + fieldType(fields[field.name], false).replace(/\?$/, ""), + ), + ); + return values.length > 1 && + targets.size === variants.size && + [...targets].every((type) => variants.has(type)) + ? [{ key, field, values }] + : []; + }); + }, + ); content += - doc( - model.name === "CustomerSearchResult" - ? "Resultados paginados." - : model.description, - " ", - ) + - ` public class ${name}${model.input ? " : Dictionary" : ""}\n {\n`; + doc(model.generic ? "Resultados paginados." : model.description, " ") + + (discriminated.length + ? ` [JsonConverter(typeof(${model.name}JsonConverter))]\n` + : "") + + ` public class ${model.name}${model.generic ? "" : ""}${model.parent ? " : " + model.parent : model.input ? " : Dictionary" : ""}\n {\n`; + const fixed = model.input + ? model.properties.filter( + (field) => + ["type", "status"].includes(field.name) && + field.values?.length === 1 && + !field.nullable, + ) + : []; const required = model.input - ? model.properties.filter((field) => field.required) + ? model.properties.filter( + (field) => field.required && !fixed.includes(field), + ) : []; - if (required.length) { - content += doc(`Crea ${name}.`, " "); + if (required.length || fixed.length) { + content += doc(`Crea ${model.name}.`, " "); for (const field of required) - content += ` /// ${text(description(field)).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\n", " ")}\n`; - content += ` public ${name}(${required.map((field) => `${fieldType(field)} ${camel(field.name)}`).join(", ")})\n {\n${required.map((field) => ` this[${JSON.stringify(field.name)}] = ${camel(field.name)};`).join("\n")}\n }\n\n`; + content += ` /// ${xml(text(description(field))).replaceAll("\n", " ")}\n`; + content += ` public ${model.name}(${required.map((field) => `${fieldType(field)} ${csIdentifier(camel(field.name))}`).join(", ")})${ + parent + ? " : base(" + + parent.properties + .filter( + (field) => + field.required && + !( + ["type", "status"].includes(field.name) && + field.values?.length === 1 && + !field.nullable + ), + ) + .map((field) => { + const own = model.properties.find( + (candidate) => candidate.name === field.name, + ); + return fixed.includes(own) + ? JSON.stringify(own.values[0]) + : csIdentifier(camel(field.name)); + }) + .join(", ") + + ")" + : "" + }\n {\n${required + .map( + (field) => + ` this[${JSON.stringify(field.name)}] = ${csIdentifier(camel(field.name))}${["union", "inputDate"].includes(field.kind) ? (fieldType(field).endsWith("?") ? "?.Value" : ".Value") : ""};`, + ) + .concat( + fixed.map( + (field) => + ` this[${JSON.stringify(field.name)}] = ${JSON.stringify(field.values[0])};`, + ), + ) + .join("\n")}\n }\n\n`; } for (const field of model.properties) { const type = - model.name === "CustomerSearchResult" && field.name === "data" - ? "List" - : field.kind === "array" && - field.item.ref === "TaxInfoValidationError" - ? "TaxInfoError[]" - : fieldType(field); + model.name === "TaxInfoValidation" && field.name === "errors" + ? "TaxInfoError[]" + : fieldType(field); content += doc(description(field), " "); - if (model.input) - content += ` [JsonIgnore]\n public ${type} ${pascal(field.name)}\n {\n get => TryGetValue(${JSON.stringify(field.name)}, out var value) ? (${type})value : default;\n set => this[${JSON.stringify(field.name)}] = value;\n }\n\n`; - else - content += ` [JsonProperty(${JSON.stringify(field.name)})]\n public ${type} ${pascal(field.name)} { get; set; }\n\n`; + if (model.input) { + const modifier = + [ + "Keys", + "Values", + "Count", + "Comparer", + "Item", + "Add", + "Remove", + "Clear", + "ContainsKey", + "ContainsValue", + "TryGetValue", + "GetEnumerator", + "CopyTo", + "Equals", + "GetHashCode", + "GetType", + "ToString", + ].includes(pascal(field.name)) || + parent?.properties.some((property) => property.name === field.name) + ? "new " + : ""; + const isUnion = ["union", "inputDate"].includes(field.kind); + const getter = + isUnion && type.endsWith("?") + ? `TryGetValue(${JSON.stringify(field.name)}, out var value) && value != null ? ${type.slice(0, -1)}.FromValue(value) : default(${type})` + : `TryGetValue(${JSON.stringify(field.name)}, out var value) ? ${isUnion ? type + ".FromValue(value)" : "(" + type + ")value!"} : default!`; + + content += ` [JsonIgnore]\n public ${modifier}${type} ${pascal(field.name)}\n {\n get => ${getter};\n set => this[${JSON.stringify(field.name)}] = ${isUnion ? "value" + (type.endsWith("?") ? "?.Value" : ".Value") : "value"};\n }\n\n`; + } else + content += ` [JsonProperty(${JSON.stringify(field.name)})]\n public ${type} ${pascal(field.name)} { get; set; } = default!;\n\n`; } + if (!model.input && model.additional) + content += + doc("Propiedades adicionales del objeto JSON.", " ") + + " [JsonExtensionData]\n public IDictionary? AdditionalProperties { get; set; }\n"; content += " }\n}\n"; + if (discriminated.length) { + let converter = + banner + + "#nullable enable\nusing System;\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Linq;\nnamespace Facturapi\n{\n" + + ` internal sealed class ${model.name}JsonConverter : JsonConverter\n {\n public override bool CanWrite => false;\n public override bool CanConvert(Type type) => type == typeof(${model.name});\n public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) => throw new NotSupportedException();\n public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)\n {\n if (reader.TokenType == JsonToken.Null) return null;\n var data = JObject.Load(reader);\n var result = new ${model.name}();\n`; + for (const { field } of discriminated) + converter += ` var ${csIdentifier(camel(field.name))} = data[${JSON.stringify(field.name)}];\n data.Remove(${JSON.stringify(field.name)});\n`; + converter += + " using (var content = data.CreateReader()) serializer.Populate(content, result);\n"; + for (const { key, field, values } of discriminated) { + converter += ` if (${csIdentifier(camel(field.name))} != null && ${csIdentifier(camel(field.name))}.Type != JTokenType.Null)\n {\n switch ((string?)data[${JSON.stringify(key)}])\n {\n`; + for (const [value, fields] of values) + converter += ` case ${JSON.stringify(value)}: result.${pascal(field.name)} = ${csIdentifier(camel(field.name))}.ToObject<${fieldType(fields[field.name], false).replace(/\?$/, "")}>(serializer)!; break;\n`; + converter += + ' default: throw new JsonSerializationException("Unknown discriminator value for a documented response alternative.");\n }\n }\n'; + } + converter += " return result;\n }\n }\n}\n"; + outputs.set(`Models/${model.name}.JsonConverter.cs`, converter); + } outputs.set( - `Models/${model.input ? "Inputs/" : ""}${name.replace("", "")}.cs`, + `Models/${model.input ? "Inputs/" : ""}${model.name}.cs`, content, ); } + // Typed alternatives serialize as their value, without a JSON envelope. + const arities = new Set([2]); + for (const model of contract.models) + for (const field of model.properties) + for (const match of fieldType(field).matchAll(/OneOf" && depth-- === 0) break; + else if (char === "," && depth === 0) arity++; + } + arities.add(arity); + } + for (const method of contract.methods.filter((method) => method.response)) { + if (method.response.kind === "union") + arities.add( + new Set( + method.response.variants.map((variant) => fieldType(variant, false)), + ).size, + ); + } + for (const count of arities) { + if (count < 2) continue; + const types = Array.from( + { length: count }, + (_, index) => `T${index + 1}`, + ).join(", "); + outputs.set( + `Models/OneOf${count}.cs`, + banner + + `#nullable enable\nusing System;\nusing Newtonsoft.Json;\n\nnamespace Facturapi\n{\n` + + doc( + "Una de las alternativas del contrato. Se serializa sin envoltura JSON.", + " ", + ) + + ` [JsonConverter(typeof(OneOfConverter))]\n public readonly struct OneOf<${types}> : IOneOfValue\n {\n` + + doc("Valor de la alternativa seleccionada.", " ") + + ` public object? Value { get; }\n private OneOf(object? value) { Value = value; }\n internal static OneOf<${types}> FromValue(object? value) => new OneOf<${types}>(value);\n` + + Array.from( + { length: count }, + (_, index) => + doc(`Selecciona la alternativa ${index + 1}.`, " ") + + ` public static implicit operator OneOf<${types}>(T${index + 1} value) => new OneOf<${types}>(value);\n`, + ).join("") + + doc( + "Obtiene el valor cuando coincide con el tipo solicitado.", + " ", + ) + + ` public bool TryGet(out T value)\n {\n if (Value is T match) { value = match; return true; }\n value = default!;\n return false;\n }\n` + + doc("Representación del valor seleccionado.", " ") + + ` public override string ToString() => Value?.ToString() ?? string.Empty;\n }\n}\n`, + ); + } return outputs; } diff --git a/scripts/sdk/render-resources.mjs b/scripts/sdk/render-resources.mjs index 6803842..a03e24b 100644 --- a/scripts/sdk/render-resources.mjs +++ b/scripts/sdk/render-resources.mjs @@ -1,142 +1,287 @@ -import { pascal } from "./compiler.mjs"; -import { banner, doc, text } from "./render-models.mjs"; +import assert from "node:assert/strict"; +import { pascal, camel } from "./compiler.mjs"; +import { banner, doc, text, xml, fieldType } from "./render-models.mjs"; -const convenience = [ - ["createNational", "CustomerNationalCreateInput", "create"], - ["createForeign", "CustomerForeignCreateInput", "create"], - ["createGeneric", "CustomerGenericCreateInput", "create"], - ["createWithEditLink", "CustomerCreateWithEditLinkInput", "create"], - ["updateWithEditLink", "CustomerUpdateWithEditLinkInput", "update"], -]; - -function methodProse(method, parameters) { +function parseSignature(signature) { + return signature.split(/,(?![^<]*>)/).map((argument) => { + const match = argument.trim().match(/^(.+?)\s+(\w+)(?:\s*=\s*(.+))?$/); + assert(match, `Invalid compatibility argument: ${argument}`); + return { type: match[1], name: match[2], default: match[3] }; + }); +} +function documentation(method, argumentsList) { return ( doc( [method.summary, method.description].filter(Boolean).join("\n\n"), " ", ) + - parameters + argumentsList .map( - ([name, type, description]) => - ` /// ${text(description).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\n", " ")}\n`, + (argument) => + ` /// ${xml(text(argument.description || (argument.name === "cancellationToken" ? "Permite cancelar la solicitud." : argument.name))).replaceAll("\n", " ")}\n`, ) .join("") + - ` /// ${text( - method.responseDescription || "Respuesta de la API.", - ) - .replaceAll("&", "&") - .replaceAll("<", "<") - .replaceAll( - ">", - ">", - )}\n /// \n` + ` /// ${xml(text(method.response.kind === "binary" ? "Stream en memoria, posicionado al inicio. El consumidor debe disponerlo al terminar." : method.responseDescription || "Respuesta de la API.")).replaceAll("\n", " ")}\n /// \n` ); } - -export function renderResources(contract) { +export function renderResources(contract, config) { const outputs = new Map(); - let content = - banner + - "using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\n\nnamespace Facturapi.Wrappers\n{\n" + - doc("Operaciones de clientes.", " ") + - " public class CustomerWrapper : BaseWrapper, ICustomerWrapper\n {\n internal CustomerWrapper(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) {}\n\n"; - let interfaces = - banner + - "using System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Facturapi.Wrappers\n{\n" + - doc("Operaciones de clientes para inyección de dependencias.", " ") + - " public interface ICustomerWrapper\n {\n"; - let router = - banner + - "using System;\nusing System.Collections.Generic;\n\nnamespace Facturapi\n{\n internal static partial class Router\n {\n"; - for (const method of contract.methods) { - const id = method.parameters.find((parameter) => parameter.in === "path"); - const hasBody = Boolean(method.requestBody); - const paramsName = method.name === "list" ? "query" : "queryParams"; - const parameters = [ - ...(id ? [["id", "string", id.description]] : []), - ...(hasBody - ? [ - [ - "data", - "Dictionary", - `Datos de la solicitud. ${method.name === "sendEditLinkByEmail" ? "Admite CustomerEditLinkEmailInput." : "Admite los modelos Customer*Input."}`, - ], - ] - : []), - ...(method.query - ? [ - [ - paramsName, - "Dictionary", - `Parámetros de consulta. Admite ${method.query.ref}.`, - ], - ] - : []), - [ - "cancellationToken", - "CancellationToken", - "Permite cancelar la solicitud.", - ], - ]; - const signature = parameters - .map( - ([name, type]) => - `${type} ${name}${name === paramsName ? " = null" : name === "cancellationToken" ? " = default" : ""}`, - ) - .join(", "); - const returnType = - method.name === "sendEditLinkByEmail" - ? "Task" - : `Task<${method.name === "list" ? "SearchResult" : method.response.ref}>`; - const declaration = `${returnType} ${pascal(method.name)}Async(${signature})`; - interfaces += - methodProse(method, parameters) + ` ${declaration};\n\n`; - content += - methodProse(method, parameters) + - ` public async ${declaration}\n {\n`; - const routeName = { - list: "ListCustomers", - retrieve: "RetrieveCustomer", - create: "CreateCustomer", - update: "UpdateCustomer", - delete: "DeleteCustomer", - validateTaxInfo: "ValidateCustomerTaxInfo", - sendEditLinkByEmail: "SendEditLinkByEmail", - }[method.name]; - router += ` public static string ${routeName}(${[...(id ? ["string id"] : []), ...(method.query ? ["Dictionary query = null"] : [])].join(", ")})\n {\n return UriWithQuery($"${method.path.slice(1).replace(/\{[^}]+\}/g, "{Uri.EscapeDataString(id)}")}"${method.query ? ", query" : ""});\n }\n\n`; - const route = `Router.${routeName}(${[...(id ? ["id"] : []), ...(method.query ? [paramsName] : [])].join(", ")})`; - if (hasBody) + for (const resource of Object.keys(config.resources)) { + const wrapper = resource + "Wrapper"; + let content = + banner + + "#nullable enable\nusing System;\nusing System.IO;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading;\nusing System.Threading.Tasks;\n#nullable disable\nusing JsonObject = System.Collections.Generic.Dictionary;\n#nullable enable\n\nnamespace Facturapi.Wrappers\n{\n" + + doc(`Operaciones de ${resource}.`, " ") + + ` public partial class ${wrapper} : BaseWrapper, I${wrapper}\n {\n internal ${wrapper}(string apiKey, string apiVersion, HttpClient httpClient) : base(apiKey, apiVersion, httpClient) {}\n\n`; + let interfaces = + banner + + "#nullable enable\nusing System;\nusing System.IO;\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\n#nullable disable\nusing JsonObject = System.Collections.Generic.Dictionary;\n#nullable enable\n\nnamespace Facturapi.Wrappers\n{\n" + + doc( + `Operaciones de ${resource} para inyección de dependencias.`, + " ", + ) + + ` public partial interface I${wrapper}\n {\n`; + for (const method of contract.methods.filter( + (method) => method.resource === resource && !method.alias, + )) { + const pathParameters = method.parameters.filter( + (parameter) => + parameter.in === "path" && + !(parameter.name in (method.fixedPath || {})), + ); + let argumentsList = method.signature + ? parseSignature(method.signature) + : [ + ...pathParameters.map((parameter, index) => ({ + name: + pathParameters.length === 1 && /_id$/.test(parameter.name) + ? "id" + : camel(parameter.name), + type: "string", + description: parameter.description, + })), + ...(method.body + ? [ + { + name: "data", + type: "Dictionary", + ...(!method.bodyRequired ? { default: "null" } : {}), + }, + ] + : []), + ...(method.query + ? [ + { + name: "query", + type: "Dictionary", + default: "null", + }, + ] + : []), + { + name: "cancellationToken", + type: "CancellationToken", + default: "default", + }, + ]; + const pathArguments = argumentsList + .filter((argument) => argument.type === "string") + .slice(0, pathParameters.length); + assert.equal( + pathArguments.length, + pathParameters.length, + `Bind path arguments for ${method.name}`, + ); + let path = method.httpPath; + for (const [name, value] of Object.entries(method.fixedPath || {})) + path = path.replace(`{${name}}`, value); + pathParameters.forEach((parameter, index) => { + path = path.replace( + `{${parameter.name}}`, + `{Uri.EscapeDataString(${pathArguments[index].name})}`, + ); + pathArguments[index].description = parameter.description; + }); + if (method.multipart) + for (const [field, name] of Object.entries(method.multipart)) { + const argument = argumentsList.find( + (argument) => argument.name === name, + ); + argument.description = + contract.models + .find((model) => model.name === method.body.ref) + ?.properties.find((property) => property.name === field) + ?.description || name; + if (argument.type === "Stream") + argument.description += + " Usa un Stream; se dispone al finalizar la solicitud."; + } + const bodyArgument = + method.body && !method.multipart && !method.bodyFields + ? argumentsList.find((argument) => + argument.type.startsWith("Dictionary<"), + ) + : null; + const queryArgument = + method.query && !method.queryFields + ? argumentsList.find( + (argument) => + argument.type.startsWith("Dictionary<") && + argument !== bodyArgument, + ) + : null; + if (bodyArgument) + bodyArgument.description = `Datos de la solicitud. Admite ${fieldType(method.body, false)}.`; + if (queryArgument) + queryArgument.description = `Parámetros de consulta. Admite ${fieldType(method.query, false)}.`; + const resultType = method.resultProperty + ? "bool" + : fieldType(method.response, false).replace(/\?$/, ""); + method.resultType = resultType; + method.argumentsList = argumentsList; + method.pathArguments = pathArguments; + const declaration = (args) => + `Task<${resultType}> ${method.name}(${args.map((argument) => `${argument.type.replace("Dictionary", "JsonObject")}${argument.default === "null" && !argument.type.endsWith("?") ? "?" : ""} ${argument.name}${argument.default ? " = " + argument.default : ""}`).join(", ")})`; + const emit = (args, typed = false) => { + const query = method.queryFields + ? `new Dictionary { ${Object.entries( + method.queryFields, + ) + .map(([key, name]) => `[${JSON.stringify(key)}] = ${name}`) + .join(", ")} }` + : queryArgument + ? queryArgument.name + : "null"; + const body = method.bodyFields + ? `new Dictionary { ${Object.entries( + method.bodyFields, + ) + .map(([key, name]) => `[${JSON.stringify(key)}] = ${name}`) + .join(", ")} }` + : bodyArgument + ? bodyArgument.name + : "null"; + const prose = documentation(method, args); + interfaces += prose + ` ${declaration(args)};\n\n`; + content += + prose + + ` public ${method.multipart || method.resultProperty ? "async " : ""}${declaration(args)}\n {\n`; + if (method.bodyFlags) { + content += + ` var requestBody = new Dictionary(${bodyArgument.name});\n` + + Object.entries(method.bodyFlags) + .map( + ([key, value]) => + ` requestBody[${JSON.stringify(key)}] = ${JSON.stringify(value)};\n`, + ) + .join(""); + } + if (method.multipart) { + content += + " using (var form = new MultipartFormDataContent())\n {\n"; + for (const [field, argument] of Object.entries(method.multipart)) + content += + field === "password" + ? ` form.Add(new StringContent(${argument}), "password");\n` + : ` form.Add(new StreamContent(${argument}), ${JSON.stringify(field)}, ${JSON.stringify(field === "file" ? "logo.jpg" : field + "." + field)});\n`; + content += ` return await RequestMultipartAsync<${resultType}>(HttpMethod.${pascal(method.verb)}, $"${path.slice(1)}", form, cancellationToken).ConfigureAwait(false);\n }\n`; + } else if (method.resultProperty) + content += ` return (await RequestAsync<${fieldType(method.response, false)}>(HttpMethod.${pascal(method.verb)}, $"${path.slice(1)}", ${query}, ${method.bodyFlags ? "requestBody" : body}, ${Boolean(method.body).toString().toLowerCase()}, cancellationToken).ConfigureAwait(false)).${pascal(method.resultProperty)} == true;\n`; + else + content += ` return RequestAsync<${resultType}>(HttpMethod.${pascal(method.verb)}, $"${path.slice(1)}", ${query}, ${method.bodyFlags ? "requestBody" : body}, ${Boolean(method.body).toString().toLowerCase()}, cancellationToken);\n`; + content += " }\n\n"; + }; + emit(argumentsList); + // A single strongly typed overload preserves dictionary compatibility. + // Query-only overloads require their query argument, avoiding no-arg ambiguity. + if ( + !method.multipart && + !method.bodyFields && + !method.queryFields && + ((bodyArgument && method.body.kind === "model") || + (queryArgument && method.query.kind === "model")) + ) { + const typed = argumentsList.map((argument) => + argument === bodyArgument && method.body.kind === "model" + ? { + ...argument, + type: fieldType(method.body, false), + default: undefined, + } + : argument === queryArgument && method.query.kind === "model" + ? { + ...argument, + type: + fieldType(method.query, false) + + (queryArgument.default === "null" ? "?" : ""), + ...(!bodyArgument ? { default: undefined } : {}), + } + : argument, + ); + emit(typed, true); + } + } + for (const alias of contract.methods.filter( + (method) => method.resource === resource && method.alias, + )) { + const target = contract.methods.find( + (method) => method.resource === resource && method.name === alias.alias, + ); + const args = parseSignature(alias.signature); + const prose = documentation(target, args); + const declaration = `Task<${target.resultType}> ${alias.name}(${args.map((argument) => `${argument.type.replace("Dictionary", "JsonObject")}${argument.default === "null" ? "?" : ""} ${argument.name}${argument.default ? " = " + argument.default : ""}`).join(", ")})`; + interfaces += + prose + + ` [Obsolete("Use ${alias.alias} instead.")]\n ${declaration};\n\n`; content += - ' using (var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json"))\n'; - content += ` using (var response = await client.${pascal(method.verb)}Async(${route}${hasBody ? ", content" : ""}, cancellationToken).ConfigureAwait(false))\n {\n await ThrowIfErrorAsync(response, cancellationToken).ConfigureAwait(false);\n`; - if (method.name !== "sendEditLinkByEmail") - content += ` return JsonConvert.DeserializeObject<${method.name === "list" ? "SearchResult" : method.response.ref}>(await response.Content.ReadAsStringAsync().ConfigureAwait(false), jsonSettings);\n`; - content += " }\n }\n\n"; - } - for (const [name, model, operation] of convenience) { - const method = contract.methods.find((method) => method.name === operation); - const parameters = [ - ...(operation === "update" ? [["id", "string", "ID del cliente."]] : []), - [ - "data", - model, - contract.models.find((item) => item.name === model).description, - ], - [ - "cancellationToken", - "CancellationToken", - "Permite cancelar la solicitud.", - ], - ]; - const declaration = `Task ${pascal(name)}Async(${parameters.map(([name, type]) => `${type} ${name}${name === "cancellationToken" ? " = default" : ""}`).join(", ")})`; - interfaces += - methodProse(method, parameters) + ` ${declaration};\n\n`; - content += - methodProse(method, parameters) + - ` public ${declaration}\n {\n return ${pascal(operation)}Async(${operation === "update" ? "id, " : ""}data, ${name.endsWith("WithEditLink") ? 'new Dictionary { ["createEditLink"] = true }' : "null"}, cancellationToken);\n }\n\n`; + prose + + ` [Obsolete("Use ${alias.alias} instead.")]\n public ${declaration} => ${alias.alias}(${args.map((argument) => argument.name).join(", ")});\n\n`; + } + for (const [name, binding] of Object.entries( + config.convenience?.[resource] || {}, + )) { + const target = contract.methods.find( + (method) => + method.resource === resource && method.name === binding.method, + ); + const args = [ + ...target.pathArguments, + { + name: "data", + type: binding.schema, + description: contract.models.find( + (model) => model.name === binding.schema, + ).description, + }, + { + name: "cancellationToken", + type: "CancellationToken", + default: "default", + }, + ]; + const declaration = `Task<${target.resultType}> ${name}(${args.map((argument) => `${argument.type} ${argument.name}${argument.default ? " = " + argument.default : ""}`).join(", ")})`; + const prose = documentation(target, args); + interfaces += prose + ` ${declaration};\n\n`; + content += + prose + + ` public ${declaration}\n {\n return ${target.name}(${target.pathArguments.map((argument) => argument.name + ", ").join("")}data${ + target.query + ? ", " + + (binding.query + ? `new Dictionary { ${Object.entries( + binding.query, + ) + .map( + ([key, value]) => `[${JSON.stringify(key)}] = ${value}`, + ) + .join(", ")} }` + : "null") + : "" + }, cancellationToken);\n }\n\n`; + } + outputs.set(`Wrappers/${wrapper}.cs`, content + " }\n}\n"); + outputs.set(`Wrappers/I${wrapper}.cs`, interfaces + " }\n}\n"); } - outputs.set("Wrappers/CustomerWrapper.cs", content + " }\n}\n"); - outputs.set("Wrappers/ICustomerWrapper.cs", interfaces + " }\n}\n"); - outputs.set("Router/CustomerRouter.cs", router + " }\n}\n"); + return outputs; }