diff --git a/.release-please-manifest.json b/.release-please-manifest.json index b6700282..617f7502 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.117.0" + ".": "0.118.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 5a93d129..c06c60ed 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 177 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-c24eebe942f400bff8922a6fbef1ce551ad14f61eb4da21b50d823a62ca42586.yml -openapi_spec_hash: b79ed927e625dedff69cea29131a34d9 -config_hash: 693dddc4721eef512d75ab6c60897794 +configured_endpoints: 185 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/lithic%2Flithic-c1dbf87770ddffb9d6d1ada33d1c43739d43498ff687c1d58e403ffc08f6f863.yml +openapi_spec_hash: f488e595de02180bb904da283b7a1c39 +config_hash: 925e84bc73b1b9b5eb0ffd230fc9800f diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bc58031..214d3bc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,30 @@ # Changelog +## 0.118.0 (2026-02-26) + +Full Changelog: [v0.117.0...v0.118.0](https://github.com/lithic-com/lithic-java/compare/v0.117.0...v0.118.0) + +### Features + +* **api:** Add account holder entity endpoints ([04b301b](https://github.com/lithic-com/lithic-java/commit/04b301b3bfc4669821fb0555bdcea4b5f8484310)) +* **api:** Add INTEREST_AND_FEES_PAUSED substatus to financial account ([b533580](https://github.com/lithic-com/lithic-java/commit/b5335809bcdb615e5f8b22f5b7f2b5ea81581219)) +* **api:** Expose MIL interest schedules and loan tape configuration endpoints ([54ea41f](https://github.com/lithic-com/lithic-java/commit/54ea41f7aa89aae69fc1120ae232b110fc64b15d)) + + +### Bug Fixes + +* set Accept header in more places ([13de846](https://github.com/lithic-com/lithic-java/commit/13de84622f05d951233a64bf00528f9aa80dc8e1)) + + +### Chores + +* drop apache dependency ([6f437cc](https://github.com/lithic-com/lithic-java/commit/6f437cc3dd1cac56e147714a789d1c767284bea6)) +* fix card embed endpoints after removing apache dependency ([3d05137](https://github.com/lithic-com/lithic-java/commit/3d051375f098f6c0efc2b24e1cfd08c5f237129b)) +* fix card embed endpoints after removing apache dependency ([c64c472](https://github.com/lithic-com/lithic-java/commit/c64c4722e902a963f62ad90526717aa38360dd6b)) +* fix card embed endpoints after removing apache dependency [#1567](https://github.com/lithic-com/lithic-java/issues/1567) ([3d05137](https://github.com/lithic-com/lithic-java/commit/3d051375f098f6c0efc2b24e1cfd08c5f237129b)) +* **internal:** expand imports ([c03db70](https://github.com/lithic-com/lithic-java/commit/c03db70d19686cd85e06e89b4b134a53ca7fb965)) +* make `Properties` more resilient to `null` ([40426af](https://github.com/lithic-com/lithic-java/commit/40426afe752ec8a8bc77e3791deb1376a2efea9b)) + ## 0.117.0 (2026-02-18) Full Changelog: [v0.116.0...v0.117.0](https://github.com/lithic-com/lithic-java/compare/v0.116.0...v0.117.0) diff --git a/README.md b/README.md index 5b40c425..dfe23ed4 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.lithic.api/lithic-java)](https://central.sonatype.com/artifact/com.lithic.api/lithic-java/0.117.0) -[![javadoc](https://javadoc.io/badge2/com.lithic.api/lithic-java/0.117.0/javadoc.svg)](https://javadoc.io/doc/com.lithic.api/lithic-java/0.117.0) +[![Maven Central](https://img.shields.io/maven-central/v/com.lithic.api/lithic-java)](https://central.sonatype.com/artifact/com.lithic.api/lithic-java/0.118.0) +[![javadoc](https://javadoc.io/badge2/com.lithic.api/lithic-java/0.118.0/javadoc.svg)](https://javadoc.io/doc/com.lithic.api/lithic-java/0.118.0) @@ -22,7 +22,7 @@ Use the Lithic MCP Server to enable AI assistants to interact with this API, all -The REST API documentation can be found on [docs.lithic.com](https://docs.lithic.com). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.lithic.api/lithic-java/0.117.0). +The REST API documentation can be found on [docs.lithic.com](https://docs.lithic.com). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.lithic.api/lithic-java/0.118.0). @@ -33,7 +33,7 @@ The REST API documentation can be found on [docs.lithic.com](https://docs.lithic ### Gradle ```kotlin -implementation("com.lithic.api:lithic-java:0.117.0") +implementation("com.lithic.api:lithic-java:0.118.0") ``` ### Maven @@ -42,7 +42,7 @@ implementation("com.lithic.api:lithic-java:0.117.0") com.lithic.api lithic-java - 0.117.0 + 0.118.0 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 3371f3d6..433e6f12 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "com.lithic.api" - version = "0.117.0" // x-release-please-version + version = "0.118.0" // x-release-please-version } subprojects { diff --git a/lithic-java-core/build.gradle.kts b/lithic-java-core/build.gradle.kts index dc2ea195..76861612 100644 --- a/lithic-java-core/build.gradle.kts +++ b/lithic-java-core/build.gradle.kts @@ -28,8 +28,6 @@ dependencies { implementation("com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.18.2") implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.2") implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.18.2") - implementation("org.apache.httpcomponents.core5:httpcore5:5.2.4") - implementation("org.apache.httpcomponents.client5:httpclient5:5.3.1") testImplementation(kotlin("test")) testImplementation(project(":lithic-java-client-okhttp")) diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/core/Properties.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/core/Properties.kt index 6de9f807..3f0593b3 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/core/Properties.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/core/Properties.kt @@ -34,9 +34,9 @@ fun getOsName(): String { } } -fun getOsVersion(): String = System.getProperty("os.version", "unknown") +fun getOsVersion(): String = System.getProperty("os.version", "unknown") ?: "unknown" fun getPackageVersion(): String = - LithicClient::class.java.`package`.implementationVersion ?: "unknown" + LithicClient::class.java.`package`?.implementationVersion ?: "unknown" -fun getJavaVersion(): String = System.getProperty("java.version", "unknown") +fun getJavaVersion(): String = System.getProperty("java.version", "unknown") ?: "unknown" diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/core/http/HttpRequestBodies.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/core/http/HttpRequestBodies.kt index 5e05f2a0..fc5c5539 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/core/http/HttpRequestBodies.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/core/http/HttpRequestBodies.kt @@ -8,13 +8,13 @@ import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.json.JsonMapper import com.fasterxml.jackson.databind.node.JsonNodeType import com.lithic.api.core.MultipartField +import com.lithic.api.core.toImmutable import com.lithic.api.errors.LithicInvalidDataException +import java.io.ByteArrayInputStream import java.io.InputStream import java.io.OutputStream +import java.util.UUID import kotlin.jvm.optionals.getOrNull -import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder -import org.apache.hc.core5.http.ContentType -import org.apache.hc.core5.http.HttpEntity @JvmSynthetic internal inline fun json(jsonMapper: JsonMapper, value: T): HttpRequestBody = @@ -37,92 +37,231 @@ internal fun multipartFormData( jsonMapper: JsonMapper, fields: Map>, ): HttpRequestBody = - object : HttpRequestBody { - private val entity: HttpEntity by lazy { - MultipartEntityBuilder.create() - .apply { - fields.forEach { (name, field) -> - val knownValue = field.value.asKnown().getOrNull() - val parts = - if (knownValue is InputStream) { - // Read directly from the `InputStream` instead of reading it all - // into memory due to the `jsonMapper` serialization below. - sequenceOf(name to knownValue) - } else { - val node = jsonMapper.valueToTree(field.value) - serializePart(name, node) + MultipartBody.Builder() + .apply { + fields.forEach { (name, field) -> + val knownValue = field.value.asKnown().getOrNull() + val parts = + if (knownValue is InputStream) { + // Read directly from the `InputStream` instead of reading it all + // into memory due to the `jsonMapper` serialization below. + sequenceOf(name to knownValue) + } else { + val node = jsonMapper.valueToTree(field.value) + serializePart(name, node) + } + + parts.forEach { (name, bytes) -> + val partBody = + if (bytes is ByteArrayInputStream) { + val byteArray = bytes.readBytes() + + object : HttpRequestBody { + + override fun writeTo(outputStream: OutputStream) { + outputStream.write(byteArray) + } + + override fun contentType(): String = field.contentType + + override fun contentLength(): Long = byteArray.size.toLong() + + override fun repeatable(): Boolean = true + + override fun close() {} } + } else { + object : HttpRequestBody { + + override fun writeTo(outputStream: OutputStream) { + bytes.copyTo(outputStream) + } + + override fun contentType(): String = field.contentType + + override fun contentLength(): Long = -1L - parts.forEach { (name, bytes) -> - addBinaryBody( - name, - bytes, - ContentType.parseLenient(field.contentType), - field.filename().getOrNull(), - ) + override fun repeatable(): Boolean = false + + override fun close() = bytes.close() + } } - } + + addPart( + MultipartBody.Part.create( + name, + field.filename().getOrNull(), + field.contentType, + partBody, + ) + ) } - .build() + } } + .build() - private fun serializePart( - name: String, - node: JsonNode, - ): Sequence> = - when (node.nodeType) { - JsonNodeType.MISSING, - JsonNodeType.NULL -> emptySequence() - JsonNodeType.BINARY -> sequenceOf(name to node.binaryValue().inputStream()) - JsonNodeType.STRING -> sequenceOf(name to node.textValue().inputStream()) - JsonNodeType.BOOLEAN -> - sequenceOf(name to node.booleanValue().toString().inputStream()) - JsonNodeType.NUMBER -> - sequenceOf(name to node.numberValue().toString().inputStream()) - JsonNodeType.ARRAY -> - sequenceOf( - name to - node - .elements() - .asSequence() - .mapNotNull { element -> - when (element.nodeType) { - JsonNodeType.MISSING, - JsonNodeType.NULL -> null - JsonNodeType.STRING -> node.textValue() - JsonNodeType.BOOLEAN -> node.booleanValue().toString() - JsonNodeType.NUMBER -> node.numberValue().toString() - null, - JsonNodeType.BINARY, - JsonNodeType.ARRAY, - JsonNodeType.OBJECT, - JsonNodeType.POJO -> - throw LithicInvalidDataException( - "Unexpected JsonNode type in array: ${node.nodeType}" - ) - } - } - .joinToString(",") - .inputStream() - ) - JsonNodeType.OBJECT -> - node.fields().asSequence().flatMap { (key, value) -> - serializePart("$name[$key]", value) - } - JsonNodeType.POJO, - null -> - throw LithicInvalidDataException("Unexpected JsonNode type: ${node.nodeType}") +private fun serializePart(name: String, node: JsonNode): Sequence> = + when (node.nodeType) { + JsonNodeType.MISSING, + JsonNodeType.NULL -> emptySequence() + JsonNodeType.BINARY -> sequenceOf(name to node.binaryValue().inputStream()) + JsonNodeType.STRING -> sequenceOf(name to node.textValue().byteInputStream()) + JsonNodeType.BOOLEAN -> sequenceOf(name to node.booleanValue().toString().byteInputStream()) + JsonNodeType.NUMBER -> sequenceOf(name to node.numberValue().toString().byteInputStream()) + JsonNodeType.ARRAY -> + sequenceOf( + name to + node + .elements() + .asSequence() + .mapNotNull { element -> + when (element.nodeType) { + JsonNodeType.MISSING, + JsonNodeType.NULL -> null + JsonNodeType.STRING -> element.textValue() + JsonNodeType.BOOLEAN -> element.booleanValue().toString() + JsonNodeType.NUMBER -> element.numberValue().toString() + null, + JsonNodeType.BINARY, + JsonNodeType.ARRAY, + JsonNodeType.OBJECT, + JsonNodeType.POJO -> + throw LithicInvalidDataException( + "Unexpected JsonNode type in array: ${element.nodeType}" + ) + } + } + .joinToString(",") + .byteInputStream() + ) + JsonNodeType.OBJECT -> + node.fields().asSequence().flatMap { (key, value) -> + serializePart("$name[$key]", value) + } + JsonNodeType.POJO, + null -> throw LithicInvalidDataException("Unexpected JsonNode type: ${node.nodeType}") + } + +private class MultipartBody +private constructor(private val boundary: String, private val parts: List) : HttpRequestBody { + private val boundaryBytes: ByteArray = boundary.toByteArray() + private val contentType = "multipart/form-data; boundary=$boundary" + + // This must remain in sync with `contentLength`. + override fun writeTo(outputStream: OutputStream) { + parts.forEach { part -> + outputStream.write(DASHDASH) + outputStream.write(boundaryBytes) + outputStream.write(CRLF) + + outputStream.write(CONTENT_DISPOSITION) + outputStream.write(part.contentDisposition.toByteArray()) + outputStream.write(CRLF) + + outputStream.write(CONTENT_TYPE) + outputStream.write(part.contentType.toByteArray()) + outputStream.write(CRLF) + + outputStream.write(CRLF) + part.body.writeTo(outputStream) + outputStream.write(CRLF) + } + + outputStream.write(DASHDASH) + outputStream.write(boundaryBytes) + outputStream.write(DASHDASH) + outputStream.write(CRLF) + } + + override fun contentType(): String = contentType + + // This must remain in sync with `writeTo`. + override fun contentLength(): Long { + var byteCount = 0L + + parts.forEach { part -> + val contentLength = part.body.contentLength() + if (contentLength == -1L) { + return -1L } - private fun String.inputStream(): InputStream = toByteArray().inputStream() + byteCount += + DASHDASH.size + + boundaryBytes.size + + CRLF.size + + CONTENT_DISPOSITION.size + + part.contentDisposition.toByteArray().size + + CRLF.size + + CONTENT_TYPE.size + + part.contentType.toByteArray().size + + CRLF.size + + CRLF.size + + contentLength + + CRLF.size + } - override fun writeTo(outputStream: OutputStream) = entity.writeTo(outputStream) + byteCount += DASHDASH.size + boundaryBytes.size + DASHDASH.size + CRLF.size + return byteCount + } - override fun contentType(): String = entity.contentType + override fun repeatable(): Boolean = parts.all { it.body.repeatable() } - override fun contentLength(): Long = entity.contentLength + override fun close() { + parts.forEach { it.body.close() } + } - override fun repeatable(): Boolean = entity.isRepeatable + class Builder { + private val boundary = UUID.randomUUID().toString() + private val parts: MutableList = mutableListOf() - override fun close() = entity.close() + fun addPart(part: Part) = apply { parts.add(part) } + + fun build() = MultipartBody(boundary, parts.toImmutable()) + } + + class Part + private constructor( + val contentDisposition: String, + val contentType: String, + val body: HttpRequestBody, + ) { + companion object { + fun create( + name: String, + filename: String?, + contentType: String, + body: HttpRequestBody, + ): Part { + val disposition = buildString { + append("form-data; name=") + appendQuotedString(name) + if (filename != null) { + append("; filename=") + appendQuotedString(filename) + } + } + return Part(disposition, contentType, body) + } + } + } + + companion object { + private val CRLF = byteArrayOf('\r'.code.toByte(), '\n'.code.toByte()) + private val DASHDASH = byteArrayOf('-'.code.toByte(), '-'.code.toByte()) + private val CONTENT_DISPOSITION = "Content-Disposition: ".toByteArray() + private val CONTENT_TYPE = "Content-Type: ".toByteArray() + + private fun StringBuilder.appendQuotedString(key: String) { + append('"') + for (ch in key) { + when (ch) { + '\n' -> append("%0A") + '\r' -> append("%0D") + '"' -> append("%22") + else -> append(ch) + } + } + append('"') + } } +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/core/http/RetryingHttpClient.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/core/http/RetryingHttpClient.kt index 5d2ac94f..a70bc12c 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/core/http/RetryingHttpClient.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/core/http/RetryingHttpClient.kt @@ -1,3 +1,5 @@ +// File generated from our OpenAPI spec by Stainless. + package com.lithic.api.core.http import com.lithic.api.core.DefaultSleeper diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderEntity.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderEntity.kt new file mode 100644 index 00000000..47572e3d --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderEntity.kt @@ -0,0 +1,1194 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.lithic.api.core.Enum +import com.lithic.api.core.ExcludeMissing +import com.lithic.api.core.JsonField +import com.lithic.api.core.JsonMissing +import com.lithic.api.core.JsonValue +import com.lithic.api.core.checkRequired +import com.lithic.api.errors.LithicInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Information about an entity associated with an account holder */ +class AccountHolderEntity +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val token: JsonField, + private val accountHolderToken: JsonField, + private val address: JsonField
, + private val dob: JsonField, + private val email: JsonField, + private val firstName: JsonField, + private val lastName: JsonField, + private val phoneNumber: JsonField, + private val status: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("token") @ExcludeMissing token: JsonField = JsonMissing.of(), + @JsonProperty("account_holder_token") + @ExcludeMissing + accountHolderToken: JsonField = JsonMissing.of(), + @JsonProperty("address") @ExcludeMissing address: JsonField
= JsonMissing.of(), + @JsonProperty("dob") @ExcludeMissing dob: JsonField = JsonMissing.of(), + @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), + @JsonProperty("first_name") @ExcludeMissing firstName: JsonField = JsonMissing.of(), + @JsonProperty("last_name") @ExcludeMissing lastName: JsonField = JsonMissing.of(), + @JsonProperty("phone_number") + @ExcludeMissing + phoneNumber: JsonField = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this( + token, + accountHolderToken, + address, + dob, + email, + firstName, + lastName, + phoneNumber, + status, + type, + mutableMapOf(), + ) + + /** + * Globally unique identifier for the entity + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun token(): String = token.getRequired("token") + + /** + * Globally unique identifier for the account holder + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun accountHolderToken(): String = accountHolderToken.getRequired("account_holder_token") + + /** + * Individual's current address + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun address(): Address = address.getRequired("address") + + /** + * Individual's date of birth, as an RFC 3339 date + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun dob(): Optional = dob.getOptional("dob") + + /** + * Individual's email address + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun email(): Optional = email.getOptional("email") + + /** + * Individual's first name, as it appears on government-issued identity documents + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun firstName(): Optional = firstName.getOptional("first_name") + + /** + * Individual's last name, as it appears on government-issued identity documents + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun lastName(): Optional = lastName.getOptional("last_name") + + /** + * Individual's phone number, entered in E.164 format + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun phoneNumber(): Optional = phoneNumber.getOptional("phone_number") + + /** + * The status of the entity + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun status(): EntityStatus = status.getRequired("status") + + /** + * The type of entity + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun type(): EntityType = type.getRequired("type") + + /** + * Returns the raw JSON value of [token]. + * + * Unlike [token], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("token") @ExcludeMissing fun _token(): JsonField = token + + /** + * Returns the raw JSON value of [accountHolderToken]. + * + * Unlike [accountHolderToken], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("account_holder_token") + @ExcludeMissing + fun _accountHolderToken(): JsonField = accountHolderToken + + /** + * Returns the raw JSON value of [address]. + * + * Unlike [address], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("address") @ExcludeMissing fun _address(): JsonField
= address + + /** + * Returns the raw JSON value of [dob]. + * + * Unlike [dob], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("dob") @ExcludeMissing fun _dob(): JsonField = dob + + /** + * Returns the raw JSON value of [email]. + * + * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("email") @ExcludeMissing fun _email(): JsonField = email + + /** + * Returns the raw JSON value of [firstName]. + * + * Unlike [firstName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("first_name") @ExcludeMissing fun _firstName(): JsonField = firstName + + /** + * Returns the raw JSON value of [lastName]. + * + * Unlike [lastName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("last_name") @ExcludeMissing fun _lastName(): JsonField = lastName + + /** + * Returns the raw JSON value of [phoneNumber]. + * + * Unlike [phoneNumber], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("phone_number") + @ExcludeMissing + fun _phoneNumber(): JsonField = phoneNumber + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [AccountHolderEntity]. + * + * The following fields are required: + * ```java + * .token() + * .accountHolderToken() + * .address() + * .dob() + * .email() + * .firstName() + * .lastName() + * .phoneNumber() + * .status() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AccountHolderEntity]. */ + class Builder internal constructor() { + + private var token: JsonField? = null + private var accountHolderToken: JsonField? = null + private var address: JsonField
? = null + private var dob: JsonField? = null + private var email: JsonField? = null + private var firstName: JsonField? = null + private var lastName: JsonField? = null + private var phoneNumber: JsonField? = null + private var status: JsonField? = null + private var type: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(accountHolderEntity: AccountHolderEntity) = apply { + token = accountHolderEntity.token + accountHolderToken = accountHolderEntity.accountHolderToken + address = accountHolderEntity.address + dob = accountHolderEntity.dob + email = accountHolderEntity.email + firstName = accountHolderEntity.firstName + lastName = accountHolderEntity.lastName + phoneNumber = accountHolderEntity.phoneNumber + status = accountHolderEntity.status + type = accountHolderEntity.type + additionalProperties = accountHolderEntity.additionalProperties.toMutableMap() + } + + /** Globally unique identifier for the entity */ + fun token(token: String) = token(JsonField.of(token)) + + /** + * Sets [Builder.token] to an arbitrary JSON value. + * + * You should usually call [Builder.token] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun token(token: JsonField) = apply { this.token = token } + + /** Globally unique identifier for the account holder */ + fun accountHolderToken(accountHolderToken: String) = + accountHolderToken(JsonField.of(accountHolderToken)) + + /** + * Sets [Builder.accountHolderToken] to an arbitrary JSON value. + * + * You should usually call [Builder.accountHolderToken] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun accountHolderToken(accountHolderToken: JsonField) = apply { + this.accountHolderToken = accountHolderToken + } + + /** Individual's current address */ + fun address(address: Address) = address(JsonField.of(address)) + + /** + * Sets [Builder.address] to an arbitrary JSON value. + * + * You should usually call [Builder.address] with a well-typed [Address] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun address(address: JsonField
) = apply { this.address = address } + + /** Individual's date of birth, as an RFC 3339 date */ + fun dob(dob: String?) = dob(JsonField.ofNullable(dob)) + + /** Alias for calling [Builder.dob] with `dob.orElse(null)`. */ + fun dob(dob: Optional) = dob(dob.getOrNull()) + + /** + * Sets [Builder.dob] to an arbitrary JSON value. + * + * You should usually call [Builder.dob] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun dob(dob: JsonField) = apply { this.dob = dob } + + /** Individual's email address */ + fun email(email: String?) = email(JsonField.ofNullable(email)) + + /** Alias for calling [Builder.email] with `email.orElse(null)`. */ + fun email(email: Optional) = email(email.getOrNull()) + + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun email(email: JsonField) = apply { this.email = email } + + /** Individual's first name, as it appears on government-issued identity documents */ + fun firstName(firstName: String?) = firstName(JsonField.ofNullable(firstName)) + + /** Alias for calling [Builder.firstName] with `firstName.orElse(null)`. */ + fun firstName(firstName: Optional) = firstName(firstName.getOrNull()) + + /** + * Sets [Builder.firstName] to an arbitrary JSON value. + * + * You should usually call [Builder.firstName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun firstName(firstName: JsonField) = apply { this.firstName = firstName } + + /** Individual's last name, as it appears on government-issued identity documents */ + fun lastName(lastName: String?) = lastName(JsonField.ofNullable(lastName)) + + /** Alias for calling [Builder.lastName] with `lastName.orElse(null)`. */ + fun lastName(lastName: Optional) = lastName(lastName.getOrNull()) + + /** + * Sets [Builder.lastName] to an arbitrary JSON value. + * + * You should usually call [Builder.lastName] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun lastName(lastName: JsonField) = apply { this.lastName = lastName } + + /** Individual's phone number, entered in E.164 format */ + fun phoneNumber(phoneNumber: String?) = phoneNumber(JsonField.ofNullable(phoneNumber)) + + /** Alias for calling [Builder.phoneNumber] with `phoneNumber.orElse(null)`. */ + fun phoneNumber(phoneNumber: Optional) = phoneNumber(phoneNumber.getOrNull()) + + /** + * Sets [Builder.phoneNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.phoneNumber] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun phoneNumber(phoneNumber: JsonField) = apply { this.phoneNumber = phoneNumber } + + /** The status of the entity */ + fun status(status: EntityStatus) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [EntityStatus] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun status(status: JsonField) = apply { this.status = status } + + /** The type of entity */ + fun type(type: EntityType) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [EntityType] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [AccountHolderEntity]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .token() + * .accountHolderToken() + * .address() + * .dob() + * .email() + * .firstName() + * .lastName() + * .phoneNumber() + * .status() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AccountHolderEntity = + AccountHolderEntity( + checkRequired("token", token), + checkRequired("accountHolderToken", accountHolderToken), + checkRequired("address", address), + checkRequired("dob", dob), + checkRequired("email", email), + checkRequired("firstName", firstName), + checkRequired("lastName", lastName), + checkRequired("phoneNumber", phoneNumber), + checkRequired("status", status), + checkRequired("type", type), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): AccountHolderEntity = apply { + if (validated) { + return@apply + } + + token() + accountHolderToken() + address().validate() + dob() + email() + firstName() + lastName() + phoneNumber() + status().validate() + type().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (token.asKnown().isPresent) 1 else 0) + + (if (accountHolderToken.asKnown().isPresent) 1 else 0) + + (address.asKnown().getOrNull()?.validity() ?: 0) + + (if (dob.asKnown().isPresent) 1 else 0) + + (if (email.asKnown().isPresent) 1 else 0) + + (if (firstName.asKnown().isPresent) 1 else 0) + + (if (lastName.asKnown().isPresent) 1 else 0) + + (if (phoneNumber.asKnown().isPresent) 1 else 0) + + (status.asKnown().getOrNull()?.validity() ?: 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + /** Individual's current address */ + class Address + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val address1: JsonField, + private val city: JsonField, + private val country: JsonField, + private val postalCode: JsonField, + private val state: JsonField, + private val address2: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("address1") + @ExcludeMissing + address1: JsonField = JsonMissing.of(), + @JsonProperty("city") @ExcludeMissing city: JsonField = JsonMissing.of(), + @JsonProperty("country") @ExcludeMissing country: JsonField = JsonMissing.of(), + @JsonProperty("postal_code") + @ExcludeMissing + postalCode: JsonField = JsonMissing.of(), + @JsonProperty("state") @ExcludeMissing state: JsonField = JsonMissing.of(), + @JsonProperty("address2") @ExcludeMissing address2: JsonField = JsonMissing.of(), + ) : this(address1, city, country, postalCode, state, address2, mutableMapOf()) + + /** + * Valid deliverable address (no PO boxes). + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun address1(): String = address1.getRequired("address1") + + /** + * Name of city. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun city(): String = city.getRequired("city") + + /** + * Valid country code. Only USA is currently supported, entered in uppercase ISO 3166-1 + * alpha-3 three-character format. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun country(): String = country.getRequired("country") + + /** + * Valid postal code. Only USA ZIP codes are currently supported, entered as a five-digit + * ZIP or nine-digit ZIP+4. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun postalCode(): String = postalCode.getRequired("postal_code") + + /** + * Valid state code. Only USA state codes are currently supported, entered in uppercase ISO + * 3166-2 two-character format. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun state(): String = state.getRequired("state") + + /** + * Unit or apartment number (if applicable). + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun address2(): Optional = address2.getOptional("address2") + + /** + * Returns the raw JSON value of [address1]. + * + * Unlike [address1], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("address1") @ExcludeMissing fun _address1(): JsonField = address1 + + /** + * Returns the raw JSON value of [city]. + * + * Unlike [city], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("city") @ExcludeMissing fun _city(): JsonField = city + + /** + * Returns the raw JSON value of [country]. + * + * Unlike [country], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("country") @ExcludeMissing fun _country(): JsonField = country + + /** + * Returns the raw JSON value of [postalCode]. + * + * Unlike [postalCode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("postal_code") + @ExcludeMissing + fun _postalCode(): JsonField = postalCode + + /** + * Returns the raw JSON value of [state]. + * + * Unlike [state], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("state") @ExcludeMissing fun _state(): JsonField = state + + /** + * Returns the raw JSON value of [address2]. + * + * Unlike [address2], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("address2") @ExcludeMissing fun _address2(): JsonField = address2 + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Address]. + * + * The following fields are required: + * ```java + * .address1() + * .city() + * .country() + * .postalCode() + * .state() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Address]. */ + class Builder internal constructor() { + + private var address1: JsonField? = null + private var city: JsonField? = null + private var country: JsonField? = null + private var postalCode: JsonField? = null + private var state: JsonField? = null + private var address2: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(address: Address) = apply { + address1 = address.address1 + city = address.city + country = address.country + postalCode = address.postalCode + state = address.state + address2 = address.address2 + additionalProperties = address.additionalProperties.toMutableMap() + } + + /** Valid deliverable address (no PO boxes). */ + fun address1(address1: String) = address1(JsonField.of(address1)) + + /** + * Sets [Builder.address1] to an arbitrary JSON value. + * + * You should usually call [Builder.address1] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun address1(address1: JsonField) = apply { this.address1 = address1 } + + /** Name of city. */ + fun city(city: String) = city(JsonField.of(city)) + + /** + * Sets [Builder.city] to an arbitrary JSON value. + * + * You should usually call [Builder.city] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun city(city: JsonField) = apply { this.city = city } + + /** + * Valid country code. Only USA is currently supported, entered in uppercase ISO 3166-1 + * alpha-3 three-character format. + */ + fun country(country: String) = country(JsonField.of(country)) + + /** + * Sets [Builder.country] to an arbitrary JSON value. + * + * You should usually call [Builder.country] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun country(country: JsonField) = apply { this.country = country } + + /** + * Valid postal code. Only USA ZIP codes are currently supported, entered as a + * five-digit ZIP or nine-digit ZIP+4. + */ + fun postalCode(postalCode: String) = postalCode(JsonField.of(postalCode)) + + /** + * Sets [Builder.postalCode] to an arbitrary JSON value. + * + * You should usually call [Builder.postalCode] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun postalCode(postalCode: JsonField) = apply { this.postalCode = postalCode } + + /** + * Valid state code. Only USA state codes are currently supported, entered in uppercase + * ISO 3166-2 two-character format. + */ + fun state(state: String) = state(JsonField.of(state)) + + /** + * Sets [Builder.state] to an arbitrary JSON value. + * + * You should usually call [Builder.state] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun state(state: JsonField) = apply { this.state = state } + + /** Unit or apartment number (if applicable). */ + fun address2(address2: String) = address2(JsonField.of(address2)) + + /** + * Sets [Builder.address2] to an arbitrary JSON value. + * + * You should usually call [Builder.address2] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun address2(address2: JsonField) = apply { this.address2 = address2 } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Address]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .address1() + * .city() + * .country() + * .postalCode() + * .state() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Address = + Address( + checkRequired("address1", address1), + checkRequired("city", city), + checkRequired("country", country), + checkRequired("postalCode", postalCode), + checkRequired("state", state), + address2, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Address = apply { + if (validated) { + return@apply + } + + address1() + city() + country() + postalCode() + state() + address2() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (address1.asKnown().isPresent) 1 else 0) + + (if (city.asKnown().isPresent) 1 else 0) + + (if (country.asKnown().isPresent) 1 else 0) + + (if (postalCode.asKnown().isPresent) 1 else 0) + + (if (state.asKnown().isPresent) 1 else 0) + + (if (address2.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Address && + address1 == other.address1 && + city == other.city && + country == other.country && + postalCode == other.postalCode && + state == other.state && + address2 == other.address2 && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(address1, city, country, postalCode, state, address2, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Address{address1=$address1, city=$city, country=$country, postalCode=$postalCode, state=$state, address2=$address2, additionalProperties=$additionalProperties}" + } + + /** The status of the entity */ + class EntityStatus @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val ACCEPTED = of("ACCEPTED") + + @JvmField val INACTIVE = of("INACTIVE") + + @JvmField val PENDING_REVIEW = of("PENDING_REVIEW") + + @JvmField val REJECTED = of("REJECTED") + + @JvmStatic fun of(value: String) = EntityStatus(JsonField.of(value)) + } + + /** An enum containing [EntityStatus]'s known values. */ + enum class Known { + ACCEPTED, + INACTIVE, + PENDING_REVIEW, + REJECTED, + } + + /** + * An enum containing [EntityStatus]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [EntityStatus] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + ACCEPTED, + INACTIVE, + PENDING_REVIEW, + REJECTED, + /** + * An enum member indicating that [EntityStatus] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + ACCEPTED -> Value.ACCEPTED + INACTIVE -> Value.INACTIVE + PENDING_REVIEW -> Value.PENDING_REVIEW + REJECTED -> Value.REJECTED + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws LithicInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + ACCEPTED -> Known.ACCEPTED + INACTIVE -> Known.INACTIVE + PENDING_REVIEW -> Known.PENDING_REVIEW + REJECTED -> Known.REJECTED + else -> throw LithicInvalidDataException("Unknown EntityStatus: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws LithicInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { LithicInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): EntityStatus = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is EntityStatus && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** The type of entity */ + class EntityType @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val BENEFICIAL_OWNER_INDIVIDUAL = of("BENEFICIAL_OWNER_INDIVIDUAL") + + @JvmField val CONTROL_PERSON = of("CONTROL_PERSON") + + @JvmStatic fun of(value: String) = EntityType(JsonField.of(value)) + } + + /** An enum containing [EntityType]'s known values. */ + enum class Known { + BENEFICIAL_OWNER_INDIVIDUAL, + CONTROL_PERSON, + } + + /** + * An enum containing [EntityType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [EntityType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + BENEFICIAL_OWNER_INDIVIDUAL, + CONTROL_PERSON, + /** + * An enum member indicating that [EntityType] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + BENEFICIAL_OWNER_INDIVIDUAL -> Value.BENEFICIAL_OWNER_INDIVIDUAL + CONTROL_PERSON -> Value.CONTROL_PERSON + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws LithicInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + BENEFICIAL_OWNER_INDIVIDUAL -> Known.BENEFICIAL_OWNER_INDIVIDUAL + CONTROL_PERSON -> Known.CONTROL_PERSON + else -> throw LithicInvalidDataException("Unknown EntityType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws LithicInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { LithicInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): EntityType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is EntityType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AccountHolderEntity && + token == other.token && + accountHolderToken == other.accountHolderToken && + address == other.address && + dob == other.dob && + email == other.email && + firstName == other.firstName && + lastName == other.lastName && + phoneNumber == other.phoneNumber && + status == other.status && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + token, + accountHolderToken, + address, + dob, + email, + firstName, + lastName, + phoneNumber, + status, + type, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "AccountHolderEntity{token=$token, accountHolderToken=$accountHolderToken, address=$address, dob=$dob, email=$email, firstName=$firstName, lastName=$lastName, phoneNumber=$phoneNumber, status=$status, type=$type, additionalProperties=$additionalProperties}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderEntityCreateParams.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderEntityCreateParams.kt new file mode 100644 index 00000000..c3bd16e4 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderEntityCreateParams.kt @@ -0,0 +1,1491 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.lithic.api.core.Enum +import com.lithic.api.core.ExcludeMissing +import com.lithic.api.core.JsonField +import com.lithic.api.core.JsonMissing +import com.lithic.api.core.JsonValue +import com.lithic.api.core.Params +import com.lithic.api.core.checkRequired +import com.lithic.api.core.http.Headers +import com.lithic.api.core.http.QueryParams +import com.lithic.api.errors.LithicInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Create a new beneficial owner or replace the control person entity on an existing KYB account + * holder. This endpoint is only applicable for account holders enrolled through a KYB workflow with + * the Persona KYB provider. A new control person can only replace the existing one. A maximum of 4 + * beneficial owners can be associated with an account holder. + */ +class AccountHolderEntityCreateParams +private constructor( + private val accountHolderToken: String?, + private val body: CreateEntityRequest, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun accountHolderToken(): Optional = Optional.ofNullable(accountHolderToken) + + /** + * Individual's current address - PO boxes, UPS drops, and FedEx drops are not acceptable; + * APO/FPO are acceptable. Only USA addresses are currently supported. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun address(): Address = body.address() + + /** + * Individual's date of birth, as an RFC 3339 date. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun dob(): String = body.dob() + + /** + * Individual's email address. If utilizing Lithic for chargeback processing, this customer + * email address may be used to communicate dispute status and resolution. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun email(): String = body.email() + + /** + * Individual's first name, as it appears on government-issued identity documents. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun firstName(): String = body.firstName() + + /** + * Government-issued identification number (required for identity verification and compliance + * with banking regulations). Social Security Numbers (SSN) and Individual Taxpayer + * Identification Numbers (ITIN) are currently supported, entered as full nine-digits, with or + * without hyphens + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun governmentId(): String = body.governmentId() + + /** + * Individual's last name, as it appears on government-issued identity documents. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun lastName(): String = body.lastName() + + /** + * Individual's phone number, entered in E.164 format. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun phoneNumber(): String = body.phoneNumber() + + /** + * The type of entity to create on the account holder + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun type(): EntityType = body.type() + + /** + * Returns the raw JSON value of [address]. + * + * Unlike [address], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _address(): JsonField
= body._address() + + /** + * Returns the raw JSON value of [dob]. + * + * Unlike [dob], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _dob(): JsonField = body._dob() + + /** + * Returns the raw JSON value of [email]. + * + * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _email(): JsonField = body._email() + + /** + * Returns the raw JSON value of [firstName]. + * + * Unlike [firstName], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _firstName(): JsonField = body._firstName() + + /** + * Returns the raw JSON value of [governmentId]. + * + * Unlike [governmentId], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _governmentId(): JsonField = body._governmentId() + + /** + * Returns the raw JSON value of [lastName]. + * + * Unlike [lastName], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _lastName(): JsonField = body._lastName() + + /** + * Returns the raw JSON value of [phoneNumber]. + * + * Unlike [phoneNumber], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _phoneNumber(): JsonField = body._phoneNumber() + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _type(): JsonField = body._type() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [AccountHolderEntityCreateParams]. + * + * The following fields are required: + * ```java + * .address() + * .dob() + * .email() + * .firstName() + * .governmentId() + * .lastName() + * .phoneNumber() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AccountHolderEntityCreateParams]. */ + class Builder internal constructor() { + + private var accountHolderToken: String? = null + private var body: CreateEntityRequest.Builder = CreateEntityRequest.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from(accountHolderEntityCreateParams: AccountHolderEntityCreateParams) = + apply { + accountHolderToken = accountHolderEntityCreateParams.accountHolderToken + body = accountHolderEntityCreateParams.body.toBuilder() + additionalHeaders = accountHolderEntityCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = + accountHolderEntityCreateParams.additionalQueryParams.toBuilder() + } + + fun accountHolderToken(accountHolderToken: String?) = apply { + this.accountHolderToken = accountHolderToken + } + + /** + * Alias for calling [Builder.accountHolderToken] with `accountHolderToken.orElse(null)`. + */ + fun accountHolderToken(accountHolderToken: Optional) = + accountHolderToken(accountHolderToken.getOrNull()) + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [address] + * - [dob] + * - [email] + * - [firstName] + * - [governmentId] + * - etc. + */ + fun body(body: CreateEntityRequest) = apply { this.body = body.toBuilder() } + + /** + * Individual's current address - PO boxes, UPS drops, and FedEx drops are not acceptable; + * APO/FPO are acceptable. Only USA addresses are currently supported. + */ + fun address(address: Address) = apply { body.address(address) } + + /** + * Sets [Builder.address] to an arbitrary JSON value. + * + * You should usually call [Builder.address] with a well-typed [Address] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun address(address: JsonField
) = apply { body.address(address) } + + /** Individual's date of birth, as an RFC 3339 date. */ + fun dob(dob: String) = apply { body.dob(dob) } + + /** + * Sets [Builder.dob] to an arbitrary JSON value. + * + * You should usually call [Builder.dob] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun dob(dob: JsonField) = apply { body.dob(dob) } + + /** + * Individual's email address. If utilizing Lithic for chargeback processing, this customer + * email address may be used to communicate dispute status and resolution. + */ + fun email(email: String) = apply { body.email(email) } + + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun email(email: JsonField) = apply { body.email(email) } + + /** Individual's first name, as it appears on government-issued identity documents. */ + fun firstName(firstName: String) = apply { body.firstName(firstName) } + + /** + * Sets [Builder.firstName] to an arbitrary JSON value. + * + * You should usually call [Builder.firstName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun firstName(firstName: JsonField) = apply { body.firstName(firstName) } + + /** + * Government-issued identification number (required for identity verification and + * compliance with banking regulations). Social Security Numbers (SSN) and Individual + * Taxpayer Identification Numbers (ITIN) are currently supported, entered as full + * nine-digits, with or without hyphens + */ + fun governmentId(governmentId: String) = apply { body.governmentId(governmentId) } + + /** + * Sets [Builder.governmentId] to an arbitrary JSON value. + * + * You should usually call [Builder.governmentId] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun governmentId(governmentId: JsonField) = apply { + body.governmentId(governmentId) + } + + /** Individual's last name, as it appears on government-issued identity documents. */ + fun lastName(lastName: String) = apply { body.lastName(lastName) } + + /** + * Sets [Builder.lastName] to an arbitrary JSON value. + * + * You should usually call [Builder.lastName] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun lastName(lastName: JsonField) = apply { body.lastName(lastName) } + + /** Individual's phone number, entered in E.164 format. */ + fun phoneNumber(phoneNumber: String) = apply { body.phoneNumber(phoneNumber) } + + /** + * Sets [Builder.phoneNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.phoneNumber] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun phoneNumber(phoneNumber: JsonField) = apply { body.phoneNumber(phoneNumber) } + + /** The type of entity to create on the account holder */ + fun type(type: EntityType) = apply { body.type(type) } + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [EntityType] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun type(type: JsonField) = apply { body.type(type) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [AccountHolderEntityCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .address() + * .dob() + * .email() + * .firstName() + * .governmentId() + * .lastName() + * .phoneNumber() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AccountHolderEntityCreateParams = + AccountHolderEntityCreateParams( + accountHolderToken, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): CreateEntityRequest = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> accountHolderToken ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + /** + * Request body for creating a new beneficial owner or replacing the control person entity on an + * existing KYB account holder. + */ + class CreateEntityRequest + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val address: JsonField
, + private val dob: JsonField, + private val email: JsonField, + private val firstName: JsonField, + private val governmentId: JsonField, + private val lastName: JsonField, + private val phoneNumber: JsonField, + private val type: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("address") @ExcludeMissing address: JsonField
= JsonMissing.of(), + @JsonProperty("dob") @ExcludeMissing dob: JsonField = JsonMissing.of(), + @JsonProperty("email") @ExcludeMissing email: JsonField = JsonMissing.of(), + @JsonProperty("first_name") + @ExcludeMissing + firstName: JsonField = JsonMissing.of(), + @JsonProperty("government_id") + @ExcludeMissing + governmentId: JsonField = JsonMissing.of(), + @JsonProperty("last_name") + @ExcludeMissing + lastName: JsonField = JsonMissing.of(), + @JsonProperty("phone_number") + @ExcludeMissing + phoneNumber: JsonField = JsonMissing.of(), + @JsonProperty("type") @ExcludeMissing type: JsonField = JsonMissing.of(), + ) : this( + address, + dob, + email, + firstName, + governmentId, + lastName, + phoneNumber, + type, + mutableMapOf(), + ) + + /** + * Individual's current address - PO boxes, UPS drops, and FedEx drops are not acceptable; + * APO/FPO are acceptable. Only USA addresses are currently supported. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun address(): Address = address.getRequired("address") + + /** + * Individual's date of birth, as an RFC 3339 date. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun dob(): String = dob.getRequired("dob") + + /** + * Individual's email address. If utilizing Lithic for chargeback processing, this customer + * email address may be used to communicate dispute status and resolution. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun email(): String = email.getRequired("email") + + /** + * Individual's first name, as it appears on government-issued identity documents. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun firstName(): String = firstName.getRequired("first_name") + + /** + * Government-issued identification number (required for identity verification and + * compliance with banking regulations). Social Security Numbers (SSN) and Individual + * Taxpayer Identification Numbers (ITIN) are currently supported, entered as full + * nine-digits, with or without hyphens + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun governmentId(): String = governmentId.getRequired("government_id") + + /** + * Individual's last name, as it appears on government-issued identity documents. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun lastName(): String = lastName.getRequired("last_name") + + /** + * Individual's phone number, entered in E.164 format. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun phoneNumber(): String = phoneNumber.getRequired("phone_number") + + /** + * The type of entity to create on the account holder + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun type(): EntityType = type.getRequired("type") + + /** + * Returns the raw JSON value of [address]. + * + * Unlike [address], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("address") @ExcludeMissing fun _address(): JsonField
= address + + /** + * Returns the raw JSON value of [dob]. + * + * Unlike [dob], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("dob") @ExcludeMissing fun _dob(): JsonField = dob + + /** + * Returns the raw JSON value of [email]. + * + * Unlike [email], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("email") @ExcludeMissing fun _email(): JsonField = email + + /** + * Returns the raw JSON value of [firstName]. + * + * Unlike [firstName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("first_name") @ExcludeMissing fun _firstName(): JsonField = firstName + + /** + * Returns the raw JSON value of [governmentId]. + * + * Unlike [governmentId], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("government_id") + @ExcludeMissing + fun _governmentId(): JsonField = governmentId + + /** + * Returns the raw JSON value of [lastName]. + * + * Unlike [lastName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("last_name") @ExcludeMissing fun _lastName(): JsonField = lastName + + /** + * Returns the raw JSON value of [phoneNumber]. + * + * Unlike [phoneNumber], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("phone_number") + @ExcludeMissing + fun _phoneNumber(): JsonField = phoneNumber + + /** + * Returns the raw JSON value of [type]. + * + * Unlike [type], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("type") @ExcludeMissing fun _type(): JsonField = type + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [CreateEntityRequest]. + * + * The following fields are required: + * ```java + * .address() + * .dob() + * .email() + * .firstName() + * .governmentId() + * .lastName() + * .phoneNumber() + * .type() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CreateEntityRequest]. */ + class Builder internal constructor() { + + private var address: JsonField
? = null + private var dob: JsonField? = null + private var email: JsonField? = null + private var firstName: JsonField? = null + private var governmentId: JsonField? = null + private var lastName: JsonField? = null + private var phoneNumber: JsonField? = null + private var type: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(createEntityRequest: CreateEntityRequest) = apply { + address = createEntityRequest.address + dob = createEntityRequest.dob + email = createEntityRequest.email + firstName = createEntityRequest.firstName + governmentId = createEntityRequest.governmentId + lastName = createEntityRequest.lastName + phoneNumber = createEntityRequest.phoneNumber + type = createEntityRequest.type + additionalProperties = createEntityRequest.additionalProperties.toMutableMap() + } + + /** + * Individual's current address - PO boxes, UPS drops, and FedEx drops are not + * acceptable; APO/FPO are acceptable. Only USA addresses are currently supported. + */ + fun address(address: Address) = address(JsonField.of(address)) + + /** + * Sets [Builder.address] to an arbitrary JSON value. + * + * You should usually call [Builder.address] with a well-typed [Address] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun address(address: JsonField
) = apply { this.address = address } + + /** Individual's date of birth, as an RFC 3339 date. */ + fun dob(dob: String) = dob(JsonField.of(dob)) + + /** + * Sets [Builder.dob] to an arbitrary JSON value. + * + * You should usually call [Builder.dob] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun dob(dob: JsonField) = apply { this.dob = dob } + + /** + * Individual's email address. If utilizing Lithic for chargeback processing, this + * customer email address may be used to communicate dispute status and resolution. + */ + fun email(email: String) = email(JsonField.of(email)) + + /** + * Sets [Builder.email] to an arbitrary JSON value. + * + * You should usually call [Builder.email] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun email(email: JsonField) = apply { this.email = email } + + /** Individual's first name, as it appears on government-issued identity documents. */ + fun firstName(firstName: String) = firstName(JsonField.of(firstName)) + + /** + * Sets [Builder.firstName] to an arbitrary JSON value. + * + * You should usually call [Builder.firstName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun firstName(firstName: JsonField) = apply { this.firstName = firstName } + + /** + * Government-issued identification number (required for identity verification and + * compliance with banking regulations). Social Security Numbers (SSN) and Individual + * Taxpayer Identification Numbers (ITIN) are currently supported, entered as full + * nine-digits, with or without hyphens + */ + fun governmentId(governmentId: String) = governmentId(JsonField.of(governmentId)) + + /** + * Sets [Builder.governmentId] to an arbitrary JSON value. + * + * You should usually call [Builder.governmentId] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun governmentId(governmentId: JsonField) = apply { + this.governmentId = governmentId + } + + /** Individual's last name, as it appears on government-issued identity documents. */ + fun lastName(lastName: String) = lastName(JsonField.of(lastName)) + + /** + * Sets [Builder.lastName] to an arbitrary JSON value. + * + * You should usually call [Builder.lastName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun lastName(lastName: JsonField) = apply { this.lastName = lastName } + + /** Individual's phone number, entered in E.164 format. */ + fun phoneNumber(phoneNumber: String) = phoneNumber(JsonField.of(phoneNumber)) + + /** + * Sets [Builder.phoneNumber] to an arbitrary JSON value. + * + * You should usually call [Builder.phoneNumber] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun phoneNumber(phoneNumber: JsonField) = apply { + this.phoneNumber = phoneNumber + } + + /** The type of entity to create on the account holder */ + fun type(type: EntityType) = type(JsonField.of(type)) + + /** + * Sets [Builder.type] to an arbitrary JSON value. + * + * You should usually call [Builder.type] with a well-typed [EntityType] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun type(type: JsonField) = apply { this.type = type } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [CreateEntityRequest]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .address() + * .dob() + * .email() + * .firstName() + * .governmentId() + * .lastName() + * .phoneNumber() + * .type() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): CreateEntityRequest = + CreateEntityRequest( + checkRequired("address", address), + checkRequired("dob", dob), + checkRequired("email", email), + checkRequired("firstName", firstName), + checkRequired("governmentId", governmentId), + checkRequired("lastName", lastName), + checkRequired("phoneNumber", phoneNumber), + checkRequired("type", type), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): CreateEntityRequest = apply { + if (validated) { + return@apply + } + + address().validate() + dob() + email() + firstName() + governmentId() + lastName() + phoneNumber() + type().validate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (address.asKnown().getOrNull()?.validity() ?: 0) + + (if (dob.asKnown().isPresent) 1 else 0) + + (if (email.asKnown().isPresent) 1 else 0) + + (if (firstName.asKnown().isPresent) 1 else 0) + + (if (governmentId.asKnown().isPresent) 1 else 0) + + (if (lastName.asKnown().isPresent) 1 else 0) + + (if (phoneNumber.asKnown().isPresent) 1 else 0) + + (type.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CreateEntityRequest && + address == other.address && + dob == other.dob && + email == other.email && + firstName == other.firstName && + governmentId == other.governmentId && + lastName == other.lastName && + phoneNumber == other.phoneNumber && + type == other.type && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + address, + dob, + email, + firstName, + governmentId, + lastName, + phoneNumber, + type, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "CreateEntityRequest{address=$address, dob=$dob, email=$email, firstName=$firstName, governmentId=$governmentId, lastName=$lastName, phoneNumber=$phoneNumber, type=$type, additionalProperties=$additionalProperties}" + } + + /** + * Individual's current address - PO boxes, UPS drops, and FedEx drops are not acceptable; + * APO/FPO are acceptable. Only USA addresses are currently supported. + */ + class Address + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val address1: JsonField, + private val city: JsonField, + private val country: JsonField, + private val postalCode: JsonField, + private val state: JsonField, + private val address2: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("address1") + @ExcludeMissing + address1: JsonField = JsonMissing.of(), + @JsonProperty("city") @ExcludeMissing city: JsonField = JsonMissing.of(), + @JsonProperty("country") @ExcludeMissing country: JsonField = JsonMissing.of(), + @JsonProperty("postal_code") + @ExcludeMissing + postalCode: JsonField = JsonMissing.of(), + @JsonProperty("state") @ExcludeMissing state: JsonField = JsonMissing.of(), + @JsonProperty("address2") @ExcludeMissing address2: JsonField = JsonMissing.of(), + ) : this(address1, city, country, postalCode, state, address2, mutableMapOf()) + + /** + * Valid deliverable address (no PO boxes). + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun address1(): String = address1.getRequired("address1") + + /** + * Name of city. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun city(): String = city.getRequired("city") + + /** + * Valid country code. Only USA is currently supported, entered in uppercase ISO 3166-1 + * alpha-3 three-character format. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun country(): String = country.getRequired("country") + + /** + * Valid postal code. Only USA ZIP codes are currently supported, entered as a five-digit + * ZIP or nine-digit ZIP+4. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun postalCode(): String = postalCode.getRequired("postal_code") + + /** + * Valid state code. Only USA state codes are currently supported, entered in uppercase ISO + * 3166-2 two-character format. + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun state(): String = state.getRequired("state") + + /** + * Unit or apartment number (if applicable). + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun address2(): Optional = address2.getOptional("address2") + + /** + * Returns the raw JSON value of [address1]. + * + * Unlike [address1], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("address1") @ExcludeMissing fun _address1(): JsonField = address1 + + /** + * Returns the raw JSON value of [city]. + * + * Unlike [city], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("city") @ExcludeMissing fun _city(): JsonField = city + + /** + * Returns the raw JSON value of [country]. + * + * Unlike [country], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("country") @ExcludeMissing fun _country(): JsonField = country + + /** + * Returns the raw JSON value of [postalCode]. + * + * Unlike [postalCode], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("postal_code") + @ExcludeMissing + fun _postalCode(): JsonField = postalCode + + /** + * Returns the raw JSON value of [state]. + * + * Unlike [state], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("state") @ExcludeMissing fun _state(): JsonField = state + + /** + * Returns the raw JSON value of [address2]. + * + * Unlike [address2], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("address2") @ExcludeMissing fun _address2(): JsonField = address2 + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [Address]. + * + * The following fields are required: + * ```java + * .address1() + * .city() + * .country() + * .postalCode() + * .state() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Address]. */ + class Builder internal constructor() { + + private var address1: JsonField? = null + private var city: JsonField? = null + private var country: JsonField? = null + private var postalCode: JsonField? = null + private var state: JsonField? = null + private var address2: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(address: Address) = apply { + address1 = address.address1 + city = address.city + country = address.country + postalCode = address.postalCode + state = address.state + address2 = address.address2 + additionalProperties = address.additionalProperties.toMutableMap() + } + + /** Valid deliverable address (no PO boxes). */ + fun address1(address1: String) = address1(JsonField.of(address1)) + + /** + * Sets [Builder.address1] to an arbitrary JSON value. + * + * You should usually call [Builder.address1] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun address1(address1: JsonField) = apply { this.address1 = address1 } + + /** Name of city. */ + fun city(city: String) = city(JsonField.of(city)) + + /** + * Sets [Builder.city] to an arbitrary JSON value. + * + * You should usually call [Builder.city] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun city(city: JsonField) = apply { this.city = city } + + /** + * Valid country code. Only USA is currently supported, entered in uppercase ISO 3166-1 + * alpha-3 three-character format. + */ + fun country(country: String) = country(JsonField.of(country)) + + /** + * Sets [Builder.country] to an arbitrary JSON value. + * + * You should usually call [Builder.country] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun country(country: JsonField) = apply { this.country = country } + + /** + * Valid postal code. Only USA ZIP codes are currently supported, entered as a + * five-digit ZIP or nine-digit ZIP+4. + */ + fun postalCode(postalCode: String) = postalCode(JsonField.of(postalCode)) + + /** + * Sets [Builder.postalCode] to an arbitrary JSON value. + * + * You should usually call [Builder.postalCode] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun postalCode(postalCode: JsonField) = apply { this.postalCode = postalCode } + + /** + * Valid state code. Only USA state codes are currently supported, entered in uppercase + * ISO 3166-2 two-character format. + */ + fun state(state: String) = state(JsonField.of(state)) + + /** + * Sets [Builder.state] to an arbitrary JSON value. + * + * You should usually call [Builder.state] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun state(state: JsonField) = apply { this.state = state } + + /** Unit or apartment number (if applicable). */ + fun address2(address2: String) = address2(JsonField.of(address2)) + + /** + * Sets [Builder.address2] to an arbitrary JSON value. + * + * You should usually call [Builder.address2] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun address2(address2: JsonField) = apply { this.address2 = address2 } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [Address]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .address1() + * .city() + * .country() + * .postalCode() + * .state() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): Address = + Address( + checkRequired("address1", address1), + checkRequired("city", city), + checkRequired("country", country), + checkRequired("postalCode", postalCode), + checkRequired("state", state), + address2, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): Address = apply { + if (validated) { + return@apply + } + + address1() + city() + country() + postalCode() + state() + address2() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (address1.asKnown().isPresent) 1 else 0) + + (if (city.asKnown().isPresent) 1 else 0) + + (if (country.asKnown().isPresent) 1 else 0) + + (if (postalCode.asKnown().isPresent) 1 else 0) + + (if (state.asKnown().isPresent) 1 else 0) + + (if (address2.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Address && + address1 == other.address1 && + city == other.city && + country == other.country && + postalCode == other.postalCode && + state == other.state && + address2 == other.address2 && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(address1, city, country, postalCode, state, address2, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Address{address1=$address1, city=$city, country=$country, postalCode=$postalCode, state=$state, address2=$address2, additionalProperties=$additionalProperties}" + } + + /** The type of entity to create on the account holder */ + class EntityType @JsonCreator private constructor(private val value: JsonField) : Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val BENEFICIAL_OWNER_INDIVIDUAL = of("BENEFICIAL_OWNER_INDIVIDUAL") + + @JvmField val CONTROL_PERSON = of("CONTROL_PERSON") + + @JvmStatic fun of(value: String) = EntityType(JsonField.of(value)) + } + + /** An enum containing [EntityType]'s known values. */ + enum class Known { + BENEFICIAL_OWNER_INDIVIDUAL, + CONTROL_PERSON, + } + + /** + * An enum containing [EntityType]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [EntityType] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + BENEFICIAL_OWNER_INDIVIDUAL, + CONTROL_PERSON, + /** + * An enum member indicating that [EntityType] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + BENEFICIAL_OWNER_INDIVIDUAL -> Value.BENEFICIAL_OWNER_INDIVIDUAL + CONTROL_PERSON -> Value.CONTROL_PERSON + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws LithicInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + BENEFICIAL_OWNER_INDIVIDUAL -> Known.BENEFICIAL_OWNER_INDIVIDUAL + CONTROL_PERSON -> Known.CONTROL_PERSON + else -> throw LithicInvalidDataException("Unknown EntityType: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws LithicInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { LithicInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): EntityType = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is EntityType && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AccountHolderEntityCreateParams && + accountHolderToken == other.accountHolderToken && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(accountHolderToken, body, additionalHeaders, additionalQueryParams) + + override fun toString() = + "AccountHolderEntityCreateParams{accountHolderToken=$accountHolderToken, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderEntityDeleteParams.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderEntityDeleteParams.kt new file mode 100644 index 00000000..4b2486ca --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/AccountHolderEntityDeleteParams.kt @@ -0,0 +1,267 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.lithic.api.core.JsonValue +import com.lithic.api.core.Params +import com.lithic.api.core.checkRequired +import com.lithic.api.core.http.Headers +import com.lithic.api.core.http.QueryParams +import com.lithic.api.core.toImmutable +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Deactivate a beneficial owner entity on an existing KYB account holder. Only beneficial owner + * entities can be deactivated. + */ +class AccountHolderEntityDeleteParams +private constructor( + private val accountHolderToken: String, + private val entityToken: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun accountHolderToken(): String = accountHolderToken + + fun entityToken(): Optional = Optional.ofNullable(entityToken) + + /** Additional body properties to send with the request. */ + fun _additionalBodyProperties(): Map = additionalBodyProperties + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [AccountHolderEntityDeleteParams]. + * + * The following fields are required: + * ```java + * .accountHolderToken() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [AccountHolderEntityDeleteParams]. */ + class Builder internal constructor() { + + private var accountHolderToken: String? = null + private var entityToken: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + private var additionalBodyProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(accountHolderEntityDeleteParams: AccountHolderEntityDeleteParams) = + apply { + accountHolderToken = accountHolderEntityDeleteParams.accountHolderToken + entityToken = accountHolderEntityDeleteParams.entityToken + additionalHeaders = accountHolderEntityDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = + accountHolderEntityDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = + accountHolderEntityDeleteParams.additionalBodyProperties.toMutableMap() + } + + fun accountHolderToken(accountHolderToken: String) = apply { + this.accountHolderToken = accountHolderToken + } + + fun entityToken(entityToken: String?) = apply { this.entityToken = entityToken } + + /** Alias for calling [Builder.entityToken] with `entityToken.orElse(null)`. */ + fun entityToken(entityToken: Optional) = entityToken(entityToken.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + this.additionalBodyProperties.clear() + putAllAdditionalBodyProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + additionalBodyProperties.put(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + this.additionalBodyProperties.putAll(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [AccountHolderEntityDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .accountHolderToken() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): AccountHolderEntityDeleteParams = + AccountHolderEntityDeleteParams( + checkRequired("accountHolderToken", accountHolderToken), + entityToken, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> accountHolderToken + 1 -> entityToken ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is AccountHolderEntityDeleteParams && + accountHolderToken == other.accountHolderToken && + entityToken == other.entityToken && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash( + accountHolderToken, + entityToken, + additionalHeaders, + additionalQueryParams, + additionalBodyProperties, + ) + + override fun toString() = + "AccountHolderEntityDeleteParams{accountHolderToken=$accountHolderToken, entityToken=$entityToken, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/CategoryTier.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/CategoryTier.kt new file mode 100644 index 00000000..47e372e3 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/CategoryTier.kt @@ -0,0 +1,190 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.lithic.api.core.ExcludeMissing +import com.lithic.api.core.JsonField +import com.lithic.api.core.JsonMissing +import com.lithic.api.core.JsonValue +import com.lithic.api.errors.LithicInvalidDataException +import java.util.Collections +import java.util.Objects +import java.util.Optional + +/** Rate and rate cap for interest on a category */ +class CategoryTier +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val capRate: JsonField, + private val rate: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("cap_rate") @ExcludeMissing capRate: JsonField = JsonMissing.of(), + @JsonProperty("rate") @ExcludeMissing rate: JsonField = JsonMissing.of(), + ) : this(capRate, rate, mutableMapOf()) + + /** + * Maximum interest rate for this category, e.g. '0.0525' for 5.25% + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun capRate(): Optional = capRate.getOptional("cap_rate") + + /** + * Interest rate for this category, e.g. '0.0525' for 5.25% + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun rate(): Optional = rate.getOptional("rate") + + /** + * Returns the raw JSON value of [capRate]. + * + * Unlike [capRate], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("cap_rate") @ExcludeMissing fun _capRate(): JsonField = capRate + + /** + * Returns the raw JSON value of [rate]. + * + * Unlike [rate], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("rate") @ExcludeMissing fun _rate(): JsonField = rate + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** Returns a mutable builder for constructing an instance of [CategoryTier]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [CategoryTier]. */ + class Builder internal constructor() { + + private var capRate: JsonField = JsonMissing.of() + private var rate: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(categoryTier: CategoryTier) = apply { + capRate = categoryTier.capRate + rate = categoryTier.rate + additionalProperties = categoryTier.additionalProperties.toMutableMap() + } + + /** Maximum interest rate for this category, e.g. '0.0525' for 5.25% */ + fun capRate(capRate: String) = capRate(JsonField.of(capRate)) + + /** + * Sets [Builder.capRate] to an arbitrary JSON value. + * + * You should usually call [Builder.capRate] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun capRate(capRate: JsonField) = apply { this.capRate = capRate } + + /** Interest rate for this category, e.g. '0.0525' for 5.25% */ + fun rate(rate: String) = rate(JsonField.of(rate)) + + /** + * Sets [Builder.rate] to an arbitrary JSON value. + * + * You should usually call [Builder.rate] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun rate(rate: JsonField) = apply { this.rate = rate } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [CategoryTier]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): CategoryTier = CategoryTier(capRate, rate, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): CategoryTier = apply { + if (validated) { + return@apply + } + + capRate() + rate() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (capRate.asKnown().isPresent) 1 else 0) + (if (rate.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is CategoryTier && + capRate == other.capRate && + rate == other.rate && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(capRate, rate, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "CategoryTier{capRate=$capRate, rate=$rate, additionalProperties=$additionalProperties}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/EntityCreateResponse.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/EntityCreateResponse.kt new file mode 100644 index 00000000..85a0d73d --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/EntityCreateResponse.kt @@ -0,0 +1,889 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.lithic.api.core.Enum +import com.lithic.api.core.ExcludeMissing +import com.lithic.api.core.JsonField +import com.lithic.api.core.JsonMissing +import com.lithic.api.core.JsonValue +import com.lithic.api.core.checkKnown +import com.lithic.api.core.checkRequired +import com.lithic.api.core.toImmutable +import com.lithic.api.errors.LithicInvalidDataException +import java.time.OffsetDateTime +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +/** + * Response body for creating a new beneficial owner or replacing the control person entity on an + * existing KYB account holder. + */ +class EntityCreateResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val token: JsonField, + private val accountHolderToken: JsonField, + private val created: JsonField, + private val requiredDocuments: JsonField>, + private val status: JsonField, + private val statusReasons: JsonField>, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("token") @ExcludeMissing token: JsonField = JsonMissing.of(), + @JsonProperty("account_holder_token") + @ExcludeMissing + accountHolderToken: JsonField = JsonMissing.of(), + @JsonProperty("created") + @ExcludeMissing + created: JsonField = JsonMissing.of(), + @JsonProperty("required_documents") + @ExcludeMissing + requiredDocuments: JsonField> = JsonMissing.of(), + @JsonProperty("status") @ExcludeMissing status: JsonField = JsonMissing.of(), + @JsonProperty("status_reasons") + @ExcludeMissing + statusReasons: JsonField> = JsonMissing.of(), + ) : this( + token, + accountHolderToken, + created, + requiredDocuments, + status, + statusReasons, + mutableMapOf(), + ) + + /** + * Globally unique identifier for the entity + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun token(): String = token.getRequired("token") + + /** + * Globally unique identifier for the account holder + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun accountHolderToken(): String = accountHolderToken.getRequired("account_holder_token") + + /** + * Timestamp of when the entity was created + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun created(): OffsetDateTime = created.getRequired("created") + + /** + * A list of documents required for the entity to be approved + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun requiredDocuments(): List = + requiredDocuments.getRequired("required_documents") + + /** + * Entity verification status + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun status(): EntityStatus = status.getRequired("status") + + /** + * Reason for the evaluation status + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun statusReasons(): List = statusReasons.getRequired("status_reasons") + + /** + * Returns the raw JSON value of [token]. + * + * Unlike [token], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("token") @ExcludeMissing fun _token(): JsonField = token + + /** + * Returns the raw JSON value of [accountHolderToken]. + * + * Unlike [accountHolderToken], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("account_holder_token") + @ExcludeMissing + fun _accountHolderToken(): JsonField = accountHolderToken + + /** + * Returns the raw JSON value of [created]. + * + * Unlike [created], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created") @ExcludeMissing fun _created(): JsonField = created + + /** + * Returns the raw JSON value of [requiredDocuments]. + * + * Unlike [requiredDocuments], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("required_documents") + @ExcludeMissing + fun _requiredDocuments(): JsonField> = requiredDocuments + + /** + * Returns the raw JSON value of [status]. + * + * Unlike [status], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status") @ExcludeMissing fun _status(): JsonField = status + + /** + * Returns the raw JSON value of [statusReasons]. + * + * Unlike [statusReasons], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("status_reasons") + @ExcludeMissing + fun _statusReasons(): JsonField> = statusReasons + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [EntityCreateResponse]. + * + * The following fields are required: + * ```java + * .token() + * .accountHolderToken() + * .created() + * .requiredDocuments() + * .status() + * .statusReasons() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [EntityCreateResponse]. */ + class Builder internal constructor() { + + private var token: JsonField? = null + private var accountHolderToken: JsonField? = null + private var created: JsonField? = null + private var requiredDocuments: JsonField>? = null + private var status: JsonField? = null + private var statusReasons: JsonField>? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(entityCreateResponse: EntityCreateResponse) = apply { + token = entityCreateResponse.token + accountHolderToken = entityCreateResponse.accountHolderToken + created = entityCreateResponse.created + requiredDocuments = entityCreateResponse.requiredDocuments.map { it.toMutableList() } + status = entityCreateResponse.status + statusReasons = entityCreateResponse.statusReasons.map { it.toMutableList() } + additionalProperties = entityCreateResponse.additionalProperties.toMutableMap() + } + + /** Globally unique identifier for the entity */ + fun token(token: String) = token(JsonField.of(token)) + + /** + * Sets [Builder.token] to an arbitrary JSON value. + * + * You should usually call [Builder.token] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun token(token: JsonField) = apply { this.token = token } + + /** Globally unique identifier for the account holder */ + fun accountHolderToken(accountHolderToken: String) = + accountHolderToken(JsonField.of(accountHolderToken)) + + /** + * Sets [Builder.accountHolderToken] to an arbitrary JSON value. + * + * You should usually call [Builder.accountHolderToken] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun accountHolderToken(accountHolderToken: JsonField) = apply { + this.accountHolderToken = accountHolderToken + } + + /** Timestamp of when the entity was created */ + fun created(created: OffsetDateTime) = created(JsonField.of(created)) + + /** + * Sets [Builder.created] to an arbitrary JSON value. + * + * You should usually call [Builder.created] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun created(created: JsonField) = apply { this.created = created } + + /** A list of documents required for the entity to be approved */ + fun requiredDocuments(requiredDocuments: List) = + requiredDocuments(JsonField.of(requiredDocuments)) + + /** + * Sets [Builder.requiredDocuments] to an arbitrary JSON value. + * + * You should usually call [Builder.requiredDocuments] with a well-typed + * `List` value instead. This method is primarily for setting the field to + * an undocumented or not yet supported value. + */ + fun requiredDocuments(requiredDocuments: JsonField>) = apply { + this.requiredDocuments = requiredDocuments.map { it.toMutableList() } + } + + /** + * Adds a single [RequiredDocument] to [requiredDocuments]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addRequiredDocument(requiredDocument: RequiredDocument) = apply { + requiredDocuments = + (requiredDocuments ?: JsonField.of(mutableListOf())).also { + checkKnown("requiredDocuments", it).add(requiredDocument) + } + } + + /** Entity verification status */ + fun status(status: EntityStatus) = status(JsonField.of(status)) + + /** + * Sets [Builder.status] to an arbitrary JSON value. + * + * You should usually call [Builder.status] with a well-typed [EntityStatus] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun status(status: JsonField) = apply { this.status = status } + + /** Reason for the evaluation status */ + fun statusReasons(statusReasons: List) = + statusReasons(JsonField.of(statusReasons)) + + /** + * Sets [Builder.statusReasons] to an arbitrary JSON value. + * + * You should usually call [Builder.statusReasons] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun statusReasons(statusReasons: JsonField>) = apply { + this.statusReasons = statusReasons.map { it.toMutableList() } + } + + /** + * Adds a single [StatusReasons] to [statusReasons]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addStatusReason(statusReason: StatusReasons) = apply { + statusReasons = + (statusReasons ?: JsonField.of(mutableListOf())).also { + checkKnown("statusReasons", it).add(statusReason) + } + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [EntityCreateResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .token() + * .accountHolderToken() + * .created() + * .requiredDocuments() + * .status() + * .statusReasons() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): EntityCreateResponse = + EntityCreateResponse( + checkRequired("token", token), + checkRequired("accountHolderToken", accountHolderToken), + checkRequired("created", created), + checkRequired("requiredDocuments", requiredDocuments).map { it.toImmutable() }, + checkRequired("status", status), + checkRequired("statusReasons", statusReasons).map { it.toImmutable() }, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): EntityCreateResponse = apply { + if (validated) { + return@apply + } + + token() + accountHolderToken() + created() + requiredDocuments().forEach { it.validate() } + status().validate() + statusReasons().forEach { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (token.asKnown().isPresent) 1 else 0) + + (if (accountHolderToken.asKnown().isPresent) 1 else 0) + + (if (created.asKnown().isPresent) 1 else 0) + + (requiredDocuments.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (status.asKnown().getOrNull()?.validity() ?: 0) + + (statusReasons.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + /** Entity verification status */ + class EntityStatus @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val ACCEPTED = of("ACCEPTED") + + @JvmField val INACTIVE = of("INACTIVE") + + @JvmField val PENDING_REVIEW = of("PENDING_REVIEW") + + @JvmField val REJECTED = of("REJECTED") + + @JvmStatic fun of(value: String) = EntityStatus(JsonField.of(value)) + } + + /** An enum containing [EntityStatus]'s known values. */ + enum class Known { + ACCEPTED, + INACTIVE, + PENDING_REVIEW, + REJECTED, + } + + /** + * An enum containing [EntityStatus]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [EntityStatus] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + ACCEPTED, + INACTIVE, + PENDING_REVIEW, + REJECTED, + /** + * An enum member indicating that [EntityStatus] was instantiated with an unknown value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + ACCEPTED -> Value.ACCEPTED + INACTIVE -> Value.INACTIVE + PENDING_REVIEW -> Value.PENDING_REVIEW + REJECTED -> Value.REJECTED + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws LithicInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + ACCEPTED -> Known.ACCEPTED + INACTIVE -> Known.INACTIVE + PENDING_REVIEW -> Known.PENDING_REVIEW + REJECTED -> Known.REJECTED + else -> throw LithicInvalidDataException("Unknown EntityStatus: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws LithicInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { LithicInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): EntityStatus = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is EntityStatus && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + /** Status Reasons for KYC/KYB enrollment states */ + class StatusReasons @JsonCreator private constructor(private val value: JsonField) : + Enum { + + /** + * Returns this class instance's raw value. + * + * This is usually only useful if this instance was deserialized from data that doesn't + * match any known member, and you want to know that value. For example, if the SDK is on an + * older version than the API, then the API may respond with new members that the SDK is + * unaware of. + */ + @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value + + companion object { + + @JvmField val ADDRESS_VERIFICATION_FAILURE = of("ADDRESS_VERIFICATION_FAILURE") + + @JvmField val AGE_THRESHOLD_FAILURE = of("AGE_THRESHOLD_FAILURE") + + @JvmField val COMPLETE_VERIFICATION_FAILURE = of("COMPLETE_VERIFICATION_FAILURE") + + @JvmField val DOB_VERIFICATION_FAILURE = of("DOB_VERIFICATION_FAILURE") + + @JvmField val ID_VERIFICATION_FAILURE = of("ID_VERIFICATION_FAILURE") + + @JvmField val MAX_DOCUMENT_ATTEMPTS = of("MAX_DOCUMENT_ATTEMPTS") + + @JvmField val MAX_RESUBMISSION_ATTEMPTS = of("MAX_RESUBMISSION_ATTEMPTS") + + @JvmField val NAME_VERIFICATION_FAILURE = of("NAME_VERIFICATION_FAILURE") + + @JvmField val OTHER_VERIFICATION_FAILURE = of("OTHER_VERIFICATION_FAILURE") + + @JvmField val RISK_THRESHOLD_FAILURE = of("RISK_THRESHOLD_FAILURE") + + @JvmField val WATCHLIST_ALERT_FAILURE = of("WATCHLIST_ALERT_FAILURE") + + @JvmField + val PRIMARY_BUSINESS_ENTITY_ID_VERIFICATION_FAILURE = + of("PRIMARY_BUSINESS_ENTITY_ID_VERIFICATION_FAILURE") + + @JvmField + val PRIMARY_BUSINESS_ENTITY_ADDRESS_VERIFICATION_FAILURE = + of("PRIMARY_BUSINESS_ENTITY_ADDRESS_VERIFICATION_FAILURE") + + @JvmField + val PRIMARY_BUSINESS_ENTITY_NAME_VERIFICATION_FAILURE = + of("PRIMARY_BUSINESS_ENTITY_NAME_VERIFICATION_FAILURE") + + @JvmField + val PRIMARY_BUSINESS_ENTITY_BUSINESS_OFFICERS_NOT_MATCHED = + of("PRIMARY_BUSINESS_ENTITY_BUSINESS_OFFICERS_NOT_MATCHED") + + @JvmField + val PRIMARY_BUSINESS_ENTITY_SOS_FILING_INACTIVE = + of("PRIMARY_BUSINESS_ENTITY_SOS_FILING_INACTIVE") + + @JvmField + val PRIMARY_BUSINESS_ENTITY_SOS_NOT_MATCHED = + of("PRIMARY_BUSINESS_ENTITY_SOS_NOT_MATCHED") + + @JvmField + val PRIMARY_BUSINESS_ENTITY_CMRA_FAILURE = of("PRIMARY_BUSINESS_ENTITY_CMRA_FAILURE") + + @JvmField + val PRIMARY_BUSINESS_ENTITY_WATCHLIST_FAILURE = + of("PRIMARY_BUSINESS_ENTITY_WATCHLIST_FAILURE") + + @JvmField + val PRIMARY_BUSINESS_ENTITY_REGISTERED_AGENT_FAILURE = + of("PRIMARY_BUSINESS_ENTITY_REGISTERED_AGENT_FAILURE") + + @JvmField + val CONTROL_PERSON_BLOCKLIST_ALERT_FAILURE = + of("CONTROL_PERSON_BLOCKLIST_ALERT_FAILURE") + + @JvmField + val CONTROL_PERSON_ID_VERIFICATION_FAILURE = + of("CONTROL_PERSON_ID_VERIFICATION_FAILURE") + + @JvmField + val CONTROL_PERSON_DOB_VERIFICATION_FAILURE = + of("CONTROL_PERSON_DOB_VERIFICATION_FAILURE") + + @JvmField + val CONTROL_PERSON_NAME_VERIFICATION_FAILURE = + of("CONTROL_PERSON_NAME_VERIFICATION_FAILURE") + + @JvmStatic fun of(value: String) = StatusReasons(JsonField.of(value)) + } + + /** An enum containing [StatusReasons]'s known values. */ + enum class Known { + ADDRESS_VERIFICATION_FAILURE, + AGE_THRESHOLD_FAILURE, + COMPLETE_VERIFICATION_FAILURE, + DOB_VERIFICATION_FAILURE, + ID_VERIFICATION_FAILURE, + MAX_DOCUMENT_ATTEMPTS, + MAX_RESUBMISSION_ATTEMPTS, + NAME_VERIFICATION_FAILURE, + OTHER_VERIFICATION_FAILURE, + RISK_THRESHOLD_FAILURE, + WATCHLIST_ALERT_FAILURE, + PRIMARY_BUSINESS_ENTITY_ID_VERIFICATION_FAILURE, + PRIMARY_BUSINESS_ENTITY_ADDRESS_VERIFICATION_FAILURE, + PRIMARY_BUSINESS_ENTITY_NAME_VERIFICATION_FAILURE, + PRIMARY_BUSINESS_ENTITY_BUSINESS_OFFICERS_NOT_MATCHED, + PRIMARY_BUSINESS_ENTITY_SOS_FILING_INACTIVE, + PRIMARY_BUSINESS_ENTITY_SOS_NOT_MATCHED, + PRIMARY_BUSINESS_ENTITY_CMRA_FAILURE, + PRIMARY_BUSINESS_ENTITY_WATCHLIST_FAILURE, + PRIMARY_BUSINESS_ENTITY_REGISTERED_AGENT_FAILURE, + CONTROL_PERSON_BLOCKLIST_ALERT_FAILURE, + CONTROL_PERSON_ID_VERIFICATION_FAILURE, + CONTROL_PERSON_DOB_VERIFICATION_FAILURE, + CONTROL_PERSON_NAME_VERIFICATION_FAILURE, + } + + /** + * An enum containing [StatusReasons]'s known values, as well as an [_UNKNOWN] member. + * + * An instance of [StatusReasons] can contain an unknown value in a couple of cases: + * - It was deserialized from data that doesn't match any known member. For example, if the + * SDK is on an older version than the API, then the API may respond with new members that + * the SDK is unaware of. + * - It was constructed with an arbitrary value using the [of] method. + */ + enum class Value { + ADDRESS_VERIFICATION_FAILURE, + AGE_THRESHOLD_FAILURE, + COMPLETE_VERIFICATION_FAILURE, + DOB_VERIFICATION_FAILURE, + ID_VERIFICATION_FAILURE, + MAX_DOCUMENT_ATTEMPTS, + MAX_RESUBMISSION_ATTEMPTS, + NAME_VERIFICATION_FAILURE, + OTHER_VERIFICATION_FAILURE, + RISK_THRESHOLD_FAILURE, + WATCHLIST_ALERT_FAILURE, + PRIMARY_BUSINESS_ENTITY_ID_VERIFICATION_FAILURE, + PRIMARY_BUSINESS_ENTITY_ADDRESS_VERIFICATION_FAILURE, + PRIMARY_BUSINESS_ENTITY_NAME_VERIFICATION_FAILURE, + PRIMARY_BUSINESS_ENTITY_BUSINESS_OFFICERS_NOT_MATCHED, + PRIMARY_BUSINESS_ENTITY_SOS_FILING_INACTIVE, + PRIMARY_BUSINESS_ENTITY_SOS_NOT_MATCHED, + PRIMARY_BUSINESS_ENTITY_CMRA_FAILURE, + PRIMARY_BUSINESS_ENTITY_WATCHLIST_FAILURE, + PRIMARY_BUSINESS_ENTITY_REGISTERED_AGENT_FAILURE, + CONTROL_PERSON_BLOCKLIST_ALERT_FAILURE, + CONTROL_PERSON_ID_VERIFICATION_FAILURE, + CONTROL_PERSON_DOB_VERIFICATION_FAILURE, + CONTROL_PERSON_NAME_VERIFICATION_FAILURE, + /** + * An enum member indicating that [StatusReasons] was instantiated with an unknown + * value. + */ + _UNKNOWN, + } + + /** + * Returns an enum member corresponding to this class instance's value, or [Value._UNKNOWN] + * if the class was instantiated with an unknown value. + * + * Use the [known] method instead if you're certain the value is always known or if you want + * to throw for the unknown case. + */ + fun value(): Value = + when (this) { + ADDRESS_VERIFICATION_FAILURE -> Value.ADDRESS_VERIFICATION_FAILURE + AGE_THRESHOLD_FAILURE -> Value.AGE_THRESHOLD_FAILURE + COMPLETE_VERIFICATION_FAILURE -> Value.COMPLETE_VERIFICATION_FAILURE + DOB_VERIFICATION_FAILURE -> Value.DOB_VERIFICATION_FAILURE + ID_VERIFICATION_FAILURE -> Value.ID_VERIFICATION_FAILURE + MAX_DOCUMENT_ATTEMPTS -> Value.MAX_DOCUMENT_ATTEMPTS + MAX_RESUBMISSION_ATTEMPTS -> Value.MAX_RESUBMISSION_ATTEMPTS + NAME_VERIFICATION_FAILURE -> Value.NAME_VERIFICATION_FAILURE + OTHER_VERIFICATION_FAILURE -> Value.OTHER_VERIFICATION_FAILURE + RISK_THRESHOLD_FAILURE -> Value.RISK_THRESHOLD_FAILURE + WATCHLIST_ALERT_FAILURE -> Value.WATCHLIST_ALERT_FAILURE + PRIMARY_BUSINESS_ENTITY_ID_VERIFICATION_FAILURE -> + Value.PRIMARY_BUSINESS_ENTITY_ID_VERIFICATION_FAILURE + PRIMARY_BUSINESS_ENTITY_ADDRESS_VERIFICATION_FAILURE -> + Value.PRIMARY_BUSINESS_ENTITY_ADDRESS_VERIFICATION_FAILURE + PRIMARY_BUSINESS_ENTITY_NAME_VERIFICATION_FAILURE -> + Value.PRIMARY_BUSINESS_ENTITY_NAME_VERIFICATION_FAILURE + PRIMARY_BUSINESS_ENTITY_BUSINESS_OFFICERS_NOT_MATCHED -> + Value.PRIMARY_BUSINESS_ENTITY_BUSINESS_OFFICERS_NOT_MATCHED + PRIMARY_BUSINESS_ENTITY_SOS_FILING_INACTIVE -> + Value.PRIMARY_BUSINESS_ENTITY_SOS_FILING_INACTIVE + PRIMARY_BUSINESS_ENTITY_SOS_NOT_MATCHED -> + Value.PRIMARY_BUSINESS_ENTITY_SOS_NOT_MATCHED + PRIMARY_BUSINESS_ENTITY_CMRA_FAILURE -> Value.PRIMARY_BUSINESS_ENTITY_CMRA_FAILURE + PRIMARY_BUSINESS_ENTITY_WATCHLIST_FAILURE -> + Value.PRIMARY_BUSINESS_ENTITY_WATCHLIST_FAILURE + PRIMARY_BUSINESS_ENTITY_REGISTERED_AGENT_FAILURE -> + Value.PRIMARY_BUSINESS_ENTITY_REGISTERED_AGENT_FAILURE + CONTROL_PERSON_BLOCKLIST_ALERT_FAILURE -> + Value.CONTROL_PERSON_BLOCKLIST_ALERT_FAILURE + CONTROL_PERSON_ID_VERIFICATION_FAILURE -> + Value.CONTROL_PERSON_ID_VERIFICATION_FAILURE + CONTROL_PERSON_DOB_VERIFICATION_FAILURE -> + Value.CONTROL_PERSON_DOB_VERIFICATION_FAILURE + CONTROL_PERSON_NAME_VERIFICATION_FAILURE -> + Value.CONTROL_PERSON_NAME_VERIFICATION_FAILURE + else -> Value._UNKNOWN + } + + /** + * Returns an enum member corresponding to this class instance's value. + * + * Use the [value] method instead if you're uncertain the value is always known and don't + * want to throw for the unknown case. + * + * @throws LithicInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + ADDRESS_VERIFICATION_FAILURE -> Known.ADDRESS_VERIFICATION_FAILURE + AGE_THRESHOLD_FAILURE -> Known.AGE_THRESHOLD_FAILURE + COMPLETE_VERIFICATION_FAILURE -> Known.COMPLETE_VERIFICATION_FAILURE + DOB_VERIFICATION_FAILURE -> Known.DOB_VERIFICATION_FAILURE + ID_VERIFICATION_FAILURE -> Known.ID_VERIFICATION_FAILURE + MAX_DOCUMENT_ATTEMPTS -> Known.MAX_DOCUMENT_ATTEMPTS + MAX_RESUBMISSION_ATTEMPTS -> Known.MAX_RESUBMISSION_ATTEMPTS + NAME_VERIFICATION_FAILURE -> Known.NAME_VERIFICATION_FAILURE + OTHER_VERIFICATION_FAILURE -> Known.OTHER_VERIFICATION_FAILURE + RISK_THRESHOLD_FAILURE -> Known.RISK_THRESHOLD_FAILURE + WATCHLIST_ALERT_FAILURE -> Known.WATCHLIST_ALERT_FAILURE + PRIMARY_BUSINESS_ENTITY_ID_VERIFICATION_FAILURE -> + Known.PRIMARY_BUSINESS_ENTITY_ID_VERIFICATION_FAILURE + PRIMARY_BUSINESS_ENTITY_ADDRESS_VERIFICATION_FAILURE -> + Known.PRIMARY_BUSINESS_ENTITY_ADDRESS_VERIFICATION_FAILURE + PRIMARY_BUSINESS_ENTITY_NAME_VERIFICATION_FAILURE -> + Known.PRIMARY_BUSINESS_ENTITY_NAME_VERIFICATION_FAILURE + PRIMARY_BUSINESS_ENTITY_BUSINESS_OFFICERS_NOT_MATCHED -> + Known.PRIMARY_BUSINESS_ENTITY_BUSINESS_OFFICERS_NOT_MATCHED + PRIMARY_BUSINESS_ENTITY_SOS_FILING_INACTIVE -> + Known.PRIMARY_BUSINESS_ENTITY_SOS_FILING_INACTIVE + PRIMARY_BUSINESS_ENTITY_SOS_NOT_MATCHED -> + Known.PRIMARY_BUSINESS_ENTITY_SOS_NOT_MATCHED + PRIMARY_BUSINESS_ENTITY_CMRA_FAILURE -> Known.PRIMARY_BUSINESS_ENTITY_CMRA_FAILURE + PRIMARY_BUSINESS_ENTITY_WATCHLIST_FAILURE -> + Known.PRIMARY_BUSINESS_ENTITY_WATCHLIST_FAILURE + PRIMARY_BUSINESS_ENTITY_REGISTERED_AGENT_FAILURE -> + Known.PRIMARY_BUSINESS_ENTITY_REGISTERED_AGENT_FAILURE + CONTROL_PERSON_BLOCKLIST_ALERT_FAILURE -> + Known.CONTROL_PERSON_BLOCKLIST_ALERT_FAILURE + CONTROL_PERSON_ID_VERIFICATION_FAILURE -> + Known.CONTROL_PERSON_ID_VERIFICATION_FAILURE + CONTROL_PERSON_DOB_VERIFICATION_FAILURE -> + Known.CONTROL_PERSON_DOB_VERIFICATION_FAILURE + CONTROL_PERSON_NAME_VERIFICATION_FAILURE -> + Known.CONTROL_PERSON_NAME_VERIFICATION_FAILURE + else -> throw LithicInvalidDataException("Unknown StatusReasons: $value") + } + + /** + * Returns this class instance's primitive wire representation. + * + * This differs from the [toString] method because that method is primarily for debugging + * and generally doesn't throw. + * + * @throws LithicInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { LithicInvalidDataException("Value is not a String") } + + private var validated: Boolean = false + + fun validate(): StatusReasons = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1 + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is StatusReasons && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is EntityCreateResponse && + token == other.token && + accountHolderToken == other.accountHolderToken && + created == other.created && + requiredDocuments == other.requiredDocuments && + status == other.status && + statusReasons == other.statusReasons && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + token, + accountHolderToken, + created, + requiredDocuments, + status, + statusReasons, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "EntityCreateResponse{token=$token, accountHolderToken=$accountHolderToken, created=$created, requiredDocuments=$requiredDocuments, status=$status, statusReasons=$statusReasons, additionalProperties=$additionalProperties}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccount.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccount.kt index 9d2201cf..1980c5a5 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccount.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccount.kt @@ -1406,6 +1406,8 @@ private constructor( @JvmField val DELINQUENT = of("DELINQUENT") + @JvmField val INTEREST_AND_FEES_PAUSED = of("INTEREST_AND_FEES_PAUSED") + @JvmStatic fun of(value: String) = FinancialAccountSubstatus(JsonField.of(value)) } @@ -1416,6 +1418,7 @@ private constructor( END_USER_REQUEST, BANK_REQUEST, DELINQUENT, + INTEREST_AND_FEES_PAUSED, } /** @@ -1435,6 +1438,7 @@ private constructor( END_USER_REQUEST, BANK_REQUEST, DELINQUENT, + INTEREST_AND_FEES_PAUSED, /** * An enum member indicating that [FinancialAccountSubstatus] was instantiated with an * unknown value. @@ -1456,6 +1460,7 @@ private constructor( END_USER_REQUEST -> Value.END_USER_REQUEST BANK_REQUEST -> Value.BANK_REQUEST DELINQUENT -> Value.DELINQUENT + INTEREST_AND_FEES_PAUSED -> Value.INTEREST_AND_FEES_PAUSED else -> Value._UNKNOWN } @@ -1475,6 +1480,7 @@ private constructor( END_USER_REQUEST -> Known.END_USER_REQUEST BANK_REQUEST -> Known.BANK_REQUEST DELINQUENT -> Known.DELINQUENT + INTEREST_AND_FEES_PAUSED -> Known.INTEREST_AND_FEES_PAUSED else -> throw LithicInvalidDataException("Unknown FinancialAccountSubstatus: $value") } diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleCreateParams.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleCreateParams.kt new file mode 100644 index 00000000..cc2b3ffb --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleCreateParams.kt @@ -0,0 +1,245 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.lithic.api.core.JsonValue +import com.lithic.api.core.Params +import com.lithic.api.core.checkRequired +import com.lithic.api.core.http.Headers +import com.lithic.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Create a new interest tier schedule entry for a supported financial account */ +class FinancialAccountInterestTierScheduleCreateParams +private constructor( + private val financialAccountToken: String?, + private val interestTierSchedule: InterestTierSchedule, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun financialAccountToken(): Optional = Optional.ofNullable(financialAccountToken) + + /** Entry in the Tier Schedule of an account */ + fun interestTierSchedule(): InterestTierSchedule = interestTierSchedule + + fun _additionalBodyProperties(): Map = + interestTierSchedule._additionalProperties() + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [FinancialAccountInterestTierScheduleCreateParams]. + * + * The following fields are required: + * ```java + * .interestTierSchedule() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FinancialAccountInterestTierScheduleCreateParams]. */ + class Builder internal constructor() { + + private var financialAccountToken: String? = null + private var interestTierSchedule: InterestTierSchedule? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from( + financialAccountInterestTierScheduleCreateParams: + FinancialAccountInterestTierScheduleCreateParams + ) = apply { + financialAccountToken = + financialAccountInterestTierScheduleCreateParams.financialAccountToken + interestTierSchedule = + financialAccountInterestTierScheduleCreateParams.interestTierSchedule + additionalHeaders = + financialAccountInterestTierScheduleCreateParams.additionalHeaders.toBuilder() + additionalQueryParams = + financialAccountInterestTierScheduleCreateParams.additionalQueryParams.toBuilder() + } + + fun financialAccountToken(financialAccountToken: String?) = apply { + this.financialAccountToken = financialAccountToken + } + + /** + * Alias for calling [Builder.financialAccountToken] with + * `financialAccountToken.orElse(null)`. + */ + fun financialAccountToken(financialAccountToken: Optional) = + financialAccountToken(financialAccountToken.getOrNull()) + + /** Entry in the Tier Schedule of an account */ + fun interestTierSchedule(interestTierSchedule: InterestTierSchedule) = apply { + this.interestTierSchedule = interestTierSchedule + } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [FinancialAccountInterestTierScheduleCreateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .interestTierSchedule() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): FinancialAccountInterestTierScheduleCreateParams = + FinancialAccountInterestTierScheduleCreateParams( + financialAccountToken, + checkRequired("interestTierSchedule", interestTierSchedule), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): InterestTierSchedule = interestTierSchedule + + fun _pathParam(index: Int): String = + when (index) { + 0 -> financialAccountToken ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FinancialAccountInterestTierScheduleCreateParams && + financialAccountToken == other.financialAccountToken && + interestTierSchedule == other.interestTierSchedule && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash( + financialAccountToken, + interestTierSchedule, + additionalHeaders, + additionalQueryParams, + ) + + override fun toString() = + "FinancialAccountInterestTierScheduleCreateParams{financialAccountToken=$financialAccountToken, interestTierSchedule=$interestTierSchedule, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleDeleteParams.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleDeleteParams.kt new file mode 100644 index 00000000..f4e50c36 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleDeleteParams.kt @@ -0,0 +1,285 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.lithic.api.core.JsonValue +import com.lithic.api.core.Params +import com.lithic.api.core.checkRequired +import com.lithic.api.core.http.Headers +import com.lithic.api.core.http.QueryParams +import com.lithic.api.core.toImmutable +import java.time.LocalDate +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * Delete an interest tier schedule entry. + * + * Returns: + * - 400 Bad Request: Invalid effective_date format OR attempting to delete the earliest tier + * schedule entry for a non-PENDING account + * - 404 Not Found: Tier schedule entry not found for the given effective_date OR ledger account not + * found + * + * Note: PENDING accounts can delete the earliest tier schedule entry (account hasn't opened yet). + * Active/non-PENDING accounts cannot delete the earliest entry to prevent orphaning the account. + * + * If the deleted tier schedule has a past effective_date and the account is ACTIVE, the loan tape + * rebuild configuration will be updated to trigger rebuilds from that date. + */ +class FinancialAccountInterestTierScheduleDeleteParams +private constructor( + private val financialAccountToken: String, + private val effectiveDate: LocalDate?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, + private val additionalBodyProperties: Map, +) : Params { + + fun financialAccountToken(): String = financialAccountToken + + fun effectiveDate(): Optional = Optional.ofNullable(effectiveDate) + + /** Additional body properties to send with the request. */ + fun _additionalBodyProperties(): Map = additionalBodyProperties + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [FinancialAccountInterestTierScheduleDeleteParams]. + * + * The following fields are required: + * ```java + * .financialAccountToken() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FinancialAccountInterestTierScheduleDeleteParams]. */ + class Builder internal constructor() { + + private var financialAccountToken: String? = null + private var effectiveDate: LocalDate? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + private var additionalBodyProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from( + financialAccountInterestTierScheduleDeleteParams: + FinancialAccountInterestTierScheduleDeleteParams + ) = apply { + financialAccountToken = + financialAccountInterestTierScheduleDeleteParams.financialAccountToken + effectiveDate = financialAccountInterestTierScheduleDeleteParams.effectiveDate + additionalHeaders = + financialAccountInterestTierScheduleDeleteParams.additionalHeaders.toBuilder() + additionalQueryParams = + financialAccountInterestTierScheduleDeleteParams.additionalQueryParams.toBuilder() + additionalBodyProperties = + financialAccountInterestTierScheduleDeleteParams.additionalBodyProperties + .toMutableMap() + } + + fun financialAccountToken(financialAccountToken: String) = apply { + this.financialAccountToken = financialAccountToken + } + + fun effectiveDate(effectiveDate: LocalDate?) = apply { this.effectiveDate = effectiveDate } + + /** Alias for calling [Builder.effectiveDate] with `effectiveDate.orElse(null)`. */ + fun effectiveDate(effectiveDate: Optional) = + effectiveDate(effectiveDate.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + this.additionalBodyProperties.clear() + putAllAdditionalBodyProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + additionalBodyProperties.put(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + this.additionalBodyProperties.putAll(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { + additionalBodyProperties.remove(key) + } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalBodyProperty) + } + + /** + * Returns an immutable instance of [FinancialAccountInterestTierScheduleDeleteParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .financialAccountToken() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): FinancialAccountInterestTierScheduleDeleteParams = + FinancialAccountInterestTierScheduleDeleteParams( + checkRequired("financialAccountToken", financialAccountToken), + effectiveDate, + additionalHeaders.build(), + additionalQueryParams.build(), + additionalBodyProperties.toImmutable(), + ) + } + + fun _body(): Optional> = + Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + + fun _pathParam(index: Int): String = + when (index) { + 0 -> financialAccountToken + 1 -> effectiveDate?.toString() ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FinancialAccountInterestTierScheduleDeleteParams && + financialAccountToken == other.financialAccountToken && + effectiveDate == other.effectiveDate && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams && + additionalBodyProperties == other.additionalBodyProperties + } + + override fun hashCode(): Int = + Objects.hash( + financialAccountToken, + effectiveDate, + additionalHeaders, + additionalQueryParams, + additionalBodyProperties, + ) + + override fun toString() = + "FinancialAccountInterestTierScheduleDeleteParams{financialAccountToken=$financialAccountToken, effectiveDate=$effectiveDate, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListPage.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListPage.kt new file mode 100644 index 00000000..3ec79c93 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListPage.kt @@ -0,0 +1,140 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.lithic.api.core.AutoPager +import com.lithic.api.core.Page +import com.lithic.api.core.checkRequired +import com.lithic.api.services.blocking.financialAccounts.InterestTierScheduleService +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** @see InterestTierScheduleService.list */ +class FinancialAccountInterestTierScheduleListPage +private constructor( + private val service: InterestTierScheduleService, + private val params: FinancialAccountInterestTierScheduleListParams, + private val response: FinancialAccountInterestTierScheduleListPageResponse, +) : Page { + + /** + * Delegates to [FinancialAccountInterestTierScheduleListPageResponse], but gracefully handles + * missing data. + * + * @see FinancialAccountInterestTierScheduleListPageResponse.data + */ + fun data(): List = + response._data().getOptional("data").getOrNull() ?: emptyList() + + /** + * Delegates to [FinancialAccountInterestTierScheduleListPageResponse], but gracefully handles + * missing data. + * + * @see FinancialAccountInterestTierScheduleListPageResponse.hasMore + */ + fun hasMore(): Optional = response._hasMore().getOptional("has_more") + + override fun items(): List = data() + + override fun hasNextPage(): Boolean = false + + fun nextPageParams(): FinancialAccountInterestTierScheduleListParams = + throw IllegalStateException("Cannot construct next page params") + + override fun nextPage(): FinancialAccountInterestTierScheduleListPage = + service.list(nextPageParams()) + + fun autoPager(): AutoPager = AutoPager.from(this) + + /** The parameters that were used to request this page. */ + fun params(): FinancialAccountInterestTierScheduleListParams = params + + /** The response that this page was parsed from. */ + fun response(): FinancialAccountInterestTierScheduleListPageResponse = response + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [FinancialAccountInterestTierScheduleListPage]. + * + * The following fields are required: + * ```java + * .service() + * .params() + * .response() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FinancialAccountInterestTierScheduleListPage]. */ + class Builder internal constructor() { + + private var service: InterestTierScheduleService? = null + private var params: FinancialAccountInterestTierScheduleListParams? = null + private var response: FinancialAccountInterestTierScheduleListPageResponse? = null + + @JvmSynthetic + internal fun from( + financialAccountInterestTierScheduleListPage: + FinancialAccountInterestTierScheduleListPage + ) = apply { + service = financialAccountInterestTierScheduleListPage.service + params = financialAccountInterestTierScheduleListPage.params + response = financialAccountInterestTierScheduleListPage.response + } + + fun service(service: InterestTierScheduleService) = apply { this.service = service } + + /** The parameters that were used to request this page. */ + fun params(params: FinancialAccountInterestTierScheduleListParams) = apply { + this.params = params + } + + /** The response that this page was parsed from. */ + fun response(response: FinancialAccountInterestTierScheduleListPageResponse) = apply { + this.response = response + } + + /** + * Returns an immutable instance of [FinancialAccountInterestTierScheduleListPage]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .service() + * .params() + * .response() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): FinancialAccountInterestTierScheduleListPage = + FinancialAccountInterestTierScheduleListPage( + checkRequired("service", service), + checkRequired("params", params), + checkRequired("response", response), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FinancialAccountInterestTierScheduleListPage && + service == other.service && + params == other.params && + response == other.response + } + + override fun hashCode(): Int = Objects.hash(service, params, response) + + override fun toString() = + "FinancialAccountInterestTierScheduleListPage{service=$service, params=$params, response=$response}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListPageAsync.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListPageAsync.kt new file mode 100644 index 00000000..83222684 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListPageAsync.kt @@ -0,0 +1,155 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.lithic.api.core.AutoPagerAsync +import com.lithic.api.core.PageAsync +import com.lithic.api.core.checkRequired +import com.lithic.api.services.async.financialAccounts.InterestTierScheduleServiceAsync +import java.util.Objects +import java.util.Optional +import java.util.concurrent.CompletableFuture +import java.util.concurrent.Executor +import kotlin.jvm.optionals.getOrNull + +/** @see InterestTierScheduleServiceAsync.list */ +class FinancialAccountInterestTierScheduleListPageAsync +private constructor( + private val service: InterestTierScheduleServiceAsync, + private val streamHandlerExecutor: Executor, + private val params: FinancialAccountInterestTierScheduleListParams, + private val response: FinancialAccountInterestTierScheduleListPageResponse, +) : PageAsync { + + /** + * Delegates to [FinancialAccountInterestTierScheduleListPageResponse], but gracefully handles + * missing data. + * + * @see FinancialAccountInterestTierScheduleListPageResponse.data + */ + fun data(): List = + response._data().getOptional("data").getOrNull() ?: emptyList() + + /** + * Delegates to [FinancialAccountInterestTierScheduleListPageResponse], but gracefully handles + * missing data. + * + * @see FinancialAccountInterestTierScheduleListPageResponse.hasMore + */ + fun hasMore(): Optional = response._hasMore().getOptional("has_more") + + override fun items(): List = data() + + override fun hasNextPage(): Boolean = false + + fun nextPageParams(): FinancialAccountInterestTierScheduleListParams = + throw IllegalStateException("Cannot construct next page params") + + override fun nextPage(): CompletableFuture = + service.list(nextPageParams()) + + fun autoPager(): AutoPagerAsync = + AutoPagerAsync.from(this, streamHandlerExecutor) + + /** The parameters that were used to request this page. */ + fun params(): FinancialAccountInterestTierScheduleListParams = params + + /** The response that this page was parsed from. */ + fun response(): FinancialAccountInterestTierScheduleListPageResponse = response + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [FinancialAccountInterestTierScheduleListPageAsync]. + * + * The following fields are required: + * ```java + * .service() + * .streamHandlerExecutor() + * .params() + * .response() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FinancialAccountInterestTierScheduleListPageAsync]. */ + class Builder internal constructor() { + + private var service: InterestTierScheduleServiceAsync? = null + private var streamHandlerExecutor: Executor? = null + private var params: FinancialAccountInterestTierScheduleListParams? = null + private var response: FinancialAccountInterestTierScheduleListPageResponse? = null + + @JvmSynthetic + internal fun from( + financialAccountInterestTierScheduleListPageAsync: + FinancialAccountInterestTierScheduleListPageAsync + ) = apply { + service = financialAccountInterestTierScheduleListPageAsync.service + streamHandlerExecutor = + financialAccountInterestTierScheduleListPageAsync.streamHandlerExecutor + params = financialAccountInterestTierScheduleListPageAsync.params + response = financialAccountInterestTierScheduleListPageAsync.response + } + + fun service(service: InterestTierScheduleServiceAsync) = apply { this.service = service } + + fun streamHandlerExecutor(streamHandlerExecutor: Executor) = apply { + this.streamHandlerExecutor = streamHandlerExecutor + } + + /** The parameters that were used to request this page. */ + fun params(params: FinancialAccountInterestTierScheduleListParams) = apply { + this.params = params + } + + /** The response that this page was parsed from. */ + fun response(response: FinancialAccountInterestTierScheduleListPageResponse) = apply { + this.response = response + } + + /** + * Returns an immutable instance of [FinancialAccountInterestTierScheduleListPageAsync]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .service() + * .streamHandlerExecutor() + * .params() + * .response() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): FinancialAccountInterestTierScheduleListPageAsync = + FinancialAccountInterestTierScheduleListPageAsync( + checkRequired("service", service), + checkRequired("streamHandlerExecutor", streamHandlerExecutor), + checkRequired("params", params), + checkRequired("response", response), + ) + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FinancialAccountInterestTierScheduleListPageAsync && + service == other.service && + streamHandlerExecutor == other.streamHandlerExecutor && + params == other.params && + response == other.response + } + + override fun hashCode(): Int = Objects.hash(service, streamHandlerExecutor, params, response) + + override fun toString() = + "FinancialAccountInterestTierScheduleListPageAsync{service=$service, streamHandlerExecutor=$streamHandlerExecutor, params=$params, response=$response}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListPageResponse.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListPageResponse.kt new file mode 100644 index 00000000..2a99c55f --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListPageResponse.kt @@ -0,0 +1,233 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.lithic.api.core.ExcludeMissing +import com.lithic.api.core.JsonField +import com.lithic.api.core.JsonMissing +import com.lithic.api.core.JsonValue +import com.lithic.api.core.checkKnown +import com.lithic.api.core.checkRequired +import com.lithic.api.core.toImmutable +import com.lithic.api.errors.LithicInvalidDataException +import java.util.Collections +import java.util.Objects +import kotlin.jvm.optionals.getOrNull + +/** Tier Schedule of the given account. Only applicable for credit products with v2 configuration */ +class FinancialAccountInterestTierScheduleListPageResponse +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val data: JsonField>, + private val hasMore: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("data") + @ExcludeMissing + data: JsonField> = JsonMissing.of(), + @JsonProperty("has_more") @ExcludeMissing hasMore: JsonField = JsonMissing.of(), + ) : this(data, hasMore, mutableMapOf()) + + /** + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun data(): List = data.getRequired("data") + + /** + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun hasMore(): Boolean = hasMore.getRequired("has_more") + + /** + * Returns the raw JSON value of [data]. + * + * Unlike [data], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("data") @ExcludeMissing fun _data(): JsonField> = data + + /** + * Returns the raw JSON value of [hasMore]. + * + * Unlike [hasMore], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("has_more") @ExcludeMissing fun _hasMore(): JsonField = hasMore + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [FinancialAccountInterestTierScheduleListPageResponse]. + * + * The following fields are required: + * ```java + * .data() + * .hasMore() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FinancialAccountInterestTierScheduleListPageResponse]. */ + class Builder internal constructor() { + + private var data: JsonField>? = null + private var hasMore: JsonField? = null + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from( + financialAccountInterestTierScheduleListPageResponse: + FinancialAccountInterestTierScheduleListPageResponse + ) = apply { + data = + financialAccountInterestTierScheduleListPageResponse.data.map { it.toMutableList() } + hasMore = financialAccountInterestTierScheduleListPageResponse.hasMore + additionalProperties = + financialAccountInterestTierScheduleListPageResponse.additionalProperties + .toMutableMap() + } + + fun data(data: List) = data(JsonField.of(data)) + + /** + * Sets [Builder.data] to an arbitrary JSON value. + * + * You should usually call [Builder.data] with a well-typed `List` + * value instead. This method is primarily for setting the field to an undocumented or not + * yet supported value. + */ + fun data(data: JsonField>) = apply { + this.data = data.map { it.toMutableList() } + } + + /** + * Adds a single [InterestTierSchedule] to [Builder.data]. + * + * @throws IllegalStateException if the field was previously set to a non-list. + */ + fun addData(data: InterestTierSchedule) = apply { + this.data = + (this.data ?: JsonField.of(mutableListOf())).also { + checkKnown("data", it).add(data) + } + } + + fun hasMore(hasMore: Boolean) = hasMore(JsonField.of(hasMore)) + + /** + * Sets [Builder.hasMore] to an arbitrary JSON value. + * + * You should usually call [Builder.hasMore] with a well-typed [Boolean] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun hasMore(hasMore: JsonField) = apply { this.hasMore = hasMore } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [FinancialAccountInterestTierScheduleListPageResponse]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .data() + * .hasMore() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): FinancialAccountInterestTierScheduleListPageResponse = + FinancialAccountInterestTierScheduleListPageResponse( + checkRequired("data", data).map { it.toImmutable() }, + checkRequired("hasMore", hasMore), + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): FinancialAccountInterestTierScheduleListPageResponse = apply { + if (validated) { + return@apply + } + + data().forEach { it.validate() } + hasMore() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (data.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0) + + (if (hasMore.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FinancialAccountInterestTierScheduleListPageResponse && + data == other.data && + hasMore == other.hasMore && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { Objects.hash(data, hasMore, additionalProperties) } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "FinancialAccountInterestTierScheduleListPageResponse{data=$data, hasMore=$hasMore, additionalProperties=$additionalProperties}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListParams.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListParams.kt new file mode 100644 index 00000000..66fb9e30 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListParams.kt @@ -0,0 +1,276 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.lithic.api.core.Params +import com.lithic.api.core.http.Headers +import com.lithic.api.core.http.QueryParams +import java.time.LocalDate +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** + * List interest tier schedules for a financial account with optional date filtering. + * + * If no date parameters are provided, returns all tier schedules. If date parameters are provided, + * uses filtering to return matching schedules (max 100). + * - for_date: Returns exact match (takes precedence over other dates) + * - before_date: Returns schedules with effective_date <= before_date + * - after_date: Returns schedules with effective_date >= after_date + * - Both before_date and after_date: Returns schedules in range + */ +class FinancialAccountInterestTierScheduleListParams +private constructor( + private val financialAccountToken: String?, + private val afterDate: LocalDate?, + private val beforeDate: LocalDate?, + private val forDate: LocalDate?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun financialAccountToken(): Optional = Optional.ofNullable(financialAccountToken) + + /** Return schedules with effective_date >= after_date (ISO format YYYY-MM-DD) */ + fun afterDate(): Optional = Optional.ofNullable(afterDate) + + /** Return schedules with effective_date <= before_date (ISO format YYYY-MM-DD) */ + fun beforeDate(): Optional = Optional.ofNullable(beforeDate) + + /** Return schedule with effective_date == for_date (ISO format YYYY-MM-DD) */ + fun forDate(): Optional = Optional.ofNullable(forDate) + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic fun none(): FinancialAccountInterestTierScheduleListParams = builder().build() + + /** + * Returns a mutable builder for constructing an instance of + * [FinancialAccountInterestTierScheduleListParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FinancialAccountInterestTierScheduleListParams]. */ + class Builder internal constructor() { + + private var financialAccountToken: String? = null + private var afterDate: LocalDate? = null + private var beforeDate: LocalDate? = null + private var forDate: LocalDate? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from( + financialAccountInterestTierScheduleListParams: + FinancialAccountInterestTierScheduleListParams + ) = apply { + financialAccountToken = + financialAccountInterestTierScheduleListParams.financialAccountToken + afterDate = financialAccountInterestTierScheduleListParams.afterDate + beforeDate = financialAccountInterestTierScheduleListParams.beforeDate + forDate = financialAccountInterestTierScheduleListParams.forDate + additionalHeaders = + financialAccountInterestTierScheduleListParams.additionalHeaders.toBuilder() + additionalQueryParams = + financialAccountInterestTierScheduleListParams.additionalQueryParams.toBuilder() + } + + fun financialAccountToken(financialAccountToken: String?) = apply { + this.financialAccountToken = financialAccountToken + } + + /** + * Alias for calling [Builder.financialAccountToken] with + * `financialAccountToken.orElse(null)`. + */ + fun financialAccountToken(financialAccountToken: Optional) = + financialAccountToken(financialAccountToken.getOrNull()) + + /** Return schedules with effective_date >= after_date (ISO format YYYY-MM-DD) */ + fun afterDate(afterDate: LocalDate?) = apply { this.afterDate = afterDate } + + /** Alias for calling [Builder.afterDate] with `afterDate.orElse(null)`. */ + fun afterDate(afterDate: Optional) = afterDate(afterDate.getOrNull()) + + /** Return schedules with effective_date <= before_date (ISO format YYYY-MM-DD) */ + fun beforeDate(beforeDate: LocalDate?) = apply { this.beforeDate = beforeDate } + + /** Alias for calling [Builder.beforeDate] with `beforeDate.orElse(null)`. */ + fun beforeDate(beforeDate: Optional) = beforeDate(beforeDate.getOrNull()) + + /** Return schedule with effective_date == for_date (ISO format YYYY-MM-DD) */ + fun forDate(forDate: LocalDate?) = apply { this.forDate = forDate } + + /** Alias for calling [Builder.forDate] with `forDate.orElse(null)`. */ + fun forDate(forDate: Optional) = forDate(forDate.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [FinancialAccountInterestTierScheduleListParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): FinancialAccountInterestTierScheduleListParams = + FinancialAccountInterestTierScheduleListParams( + financialAccountToken, + afterDate, + beforeDate, + forDate, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> financialAccountToken ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = + QueryParams.builder() + .apply { + afterDate?.let { put("after_date", it.toString()) } + beforeDate?.let { put("before_date", it.toString()) } + forDate?.let { put("for_date", it.toString()) } + putAll(additionalQueryParams) + } + .build() + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FinancialAccountInterestTierScheduleListParams && + financialAccountToken == other.financialAccountToken && + afterDate == other.afterDate && + beforeDate == other.beforeDate && + forDate == other.forDate && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash( + financialAccountToken, + afterDate, + beforeDate, + forDate, + additionalHeaders, + additionalQueryParams, + ) + + override fun toString() = + "FinancialAccountInterestTierScheduleListParams{financialAccountToken=$financialAccountToken, afterDate=$afterDate, beforeDate=$beforeDate, forDate=$forDate, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleRetrieveParams.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleRetrieveParams.kt new file mode 100644 index 00000000..f585386f --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleRetrieveParams.kt @@ -0,0 +1,228 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.lithic.api.core.Params +import com.lithic.api.core.checkRequired +import com.lithic.api.core.http.Headers +import com.lithic.api.core.http.QueryParams +import java.time.LocalDate +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Get a specific interest tier schedule by effective date */ +class FinancialAccountInterestTierScheduleRetrieveParams +private constructor( + private val financialAccountToken: String, + private val effectiveDate: LocalDate?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun financialAccountToken(): String = financialAccountToken + + fun effectiveDate(): Optional = Optional.ofNullable(effectiveDate) + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [FinancialAccountInterestTierScheduleRetrieveParams]. + * + * The following fields are required: + * ```java + * .financialAccountToken() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FinancialAccountInterestTierScheduleRetrieveParams]. */ + class Builder internal constructor() { + + private var financialAccountToken: String? = null + private var effectiveDate: LocalDate? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from( + financialAccountInterestTierScheduleRetrieveParams: + FinancialAccountInterestTierScheduleRetrieveParams + ) = apply { + financialAccountToken = + financialAccountInterestTierScheduleRetrieveParams.financialAccountToken + effectiveDate = financialAccountInterestTierScheduleRetrieveParams.effectiveDate + additionalHeaders = + financialAccountInterestTierScheduleRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = + financialAccountInterestTierScheduleRetrieveParams.additionalQueryParams.toBuilder() + } + + fun financialAccountToken(financialAccountToken: String) = apply { + this.financialAccountToken = financialAccountToken + } + + fun effectiveDate(effectiveDate: LocalDate?) = apply { this.effectiveDate = effectiveDate } + + /** Alias for calling [Builder.effectiveDate] with `effectiveDate.orElse(null)`. */ + fun effectiveDate(effectiveDate: Optional) = + effectiveDate(effectiveDate.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [FinancialAccountInterestTierScheduleRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .financialAccountToken() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): FinancialAccountInterestTierScheduleRetrieveParams = + FinancialAccountInterestTierScheduleRetrieveParams( + checkRequired("financialAccountToken", financialAccountToken), + effectiveDate, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> financialAccountToken + 1 -> effectiveDate?.toString() ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FinancialAccountInterestTierScheduleRetrieveParams && + financialAccountToken == other.financialAccountToken && + effectiveDate == other.effectiveDate && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(financialAccountToken, effectiveDate, additionalHeaders, additionalQueryParams) + + override fun toString() = + "FinancialAccountInterestTierScheduleRetrieveParams{financialAccountToken=$financialAccountToken, effectiveDate=$effectiveDate, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleUpdateParams.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleUpdateParams.kt new file mode 100644 index 00000000..e30bf88d --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleUpdateParams.kt @@ -0,0 +1,498 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.lithic.api.core.ExcludeMissing +import com.lithic.api.core.JsonField +import com.lithic.api.core.JsonMissing +import com.lithic.api.core.JsonValue +import com.lithic.api.core.Params +import com.lithic.api.core.checkRequired +import com.lithic.api.core.http.Headers +import com.lithic.api.core.http.QueryParams +import com.lithic.api.errors.LithicInvalidDataException +import java.time.LocalDate +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Update an existing interest tier schedule */ +class FinancialAccountInterestTierScheduleUpdateParams +private constructor( + private val financialAccountToken: String, + private val effectiveDate: LocalDate?, + private val body: UpdateTierScheduleEntryRequest, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + fun financialAccountToken(): String = financialAccountToken + + fun effectiveDate(): Optional = Optional.ofNullable(effectiveDate) + + /** + * Name of a tier contained in the credit product. Mutually exclusive with tier_rates + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tierName(): Optional = body.tierName() + + /** + * Custom rates per category. Mutually exclusive with tier_name + * + * This arbitrary value can be deserialized into a custom type using the `convert` method: + * ```java + * MyClass myObject = financialAccountInterestTierScheduleUpdateParams.tierRates().convert(MyClass.class); + * ``` + */ + fun _tierRates(): JsonValue = body._tierRates() + + /** + * Returns the raw JSON value of [tierName]. + * + * Unlike [tierName], this method doesn't throw if the JSON field has an unexpected type. + */ + fun _tierName(): JsonField = body._tierName() + + fun _additionalBodyProperties(): Map = body._additionalProperties() + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [FinancialAccountInterestTierScheduleUpdateParams]. + * + * The following fields are required: + * ```java + * .financialAccountToken() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FinancialAccountInterestTierScheduleUpdateParams]. */ + class Builder internal constructor() { + + private var financialAccountToken: String? = null + private var effectiveDate: LocalDate? = null + private var body: UpdateTierScheduleEntryRequest.Builder = + UpdateTierScheduleEntryRequest.builder() + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from( + financialAccountInterestTierScheduleUpdateParams: + FinancialAccountInterestTierScheduleUpdateParams + ) = apply { + financialAccountToken = + financialAccountInterestTierScheduleUpdateParams.financialAccountToken + effectiveDate = financialAccountInterestTierScheduleUpdateParams.effectiveDate + body = financialAccountInterestTierScheduleUpdateParams.body.toBuilder() + additionalHeaders = + financialAccountInterestTierScheduleUpdateParams.additionalHeaders.toBuilder() + additionalQueryParams = + financialAccountInterestTierScheduleUpdateParams.additionalQueryParams.toBuilder() + } + + fun financialAccountToken(financialAccountToken: String) = apply { + this.financialAccountToken = financialAccountToken + } + + fun effectiveDate(effectiveDate: LocalDate?) = apply { this.effectiveDate = effectiveDate } + + /** Alias for calling [Builder.effectiveDate] with `effectiveDate.orElse(null)`. */ + fun effectiveDate(effectiveDate: Optional) = + effectiveDate(effectiveDate.getOrNull()) + + /** + * Sets the entire request body. + * + * This is generally only useful if you are already constructing the body separately. + * Otherwise, it's more convenient to use the top-level setters instead: + * - [tierName] + * - [tierRates] + */ + fun body(body: UpdateTierScheduleEntryRequest) = apply { this.body = body.toBuilder() } + + /** Name of a tier contained in the credit product. Mutually exclusive with tier_rates */ + fun tierName(tierName: String) = apply { body.tierName(tierName) } + + /** + * Sets [Builder.tierName] to an arbitrary JSON value. + * + * You should usually call [Builder.tierName] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun tierName(tierName: JsonField) = apply { body.tierName(tierName) } + + /** Custom rates per category. Mutually exclusive with tier_name */ + fun tierRates(tierRates: JsonValue) = apply { body.tierRates(tierRates) } + + fun additionalBodyProperties(additionalBodyProperties: Map) = apply { + body.additionalProperties(additionalBodyProperties) + } + + fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply { + body.putAdditionalProperty(key, value) + } + + fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) = + apply { + body.putAllAdditionalProperties(additionalBodyProperties) + } + + fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) } + + fun removeAllAdditionalBodyProperties(keys: Set) = apply { + body.removeAllAdditionalProperties(keys) + } + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [FinancialAccountInterestTierScheduleUpdateParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .financialAccountToken() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): FinancialAccountInterestTierScheduleUpdateParams = + FinancialAccountInterestTierScheduleUpdateParams( + checkRequired("financialAccountToken", financialAccountToken), + effectiveDate, + body.build(), + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _body(): UpdateTierScheduleEntryRequest = body + + fun _pathParam(index: Int): String = + when (index) { + 0 -> financialAccountToken + 1 -> effectiveDate?.toString() ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + /** Entry in the Tier Schedule of an account */ + class UpdateTierScheduleEntryRequest + @JsonCreator(mode = JsonCreator.Mode.DISABLED) + private constructor( + private val tierName: JsonField, + private val tierRates: JsonValue, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("tier_name") + @ExcludeMissing + tierName: JsonField = JsonMissing.of(), + @JsonProperty("tier_rates") @ExcludeMissing tierRates: JsonValue = JsonMissing.of(), + ) : this(tierName, tierRates, mutableMapOf()) + + /** + * Name of a tier contained in the credit product. Mutually exclusive with tier_rates + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tierName(): Optional = tierName.getOptional("tier_name") + + /** + * Custom rates per category. Mutually exclusive with tier_name + * + * This arbitrary value can be deserialized into a custom type using the `convert` method: + * ```java + * MyClass myObject = updateTierScheduleEntryRequest.tierRates().convert(MyClass.class); + * ``` + */ + @JsonProperty("tier_rates") @ExcludeMissing fun _tierRates(): JsonValue = tierRates + + /** + * Returns the raw JSON value of [tierName]. + * + * Unlike [tierName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("tier_name") @ExcludeMissing fun _tierName(): JsonField = tierName + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of + * [UpdateTierScheduleEntryRequest]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [UpdateTierScheduleEntryRequest]. */ + class Builder internal constructor() { + + private var tierName: JsonField = JsonMissing.of() + private var tierRates: JsonValue = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(updateTierScheduleEntryRequest: UpdateTierScheduleEntryRequest) = + apply { + tierName = updateTierScheduleEntryRequest.tierName + tierRates = updateTierScheduleEntryRequest.tierRates + additionalProperties = + updateTierScheduleEntryRequest.additionalProperties.toMutableMap() + } + + /** + * Name of a tier contained in the credit product. Mutually exclusive with tier_rates + */ + fun tierName(tierName: String) = tierName(JsonField.of(tierName)) + + /** + * Sets [Builder.tierName] to an arbitrary JSON value. + * + * You should usually call [Builder.tierName] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun tierName(tierName: JsonField) = apply { this.tierName = tierName } + + /** Custom rates per category. Mutually exclusive with tier_name */ + fun tierRates(tierRates: JsonValue) = apply { this.tierRates = tierRates } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [UpdateTierScheduleEntryRequest]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): UpdateTierScheduleEntryRequest = + UpdateTierScheduleEntryRequest( + tierName, + tierRates, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): UpdateTierScheduleEntryRequest = apply { + if (validated) { + return@apply + } + + tierName() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object + * recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic internal fun validity(): Int = (if (tierName.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is UpdateTierScheduleEntryRequest && + tierName == other.tierName && + tierRates == other.tierRates && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(tierName, tierRates, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "UpdateTierScheduleEntryRequest{tierName=$tierName, tierRates=$tierRates, additionalProperties=$additionalProperties}" + } + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FinancialAccountInterestTierScheduleUpdateParams && + financialAccountToken == other.financialAccountToken && + effectiveDate == other.effectiveDate && + body == other.body && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash( + financialAccountToken, + effectiveDate, + body, + additionalHeaders, + additionalQueryParams, + ) + + override fun toString() = + "FinancialAccountInterestTierScheduleUpdateParams{financialAccountToken=$financialAccountToken, effectiveDate=$effectiveDate, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountLoanTapeConfigurationRetrieveParams.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountLoanTapeConfigurationRetrieveParams.kt new file mode 100644 index 00000000..d1649e59 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountLoanTapeConfigurationRetrieveParams.kt @@ -0,0 +1,213 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.lithic.api.core.Params +import com.lithic.api.core.http.Headers +import com.lithic.api.core.http.QueryParams +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Get the loan tape configuration for a given financial account. */ +class FinancialAccountLoanTapeConfigurationRetrieveParams +private constructor( + private val financialAccountToken: String?, + private val additionalHeaders: Headers, + private val additionalQueryParams: QueryParams, +) : Params { + + /** Globally unique identifier for financial account. */ + fun financialAccountToken(): Optional = Optional.ofNullable(financialAccountToken) + + /** Additional headers to send with the request. */ + fun _additionalHeaders(): Headers = additionalHeaders + + /** Additional query param to send with the request. */ + fun _additionalQueryParams(): QueryParams = additionalQueryParams + + fun toBuilder() = Builder().from(this) + + companion object { + + @JvmStatic + fun none(): FinancialAccountLoanTapeConfigurationRetrieveParams = builder().build() + + /** + * Returns a mutable builder for constructing an instance of + * [FinancialAccountLoanTapeConfigurationRetrieveParams]. + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [FinancialAccountLoanTapeConfigurationRetrieveParams]. */ + class Builder internal constructor() { + + private var financialAccountToken: String? = null + private var additionalHeaders: Headers.Builder = Headers.builder() + private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() + + @JvmSynthetic + internal fun from( + financialAccountLoanTapeConfigurationRetrieveParams: + FinancialAccountLoanTapeConfigurationRetrieveParams + ) = apply { + financialAccountToken = + financialAccountLoanTapeConfigurationRetrieveParams.financialAccountToken + additionalHeaders = + financialAccountLoanTapeConfigurationRetrieveParams.additionalHeaders.toBuilder() + additionalQueryParams = + financialAccountLoanTapeConfigurationRetrieveParams.additionalQueryParams + .toBuilder() + } + + /** Globally unique identifier for financial account. */ + fun financialAccountToken(financialAccountToken: String?) = apply { + this.financialAccountToken = financialAccountToken + } + + /** + * Alias for calling [Builder.financialAccountToken] with + * `financialAccountToken.orElse(null)`. + */ + fun financialAccountToken(financialAccountToken: Optional) = + financialAccountToken(financialAccountToken.getOrNull()) + + fun additionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun additionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.clear() + putAllAdditionalHeaders(additionalHeaders) + } + + fun putAdditionalHeader(name: String, value: String) = apply { + additionalHeaders.put(name, value) + } + + fun putAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.put(name, values) + } + + fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.putAll(additionalHeaders) + } + + fun replaceAdditionalHeaders(name: String, value: String) = apply { + additionalHeaders.replace(name, value) + } + + fun replaceAdditionalHeaders(name: String, values: Iterable) = apply { + additionalHeaders.replace(name, values) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply { + this.additionalHeaders.replaceAll(additionalHeaders) + } + + fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) } + + fun removeAllAdditionalHeaders(names: Set) = apply { + additionalHeaders.removeAll(names) + } + + fun additionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun additionalQueryParams(additionalQueryParams: Map>) = apply { + this.additionalQueryParams.clear() + putAllAdditionalQueryParams(additionalQueryParams) + } + + fun putAdditionalQueryParam(key: String, value: String) = apply { + additionalQueryParams.put(key, value) + } + + fun putAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.put(key, values) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun putAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.putAll(additionalQueryParams) + } + + fun replaceAdditionalQueryParams(key: String, value: String) = apply { + additionalQueryParams.replace(key, value) + } + + fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply { + additionalQueryParams.replace(key, values) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) = + apply { + this.additionalQueryParams.replaceAll(additionalQueryParams) + } + + fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) } + + fun removeAllAdditionalQueryParams(keys: Set) = apply { + additionalQueryParams.removeAll(keys) + } + + /** + * Returns an immutable instance of [FinancialAccountLoanTapeConfigurationRetrieveParams]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): FinancialAccountLoanTapeConfigurationRetrieveParams = + FinancialAccountLoanTapeConfigurationRetrieveParams( + financialAccountToken, + additionalHeaders.build(), + additionalQueryParams.build(), + ) + } + + fun _pathParam(index: Int): String = + when (index) { + 0 -> financialAccountToken ?: "" + else -> "" + } + + override fun _headers(): Headers = additionalHeaders + + override fun _queryParams(): QueryParams = additionalQueryParams + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is FinancialAccountLoanTapeConfigurationRetrieveParams && + financialAccountToken == other.financialAccountToken && + additionalHeaders == other.additionalHeaders && + additionalQueryParams == other.additionalQueryParams + } + + override fun hashCode(): Int = + Objects.hash(financialAccountToken, additionalHeaders, additionalQueryParams) + + override fun toString() = + "FinancialAccountLoanTapeConfigurationRetrieveParams{financialAccountToken=$financialAccountToken, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountUpdateStatusParams.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountUpdateStatusParams.kt index e51d0e37..73595a71 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountUpdateStatusParams.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/FinancialAccountUpdateStatusParams.kt @@ -777,6 +777,8 @@ private constructor( @JvmField val CHARGED_OFF_DELINQUENT = of("CHARGED_OFF_DELINQUENT") + @JvmField val INTEREST_AND_FEES_PAUSED = of("INTEREST_AND_FEES_PAUSED") + @JvmStatic fun of(value: String) = UpdateFinancialAccountSubstatus(JsonField.of(value)) } @@ -786,6 +788,7 @@ private constructor( END_USER_REQUEST, BANK_REQUEST, CHARGED_OFF_DELINQUENT, + INTEREST_AND_FEES_PAUSED, } /** @@ -804,6 +807,7 @@ private constructor( END_USER_REQUEST, BANK_REQUEST, CHARGED_OFF_DELINQUENT, + INTEREST_AND_FEES_PAUSED, /** * An enum member indicating that [UpdateFinancialAccountSubstatus] was instantiated * with an unknown value. @@ -824,6 +828,7 @@ private constructor( END_USER_REQUEST -> Value.END_USER_REQUEST BANK_REQUEST -> Value.BANK_REQUEST CHARGED_OFF_DELINQUENT -> Value.CHARGED_OFF_DELINQUENT + INTEREST_AND_FEES_PAUSED -> Value.INTEREST_AND_FEES_PAUSED else -> Value._UNKNOWN } @@ -842,6 +847,7 @@ private constructor( END_USER_REQUEST -> Known.END_USER_REQUEST BANK_REQUEST -> Known.BANK_REQUEST CHARGED_OFF_DELINQUENT -> Known.CHARGED_OFF_DELINQUENT + INTEREST_AND_FEES_PAUSED -> Known.INTEREST_AND_FEES_PAUSED else -> throw LithicInvalidDataException( "Unknown UpdateFinancialAccountSubstatus: $value" diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/InterestTierSchedule.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/InterestTierSchedule.kt new file mode 100644 index 00000000..b5f3e267 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/InterestTierSchedule.kt @@ -0,0 +1,285 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.lithic.api.core.ExcludeMissing +import com.lithic.api.core.JsonField +import com.lithic.api.core.JsonMissing +import com.lithic.api.core.JsonValue +import com.lithic.api.core.checkRequired +import com.lithic.api.errors.LithicInvalidDataException +import java.time.LocalDate +import java.util.Collections +import java.util.Objects +import java.util.Optional + +/** Entry in the Tier Schedule of an account */ +class InterestTierSchedule +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val creditProductToken: JsonField, + private val effectiveDate: JsonField, + private val tierName: JsonField, + private val tierRates: JsonValue, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("credit_product_token") + @ExcludeMissing + creditProductToken: JsonField = JsonMissing.of(), + @JsonProperty("effective_date") + @ExcludeMissing + effectiveDate: JsonField = JsonMissing.of(), + @JsonProperty("tier_name") @ExcludeMissing tierName: JsonField = JsonMissing.of(), + @JsonProperty("tier_rates") @ExcludeMissing tierRates: JsonValue = JsonMissing.of(), + ) : this(creditProductToken, effectiveDate, tierName, tierRates, mutableMapOf()) + + /** + * Globally unique identifier for a credit product + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun creditProductToken(): String = creditProductToken.getRequired("credit_product_token") + + /** + * Date the tier should be effective in YYYY-MM-DD format + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun effectiveDate(): LocalDate = effectiveDate.getRequired("effective_date") + + /** + * Name of a tier contained in the credit product. Mutually exclusive with tier_rates + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tierName(): Optional = tierName.getOptional("tier_name") + + /** + * Custom rates per category. Mutually exclusive with tier_name + * + * This arbitrary value can be deserialized into a custom type using the `convert` method: + * ```java + * MyClass myObject = interestTierSchedule.tierRates().convert(MyClass.class); + * ``` + */ + @JsonProperty("tier_rates") @ExcludeMissing fun _tierRates(): JsonValue = tierRates + + /** + * Returns the raw JSON value of [creditProductToken]. + * + * Unlike [creditProductToken], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("credit_product_token") + @ExcludeMissing + fun _creditProductToken(): JsonField = creditProductToken + + /** + * Returns the raw JSON value of [effectiveDate]. + * + * Unlike [effectiveDate], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("effective_date") + @ExcludeMissing + fun _effectiveDate(): JsonField = effectiveDate + + /** + * Returns the raw JSON value of [tierName]. + * + * Unlike [tierName], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("tier_name") @ExcludeMissing fun _tierName(): JsonField = tierName + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [InterestTierSchedule]. + * + * The following fields are required: + * ```java + * .creditProductToken() + * .effectiveDate() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [InterestTierSchedule]. */ + class Builder internal constructor() { + + private var creditProductToken: JsonField? = null + private var effectiveDate: JsonField? = null + private var tierName: JsonField = JsonMissing.of() + private var tierRates: JsonValue = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(interestTierSchedule: InterestTierSchedule) = apply { + creditProductToken = interestTierSchedule.creditProductToken + effectiveDate = interestTierSchedule.effectiveDate + tierName = interestTierSchedule.tierName + tierRates = interestTierSchedule.tierRates + additionalProperties = interestTierSchedule.additionalProperties.toMutableMap() + } + + /** Globally unique identifier for a credit product */ + fun creditProductToken(creditProductToken: String) = + creditProductToken(JsonField.of(creditProductToken)) + + /** + * Sets [Builder.creditProductToken] to an arbitrary JSON value. + * + * You should usually call [Builder.creditProductToken] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun creditProductToken(creditProductToken: JsonField) = apply { + this.creditProductToken = creditProductToken + } + + /** Date the tier should be effective in YYYY-MM-DD format */ + fun effectiveDate(effectiveDate: LocalDate) = effectiveDate(JsonField.of(effectiveDate)) + + /** + * Sets [Builder.effectiveDate] to an arbitrary JSON value. + * + * You should usually call [Builder.effectiveDate] with a well-typed [LocalDate] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun effectiveDate(effectiveDate: JsonField) = apply { + this.effectiveDate = effectiveDate + } + + /** Name of a tier contained in the credit product. Mutually exclusive with tier_rates */ + fun tierName(tierName: String) = tierName(JsonField.of(tierName)) + + /** + * Sets [Builder.tierName] to an arbitrary JSON value. + * + * You should usually call [Builder.tierName] with a well-typed [String] value instead. This + * method is primarily for setting the field to an undocumented or not yet supported value. + */ + fun tierName(tierName: JsonField) = apply { this.tierName = tierName } + + /** Custom rates per category. Mutually exclusive with tier_name */ + fun tierRates(tierRates: JsonValue) = apply { this.tierRates = tierRates } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [InterestTierSchedule]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .creditProductToken() + * .effectiveDate() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): InterestTierSchedule = + InterestTierSchedule( + checkRequired("creditProductToken", creditProductToken), + checkRequired("effectiveDate", effectiveDate), + tierName, + tierRates, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): InterestTierSchedule = apply { + if (validated) { + return@apply + } + + creditProductToken() + effectiveDate() + tierName() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (creditProductToken.asKnown().isPresent) 1 else 0) + + (if (effectiveDate.asKnown().isPresent) 1 else 0) + + (if (tierName.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is InterestTierSchedule && + creditProductToken == other.creditProductToken && + effectiveDate == other.effectiveDate && + tierName == other.tierName && + tierRates == other.tierRates && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(creditProductToken, effectiveDate, tierName, tierRates, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "InterestTierSchedule{creditProductToken=$creditProductToken, effectiveDate=$effectiveDate, tierName=$tierName, tierRates=$tierRates, additionalProperties=$additionalProperties}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/LoanTape.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/LoanTape.kt index 274e35e3..de8899a7 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/LoanTape.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/LoanTape.kt @@ -1869,6 +1869,8 @@ private constructor( @JvmField val DELINQUENT = of("DELINQUENT") + @JvmField val INTEREST_AND_FEES_PAUSED = of("INTEREST_AND_FEES_PAUSED") + @JvmStatic fun of(value: String) = FinancialAccountSubstatus(JsonField.of(value)) } @@ -1880,6 +1882,7 @@ private constructor( END_USER_REQUEST, BANK_REQUEST, DELINQUENT, + INTEREST_AND_FEES_PAUSED, } /** @@ -1899,6 +1902,7 @@ private constructor( END_USER_REQUEST, BANK_REQUEST, DELINQUENT, + INTEREST_AND_FEES_PAUSED, /** * An enum member indicating that [FinancialAccountSubstatus] was instantiated * with an unknown value. @@ -1920,6 +1924,7 @@ private constructor( END_USER_REQUEST -> Value.END_USER_REQUEST BANK_REQUEST -> Value.BANK_REQUEST DELINQUENT -> Value.DELINQUENT + INTEREST_AND_FEES_PAUSED -> Value.INTEREST_AND_FEES_PAUSED else -> Value._UNKNOWN } @@ -1939,6 +1944,7 @@ private constructor( END_USER_REQUEST -> Known.END_USER_REQUEST BANK_REQUEST -> Known.BANK_REQUEST DELINQUENT -> Known.DELINQUENT + INTEREST_AND_FEES_PAUSED -> Known.INTEREST_AND_FEES_PAUSED else -> throw LithicInvalidDataException( "Unknown FinancialAccountSubstatus: $value" diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/LoanTapeConfiguration.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/LoanTapeConfiguration.kt new file mode 100644 index 00000000..e7fdc727 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/LoanTapeConfiguration.kt @@ -0,0 +1,451 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.lithic.api.core.ExcludeMissing +import com.lithic.api.core.JsonField +import com.lithic.api.core.JsonMissing +import com.lithic.api.core.JsonValue +import com.lithic.api.core.checkRequired +import com.lithic.api.errors.LithicInvalidDataException +import java.time.OffsetDateTime +import java.util.Collections +import java.util.Objects +import java.util.Optional +import kotlin.jvm.optionals.getOrNull + +/** Configuration for loan tapes */ +class LoanTapeConfiguration +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val createdAt: JsonField, + private val financialAccountToken: JsonField, + private val instanceToken: JsonField, + private val updatedAt: JsonField, + private val creditProductToken: JsonField, + private val loanTapeRebuildConfiguration: JsonField, + private val tierScheduleChangedAt: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("created_at") + @ExcludeMissing + createdAt: JsonField = JsonMissing.of(), + @JsonProperty("financial_account_token") + @ExcludeMissing + financialAccountToken: JsonField = JsonMissing.of(), + @JsonProperty("instance_token") + @ExcludeMissing + instanceToken: JsonField = JsonMissing.of(), + @JsonProperty("updated_at") + @ExcludeMissing + updatedAt: JsonField = JsonMissing.of(), + @JsonProperty("credit_product_token") + @ExcludeMissing + creditProductToken: JsonField = JsonMissing.of(), + @JsonProperty("loan_tape_rebuild_configuration") + @ExcludeMissing + loanTapeRebuildConfiguration: JsonField = JsonMissing.of(), + @JsonProperty("tier_schedule_changed_at") + @ExcludeMissing + tierScheduleChangedAt: JsonField = JsonMissing.of(), + ) : this( + createdAt, + financialAccountToken, + instanceToken, + updatedAt, + creditProductToken, + loanTapeRebuildConfiguration, + tierScheduleChangedAt, + mutableMapOf(), + ) + + /** + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun createdAt(): OffsetDateTime = createdAt.getRequired("created_at") + + /** + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun financialAccountToken(): String = + financialAccountToken.getRequired("financial_account_token") + + /** + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun instanceToken(): String = instanceToken.getRequired("instance_token") + + /** + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun updatedAt(): OffsetDateTime = updatedAt.getRequired("updated_at") + + /** + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun creditProductToken(): Optional = + creditProductToken.getOptional("credit_product_token") + + /** + * Configuration for building loan tapes + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun loanTapeRebuildConfiguration(): Optional = + loanTapeRebuildConfiguration.getOptional("loan_tape_rebuild_configuration") + + /** + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun tierScheduleChangedAt(): Optional = + tierScheduleChangedAt.getOptional("tier_schedule_changed_at") + + /** + * Returns the raw JSON value of [createdAt]. + * + * Unlike [createdAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("created_at") + @ExcludeMissing + fun _createdAt(): JsonField = createdAt + + /** + * Returns the raw JSON value of [financialAccountToken]. + * + * Unlike [financialAccountToken], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("financial_account_token") + @ExcludeMissing + fun _financialAccountToken(): JsonField = financialAccountToken + + /** + * Returns the raw JSON value of [instanceToken]. + * + * Unlike [instanceToken], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("instance_token") + @ExcludeMissing + fun _instanceToken(): JsonField = instanceToken + + /** + * Returns the raw JSON value of [updatedAt]. + * + * Unlike [updatedAt], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("updated_at") + @ExcludeMissing + fun _updatedAt(): JsonField = updatedAt + + /** + * Returns the raw JSON value of [creditProductToken]. + * + * Unlike [creditProductToken], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("credit_product_token") + @ExcludeMissing + fun _creditProductToken(): JsonField = creditProductToken + + /** + * Returns the raw JSON value of [loanTapeRebuildConfiguration]. + * + * Unlike [loanTapeRebuildConfiguration], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("loan_tape_rebuild_configuration") + @ExcludeMissing + fun _loanTapeRebuildConfiguration(): JsonField = + loanTapeRebuildConfiguration + + /** + * Returns the raw JSON value of [tierScheduleChangedAt]. + * + * Unlike [tierScheduleChangedAt], this method doesn't throw if the JSON field has an unexpected + * type. + */ + @JsonProperty("tier_schedule_changed_at") + @ExcludeMissing + fun _tierScheduleChangedAt(): JsonField = tierScheduleChangedAt + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [LoanTapeConfiguration]. + * + * The following fields are required: + * ```java + * .createdAt() + * .financialAccountToken() + * .instanceToken() + * .updatedAt() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LoanTapeConfiguration]. */ + class Builder internal constructor() { + + private var createdAt: JsonField? = null + private var financialAccountToken: JsonField? = null + private var instanceToken: JsonField? = null + private var updatedAt: JsonField? = null + private var creditProductToken: JsonField = JsonMissing.of() + private var loanTapeRebuildConfiguration: JsonField = + JsonMissing.of() + private var tierScheduleChangedAt: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(loanTapeConfiguration: LoanTapeConfiguration) = apply { + createdAt = loanTapeConfiguration.createdAt + financialAccountToken = loanTapeConfiguration.financialAccountToken + instanceToken = loanTapeConfiguration.instanceToken + updatedAt = loanTapeConfiguration.updatedAt + creditProductToken = loanTapeConfiguration.creditProductToken + loanTapeRebuildConfiguration = loanTapeConfiguration.loanTapeRebuildConfiguration + tierScheduleChangedAt = loanTapeConfiguration.tierScheduleChangedAt + additionalProperties = loanTapeConfiguration.additionalProperties.toMutableMap() + } + + fun createdAt(createdAt: OffsetDateTime) = createdAt(JsonField.of(createdAt)) + + /** + * Sets [Builder.createdAt] to an arbitrary JSON value. + * + * You should usually call [Builder.createdAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun createdAt(createdAt: JsonField) = apply { this.createdAt = createdAt } + + fun financialAccountToken(financialAccountToken: String) = + financialAccountToken(JsonField.of(financialAccountToken)) + + /** + * Sets [Builder.financialAccountToken] to an arbitrary JSON value. + * + * You should usually call [Builder.financialAccountToken] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun financialAccountToken(financialAccountToken: JsonField) = apply { + this.financialAccountToken = financialAccountToken + } + + fun instanceToken(instanceToken: String) = instanceToken(JsonField.of(instanceToken)) + + /** + * Sets [Builder.instanceToken] to an arbitrary JSON value. + * + * You should usually call [Builder.instanceToken] with a well-typed [String] value instead. + * This method is primarily for setting the field to an undocumented or not yet supported + * value. + */ + fun instanceToken(instanceToken: JsonField) = apply { + this.instanceToken = instanceToken + } + + fun updatedAt(updatedAt: OffsetDateTime) = updatedAt(JsonField.of(updatedAt)) + + /** + * Sets [Builder.updatedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.updatedAt] with a well-typed [OffsetDateTime] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun updatedAt(updatedAt: JsonField) = apply { this.updatedAt = updatedAt } + + fun creditProductToken(creditProductToken: String) = + creditProductToken(JsonField.of(creditProductToken)) + + /** + * Sets [Builder.creditProductToken] to an arbitrary JSON value. + * + * You should usually call [Builder.creditProductToken] with a well-typed [String] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun creditProductToken(creditProductToken: JsonField) = apply { + this.creditProductToken = creditProductToken + } + + /** Configuration for building loan tapes */ + fun loanTapeRebuildConfiguration( + loanTapeRebuildConfiguration: LoanTapeRebuildConfiguration + ) = loanTapeRebuildConfiguration(JsonField.of(loanTapeRebuildConfiguration)) + + /** + * Sets [Builder.loanTapeRebuildConfiguration] to an arbitrary JSON value. + * + * You should usually call [Builder.loanTapeRebuildConfiguration] with a well-typed + * [LoanTapeRebuildConfiguration] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun loanTapeRebuildConfiguration( + loanTapeRebuildConfiguration: JsonField + ) = apply { this.loanTapeRebuildConfiguration = loanTapeRebuildConfiguration } + + fun tierScheduleChangedAt(tierScheduleChangedAt: OffsetDateTime) = + tierScheduleChangedAt(JsonField.of(tierScheduleChangedAt)) + + /** + * Sets [Builder.tierScheduleChangedAt] to an arbitrary JSON value. + * + * You should usually call [Builder.tierScheduleChangedAt] with a well-typed + * [OffsetDateTime] value instead. This method is primarily for setting the field to an + * undocumented or not yet supported value. + */ + fun tierScheduleChangedAt(tierScheduleChangedAt: JsonField) = apply { + this.tierScheduleChangedAt = tierScheduleChangedAt + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [LoanTapeConfiguration]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .createdAt() + * .financialAccountToken() + * .instanceToken() + * .updatedAt() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): LoanTapeConfiguration = + LoanTapeConfiguration( + checkRequired("createdAt", createdAt), + checkRequired("financialAccountToken", financialAccountToken), + checkRequired("instanceToken", instanceToken), + checkRequired("updatedAt", updatedAt), + creditProductToken, + loanTapeRebuildConfiguration, + tierScheduleChangedAt, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): LoanTapeConfiguration = apply { + if (validated) { + return@apply + } + + createdAt() + financialAccountToken() + instanceToken() + updatedAt() + creditProductToken() + loanTapeRebuildConfiguration().ifPresent { it.validate() } + tierScheduleChangedAt() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (createdAt.asKnown().isPresent) 1 else 0) + + (if (financialAccountToken.asKnown().isPresent) 1 else 0) + + (if (instanceToken.asKnown().isPresent) 1 else 0) + + (if (updatedAt.asKnown().isPresent) 1 else 0) + + (if (creditProductToken.asKnown().isPresent) 1 else 0) + + (loanTapeRebuildConfiguration.asKnown().getOrNull()?.validity() ?: 0) + + (if (tierScheduleChangedAt.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LoanTapeConfiguration && + createdAt == other.createdAt && + financialAccountToken == other.financialAccountToken && + instanceToken == other.instanceToken && + updatedAt == other.updatedAt && + creditProductToken == other.creditProductToken && + loanTapeRebuildConfiguration == other.loanTapeRebuildConfiguration && + tierScheduleChangedAt == other.tierScheduleChangedAt && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash( + createdAt, + financialAccountToken, + instanceToken, + updatedAt, + creditProductToken, + loanTapeRebuildConfiguration, + tierScheduleChangedAt, + additionalProperties, + ) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "LoanTapeConfiguration{createdAt=$createdAt, financialAccountToken=$financialAccountToken, instanceToken=$instanceToken, updatedAt=$updatedAt, creditProductToken=$creditProductToken, loanTapeRebuildConfiguration=$loanTapeRebuildConfiguration, tierScheduleChangedAt=$tierScheduleChangedAt, additionalProperties=$additionalProperties}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/LoanTapeRebuildConfiguration.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/LoanTapeRebuildConfiguration.kt new file mode 100644 index 00000000..fe327d24 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/LoanTapeRebuildConfiguration.kt @@ -0,0 +1,269 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.fasterxml.jackson.annotation.JsonAnyGetter +import com.fasterxml.jackson.annotation.JsonAnySetter +import com.fasterxml.jackson.annotation.JsonCreator +import com.fasterxml.jackson.annotation.JsonProperty +import com.lithic.api.core.ExcludeMissing +import com.lithic.api.core.JsonField +import com.lithic.api.core.JsonMissing +import com.lithic.api.core.JsonValue +import com.lithic.api.core.checkRequired +import com.lithic.api.errors.LithicInvalidDataException +import java.time.LocalDate +import java.util.Collections +import java.util.Objects +import java.util.Optional + +/** Configuration for building loan tapes */ +class LoanTapeRebuildConfiguration +@JsonCreator(mode = JsonCreator.Mode.DISABLED) +private constructor( + private val rebuildNeeded: JsonField, + private val lastRebuild: JsonField, + private val rebuildFrom: JsonField, + private val additionalProperties: MutableMap, +) { + + @JsonCreator + private constructor( + @JsonProperty("rebuild_needed") + @ExcludeMissing + rebuildNeeded: JsonField = JsonMissing.of(), + @JsonProperty("last_rebuild") + @ExcludeMissing + lastRebuild: JsonField = JsonMissing.of(), + @JsonProperty("rebuild_from") + @ExcludeMissing + rebuildFrom: JsonField = JsonMissing.of(), + ) : this(rebuildNeeded, lastRebuild, rebuildFrom, mutableMapOf()) + + /** + * Whether the account's loan tapes need to be rebuilt or not + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type or is + * unexpectedly missing or null (e.g. if the server responded with an unexpected value). + */ + fun rebuildNeeded(): Boolean = rebuildNeeded.getRequired("rebuild_needed") + + /** + * The date for which the account's loan tapes were last rebuilt + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun lastRebuild(): Optional = lastRebuild.getOptional("last_rebuild") + + /** + * Date from which to start rebuilding from if the account requires a rebuild + * + * @throws LithicInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun rebuildFrom(): Optional = rebuildFrom.getOptional("rebuild_from") + + /** + * Returns the raw JSON value of [rebuildNeeded]. + * + * Unlike [rebuildNeeded], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("rebuild_needed") + @ExcludeMissing + fun _rebuildNeeded(): JsonField = rebuildNeeded + + /** + * Returns the raw JSON value of [lastRebuild]. + * + * Unlike [lastRebuild], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("last_rebuild") + @ExcludeMissing + fun _lastRebuild(): JsonField = lastRebuild + + /** + * Returns the raw JSON value of [rebuildFrom]. + * + * Unlike [rebuildFrom], this method doesn't throw if the JSON field has an unexpected type. + */ + @JsonProperty("rebuild_from") + @ExcludeMissing + fun _rebuildFrom(): JsonField = rebuildFrom + + @JsonAnySetter + private fun putAdditionalProperty(key: String, value: JsonValue) { + additionalProperties.put(key, value) + } + + @JsonAnyGetter + @ExcludeMissing + fun _additionalProperties(): Map = + Collections.unmodifiableMap(additionalProperties) + + fun toBuilder() = Builder().from(this) + + companion object { + + /** + * Returns a mutable builder for constructing an instance of [LoanTapeRebuildConfiguration]. + * + * The following fields are required: + * ```java + * .rebuildNeeded() + * ``` + */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [LoanTapeRebuildConfiguration]. */ + class Builder internal constructor() { + + private var rebuildNeeded: JsonField? = null + private var lastRebuild: JsonField = JsonMissing.of() + private var rebuildFrom: JsonField = JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(loanTapeRebuildConfiguration: LoanTapeRebuildConfiguration) = apply { + rebuildNeeded = loanTapeRebuildConfiguration.rebuildNeeded + lastRebuild = loanTapeRebuildConfiguration.lastRebuild + rebuildFrom = loanTapeRebuildConfiguration.rebuildFrom + additionalProperties = loanTapeRebuildConfiguration.additionalProperties.toMutableMap() + } + + /** Whether the account's loan tapes need to be rebuilt or not */ + fun rebuildNeeded(rebuildNeeded: Boolean) = rebuildNeeded(JsonField.of(rebuildNeeded)) + + /** + * Sets [Builder.rebuildNeeded] to an arbitrary JSON value. + * + * You should usually call [Builder.rebuildNeeded] with a well-typed [Boolean] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun rebuildNeeded(rebuildNeeded: JsonField) = apply { + this.rebuildNeeded = rebuildNeeded + } + + /** The date for which the account's loan tapes were last rebuilt */ + fun lastRebuild(lastRebuild: LocalDate) = lastRebuild(JsonField.of(lastRebuild)) + + /** + * Sets [Builder.lastRebuild] to an arbitrary JSON value. + * + * You should usually call [Builder.lastRebuild] with a well-typed [LocalDate] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun lastRebuild(lastRebuild: JsonField) = apply { + this.lastRebuild = lastRebuild + } + + /** Date from which to start rebuilding from if the account requires a rebuild */ + fun rebuildFrom(rebuildFrom: LocalDate) = rebuildFrom(JsonField.of(rebuildFrom)) + + /** + * Sets [Builder.rebuildFrom] to an arbitrary JSON value. + * + * You should usually call [Builder.rebuildFrom] with a well-typed [LocalDate] value + * instead. This method is primarily for setting the field to an undocumented or not yet + * supported value. + */ + fun rebuildFrom(rebuildFrom: JsonField) = apply { + this.rebuildFrom = rebuildFrom + } + + fun additionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.clear() + putAllAdditionalProperties(additionalProperties) + } + + fun putAdditionalProperty(key: String, value: JsonValue) = apply { + additionalProperties.put(key, value) + } + + fun putAllAdditionalProperties(additionalProperties: Map) = apply { + this.additionalProperties.putAll(additionalProperties) + } + + fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) } + + fun removeAllAdditionalProperties(keys: Set) = apply { + keys.forEach(::removeAdditionalProperty) + } + + /** + * Returns an immutable instance of [LoanTapeRebuildConfiguration]. + * + * Further updates to this [Builder] will not mutate the returned instance. + * + * The following fields are required: + * ```java + * .rebuildNeeded() + * ``` + * + * @throws IllegalStateException if any required field is unset. + */ + fun build(): LoanTapeRebuildConfiguration = + LoanTapeRebuildConfiguration( + checkRequired("rebuildNeeded", rebuildNeeded), + lastRebuild, + rebuildFrom, + additionalProperties.toMutableMap(), + ) + } + + private var validated: Boolean = false + + fun validate(): LoanTapeRebuildConfiguration = apply { + if (validated) { + return@apply + } + + rebuildNeeded() + lastRebuild() + rebuildFrom() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: LithicInvalidDataException) { + false + } + + /** + * Returns a score indicating how many valid values are contained in this object recursively. + * + * Used for best match union deserialization. + */ + @JvmSynthetic + internal fun validity(): Int = + (if (rebuildNeeded.asKnown().isPresent) 1 else 0) + + (if (lastRebuild.asKnown().isPresent) 1 else 0) + + (if (rebuildFrom.asKnown().isPresent) 1 else 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is LoanTapeRebuildConfiguration && + rebuildNeeded == other.rebuildNeeded && + lastRebuild == other.lastRebuild && + rebuildFrom == other.rebuildFrom && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(rebuildNeeded, lastRebuild, rebuildFrom, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "LoanTapeRebuildConfiguration{rebuildNeeded=$rebuildNeeded, lastRebuild=$lastRebuild, rebuildFrom=$rebuildFrom, additionalProperties=$additionalProperties}" +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/models/Statement.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/models/Statement.kt index de6ca12a..c4cc252d 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/models/Statement.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/models/Statement.kt @@ -1902,6 +1902,8 @@ private constructor( @JvmField val DELINQUENT = of("DELINQUENT") + @JvmField val INTEREST_AND_FEES_PAUSED = of("INTEREST_AND_FEES_PAUSED") + @JvmStatic fun of(value: String) = FinancialAccountSubstatus(JsonField.of(value)) } @@ -1913,6 +1915,7 @@ private constructor( END_USER_REQUEST, BANK_REQUEST, DELINQUENT, + INTEREST_AND_FEES_PAUSED, } /** @@ -1932,6 +1935,7 @@ private constructor( END_USER_REQUEST, BANK_REQUEST, DELINQUENT, + INTEREST_AND_FEES_PAUSED, /** * An enum member indicating that [FinancialAccountSubstatus] was instantiated * with an unknown value. @@ -1953,6 +1957,7 @@ private constructor( END_USER_REQUEST -> Value.END_USER_REQUEST BANK_REQUEST -> Value.BANK_REQUEST DELINQUENT -> Value.DELINQUENT + INTEREST_AND_FEES_PAUSED -> Value.INTEREST_AND_FEES_PAUSED else -> Value._UNKNOWN } @@ -1972,6 +1977,7 @@ private constructor( END_USER_REQUEST -> Known.END_USER_REQUEST BANK_REQUEST -> Known.BANK_REQUEST DELINQUENT -> Known.DELINQUENT + INTEREST_AND_FEES_PAUSED -> Known.INTEREST_AND_FEES_PAUSED else -> throw LithicInvalidDataException( "Unknown FinancialAccountSubstatus: $value" diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/AccountHolderServiceAsync.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/AccountHolderServiceAsync.kt index a2f1ff8a..81d88ec7 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/AccountHolderServiceAsync.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/AccountHolderServiceAsync.kt @@ -24,6 +24,7 @@ import com.lithic.api.models.Document import com.lithic.api.models.Kyb import com.lithic.api.models.Kyc import com.lithic.api.models.KycExempt +import com.lithic.api.services.async.accountHolders.EntityServiceAsync import java.util.concurrent.CompletableFuture import java.util.function.Consumer @@ -41,6 +42,8 @@ interface AccountHolderServiceAsync { */ fun withOptions(modifier: Consumer): AccountHolderServiceAsync + fun entities(): EntityServiceAsync + /** * Create an account holder and initiate the appropriate onboarding workflow. Account holders * and accounts have a 1:1 relationship. When an account holder is successfully created an @@ -401,6 +404,8 @@ interface AccountHolderServiceAsync { modifier: Consumer ): AccountHolderServiceAsync.WithRawResponse + fun entities(): EntityServiceAsync.WithRawResponse + /** * Returns a raw HTTP response for `post /v1/account_holders`, but is otherwise the same as * [AccountHolderServiceAsync.create]. diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/AccountHolderServiceAsyncImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/AccountHolderServiceAsyncImpl.kt index 91b71340..0c0e4bcf 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/AccountHolderServiceAsyncImpl.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/AccountHolderServiceAsyncImpl.kt @@ -33,6 +33,8 @@ import com.lithic.api.models.AccountHolderUpdateParams import com.lithic.api.models.AccountHolderUpdateResponse import com.lithic.api.models.AccountHolderUploadDocumentParams import com.lithic.api.models.Document +import com.lithic.api.services.async.accountHolders.EntityServiceAsync +import com.lithic.api.services.async.accountHolders.EntityServiceAsyncImpl import java.time.Duration import java.util.concurrent.CompletableFuture import java.util.function.Consumer @@ -45,11 +47,15 @@ class AccountHolderServiceAsyncImpl internal constructor(private val clientOptio WithRawResponseImpl(clientOptions) } + private val entities: EntityServiceAsync by lazy { EntityServiceAsyncImpl(clientOptions) } + override fun withRawResponse(): AccountHolderServiceAsync.WithRawResponse = withRawResponse override fun withOptions(modifier: Consumer): AccountHolderServiceAsync = AccountHolderServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + override fun entities(): EntityServiceAsync = entities + override fun create( params: AccountHolderCreateParams, requestOptions: RequestOptions, @@ -121,6 +127,10 @@ class AccountHolderServiceAsyncImpl internal constructor(private val clientOptio private val errorHandler: Handler = errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + private val entities: EntityServiceAsync.WithRawResponse by lazy { + EntityServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + override fun withOptions( modifier: Consumer ): AccountHolderServiceAsync.WithRawResponse = @@ -128,6 +138,8 @@ class AccountHolderServiceAsyncImpl internal constructor(private val clientOptio clientOptions.toBuilder().apply(modifier::accept).build() ) + override fun entities(): EntityServiceAsync.WithRawResponse = entities + private val createHandler: Handler = jsonHandler(clientOptions.jsonMapper) diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/CardServiceAsyncImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/CardServiceAsyncImpl.kt index a723a8ad..c0f754b8 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/CardServiceAsyncImpl.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/CardServiceAsyncImpl.kt @@ -41,14 +41,13 @@ import com.lithic.api.services.async.cards.BalanceServiceAsync import com.lithic.api.services.async.cards.BalanceServiceAsyncImpl import com.lithic.api.services.async.cards.FinancialTransactionServiceAsync import com.lithic.api.services.async.cards.FinancialTransactionServiceAsyncImpl -import java.net.URI +import java.net.URLEncoder import java.util.Base64 import java.util.concurrent.CompletableFuture import java.util.function.Consumer import javax.crypto.Mac import javax.crypto.spec.SecretKeySpec import kotlin.jvm.optionals.getOrNull -import org.apache.hc.core5.net.URIBuilder class CardServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : CardServiceAsync { @@ -361,6 +360,7 @@ class CardServiceAsyncImpl internal constructor(private val clientOptions: Clien .method(HttpMethod.GET) .baseUrl(clientOptions.baseUrl()) .addPathSegments("v1", "embed", "card") + .putHeader("Accept", "text/html") .build() .prepareAsync(clientOptions, params) val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) @@ -591,6 +591,7 @@ class CardServiceAsyncImpl internal constructor(private val clientOptions: Clien val request = HttpRequest.builder() .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) .addPathSegments("v1", "embed", "card") .putQueryParam("embed_request", embed_request) .putQueryParam("hmac", embed_request_hmac) @@ -617,10 +618,14 @@ class CardServiceAsyncImpl internal constructor(private val clientOptions: Clien val embed_request_hmac = Base64.getEncoder().encodeToString(mac.doFinal(embed_request.toByteArray())) - return URIBuilder(URI.create(clientOptions.baseUrl())) - .appendPathSegments("embed", "card") - .addParameter("embed_request", embed_request) - .addParameter("hmac", embed_request_hmac) - .toString() + return buildString { + append(clientOptions.baseUrl()) + if (!endsWith("/")) append("/") + append("embed/card") + append("?embed_request=") + append(URLEncoder.encode(embed_request, "UTF-8")) + append("&hmac=") + append(URLEncoder.encode(embed_request_hmac, "UTF-8")) + } } } diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/FinancialAccountServiceAsync.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/FinancialAccountServiceAsync.kt index 8e70b49f..8d0362c4 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/FinancialAccountServiceAsync.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/FinancialAccountServiceAsync.kt @@ -17,6 +17,8 @@ import com.lithic.api.models.FinancialAccountUpdateStatusParams import com.lithic.api.services.async.financialAccounts.BalanceServiceAsync import com.lithic.api.services.async.financialAccounts.CreditConfigurationServiceAsync import com.lithic.api.services.async.financialAccounts.FinancialTransactionServiceAsync +import com.lithic.api.services.async.financialAccounts.InterestTierScheduleServiceAsync +import com.lithic.api.services.async.financialAccounts.LoanTapeConfigurationServiceAsync import com.lithic.api.services.async.financialAccounts.LoanTapeServiceAsync import com.lithic.api.services.async.financialAccounts.StatementServiceAsync import java.util.concurrent.CompletableFuture @@ -46,6 +48,10 @@ interface FinancialAccountServiceAsync { fun loanTapes(): LoanTapeServiceAsync + fun loanTapeConfiguration(): LoanTapeConfigurationServiceAsync + + fun interestTierSchedule(): InterestTierScheduleServiceAsync + /** Create a new financial account */ fun create(params: FinancialAccountCreateParams): CompletableFuture = create(params, RequestOptions.none()) @@ -236,6 +242,10 @@ interface FinancialAccountServiceAsync { fun loanTapes(): LoanTapeServiceAsync.WithRawResponse + fun loanTapeConfiguration(): LoanTapeConfigurationServiceAsync.WithRawResponse + + fun interestTierSchedule(): InterestTierScheduleServiceAsync.WithRawResponse + /** * Returns a raw HTTP response for `post /v1/financial_accounts`, but is otherwise the same * as [FinancialAccountServiceAsync.create]. diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/FinancialAccountServiceAsyncImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/FinancialAccountServiceAsyncImpl.kt index ca57d2c0..94d99f44 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/FinancialAccountServiceAsyncImpl.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/FinancialAccountServiceAsyncImpl.kt @@ -32,6 +32,10 @@ import com.lithic.api.services.async.financialAccounts.CreditConfigurationServic import com.lithic.api.services.async.financialAccounts.CreditConfigurationServiceAsyncImpl import com.lithic.api.services.async.financialAccounts.FinancialTransactionServiceAsync import com.lithic.api.services.async.financialAccounts.FinancialTransactionServiceAsyncImpl +import com.lithic.api.services.async.financialAccounts.InterestTierScheduleServiceAsync +import com.lithic.api.services.async.financialAccounts.InterestTierScheduleServiceAsyncImpl +import com.lithic.api.services.async.financialAccounts.LoanTapeConfigurationServiceAsync +import com.lithic.api.services.async.financialAccounts.LoanTapeConfigurationServiceAsyncImpl import com.lithic.api.services.async.financialAccounts.LoanTapeServiceAsync import com.lithic.api.services.async.financialAccounts.LoanTapeServiceAsyncImpl import com.lithic.api.services.async.financialAccounts.StatementServiceAsync @@ -63,6 +67,14 @@ internal constructor(private val clientOptions: ClientOptions) : FinancialAccoun private val loanTapes: LoanTapeServiceAsync by lazy { LoanTapeServiceAsyncImpl(clientOptions) } + private val loanTapeConfiguration: LoanTapeConfigurationServiceAsync by lazy { + LoanTapeConfigurationServiceAsyncImpl(clientOptions) + } + + private val interestTierSchedule: InterestTierScheduleServiceAsync by lazy { + InterestTierScheduleServiceAsyncImpl(clientOptions) + } + override fun withRawResponse(): FinancialAccountServiceAsync.WithRawResponse = withRawResponse override fun withOptions( @@ -80,6 +92,10 @@ internal constructor(private val clientOptions: ClientOptions) : FinancialAccoun override fun loanTapes(): LoanTapeServiceAsync = loanTapes + override fun loanTapeConfiguration(): LoanTapeConfigurationServiceAsync = loanTapeConfiguration + + override fun interestTierSchedule(): InterestTierScheduleServiceAsync = interestTierSchedule + override fun create( params: FinancialAccountCreateParams, requestOptions: RequestOptions, @@ -149,6 +165,15 @@ internal constructor(private val clientOptions: ClientOptions) : FinancialAccoun LoanTapeServiceAsyncImpl.WithRawResponseImpl(clientOptions) } + private val loanTapeConfiguration: + LoanTapeConfigurationServiceAsync.WithRawResponse by lazy { + LoanTapeConfigurationServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + + private val interestTierSchedule: InterestTierScheduleServiceAsync.WithRawResponse by lazy { + InterestTierScheduleServiceAsyncImpl.WithRawResponseImpl(clientOptions) + } + override fun withOptions( modifier: Consumer ): FinancialAccountServiceAsync.WithRawResponse = @@ -168,6 +193,12 @@ internal constructor(private val clientOptions: ClientOptions) : FinancialAccoun override fun loanTapes(): LoanTapeServiceAsync.WithRawResponse = loanTapes + override fun loanTapeConfiguration(): LoanTapeConfigurationServiceAsync.WithRawResponse = + loanTapeConfiguration + + override fun interestTierSchedule(): InterestTierScheduleServiceAsync.WithRawResponse = + interestTierSchedule + private val createHandler: Handler = jsonHandler(clientOptions.jsonMapper) diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/accountHolders/EntityServiceAsync.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/accountHolders/EntityServiceAsync.kt new file mode 100644 index 00000000..64d91bb0 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/accountHolders/EntityServiceAsync.kt @@ -0,0 +1,165 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.async.accountHolders + +import com.lithic.api.core.ClientOptions +import com.lithic.api.core.RequestOptions +import com.lithic.api.core.http.HttpResponseFor +import com.lithic.api.models.AccountHolderEntity +import com.lithic.api.models.AccountHolderEntityCreateParams +import com.lithic.api.models.AccountHolderEntityDeleteParams +import com.lithic.api.models.EntityCreateResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface EntityServiceAsync { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): EntityServiceAsync + + /** + * Create a new beneficial owner or replace the control person entity on an existing KYB account + * holder. This endpoint is only applicable for account holders enrolled through a KYB workflow + * with the Persona KYB provider. A new control person can only replace the existing one. A + * maximum of 4 beneficial owners can be associated with an account holder. + */ + fun create( + accountHolderToken: String, + params: AccountHolderEntityCreateParams, + ): CompletableFuture = + create(accountHolderToken, params, RequestOptions.none()) + + /** @see create */ + fun create( + accountHolderToken: String, + params: AccountHolderEntityCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create(params.toBuilder().accountHolderToken(accountHolderToken).build(), requestOptions) + + /** @see create */ + fun create(params: AccountHolderEntityCreateParams): CompletableFuture = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + params: AccountHolderEntityCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * Deactivate a beneficial owner entity on an existing KYB account holder. Only beneficial owner + * entities can be deactivated. + */ + fun delete( + entityToken: String, + params: AccountHolderEntityDeleteParams, + ): CompletableFuture = delete(entityToken, params, RequestOptions.none()) + + /** @see delete */ + fun delete( + entityToken: String, + params: AccountHolderEntityDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().entityToken(entityToken).build(), requestOptions) + + /** @see delete */ + fun delete(params: AccountHolderEntityDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see delete */ + fun delete( + params: AccountHolderEntityDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * A view of [EntityServiceAsync] that provides access to raw HTTP responses for each method. + */ + interface WithRawResponse { + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions( + modifier: Consumer + ): EntityServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post + * /v1/account_holders/{account_holder_token}/entities`, but is otherwise the same as + * [EntityServiceAsync.create]. + */ + fun create( + accountHolderToken: String, + params: AccountHolderEntityCreateParams, + ): CompletableFuture> = + create(accountHolderToken, params, RequestOptions.none()) + + /** @see create */ + fun create( + accountHolderToken: String, + params: AccountHolderEntityCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create( + params.toBuilder().accountHolderToken(accountHolderToken).build(), + requestOptions, + ) + + /** @see create */ + fun create( + params: AccountHolderEntityCreateParams + ): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + params: AccountHolderEntityCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `delete + * /v1/account_holders/{account_holder_token}/entities/{entity_token}`, but is otherwise the + * same as [EntityServiceAsync.delete]. + */ + fun delete( + entityToken: String, + params: AccountHolderEntityDeleteParams, + ): CompletableFuture> = + delete(entityToken, params, RequestOptions.none()) + + /** @see delete */ + fun delete( + entityToken: String, + params: AccountHolderEntityDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + delete(params.toBuilder().entityToken(entityToken).build(), requestOptions) + + /** @see delete */ + fun delete( + params: AccountHolderEntityDeleteParams + ): CompletableFuture> = + delete(params, RequestOptions.none()) + + /** @see delete */ + fun delete( + params: AccountHolderEntityDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + } +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/accountHolders/EntityServiceAsyncImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/accountHolders/EntityServiceAsyncImpl.kt new file mode 100644 index 00000000..db5a68ef --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/accountHolders/EntityServiceAsyncImpl.kt @@ -0,0 +1,140 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.async.accountHolders + +import com.lithic.api.core.ClientOptions +import com.lithic.api.core.RequestOptions +import com.lithic.api.core.checkRequired +import com.lithic.api.core.handlers.errorBodyHandler +import com.lithic.api.core.handlers.errorHandler +import com.lithic.api.core.handlers.jsonHandler +import com.lithic.api.core.http.HttpMethod +import com.lithic.api.core.http.HttpRequest +import com.lithic.api.core.http.HttpResponse +import com.lithic.api.core.http.HttpResponse.Handler +import com.lithic.api.core.http.HttpResponseFor +import com.lithic.api.core.http.json +import com.lithic.api.core.http.parseable +import com.lithic.api.core.prepareAsync +import com.lithic.api.models.AccountHolderEntity +import com.lithic.api.models.AccountHolderEntityCreateParams +import com.lithic.api.models.AccountHolderEntityDeleteParams +import com.lithic.api.models.EntityCreateResponse +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull + +class EntityServiceAsyncImpl internal constructor(private val clientOptions: ClientOptions) : + EntityServiceAsync { + + private val withRawResponse: EntityServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): EntityServiceAsync.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): EntityServiceAsync = + EntityServiceAsyncImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun create( + params: AccountHolderEntityCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/account_holders/{account_holder_token}/entities + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: AccountHolderEntityDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete /v1/account_holders/{account_holder_token}/entities/{entity_token} + withRawResponse().delete(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + EntityServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): EntityServiceAsync.WithRawResponse = + EntityServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: AccountHolderEntityCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("accountHolderToken", params.accountHolderToken().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "account_holders", params._pathParam(0), "entities") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun delete( + params: AccountHolderEntityDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("entityToken", params.entityToken().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "v1", + "account_holders", + params._pathParam(0), + "entities", + params._pathParam(1), + ) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/financialAccounts/InterestTierScheduleServiceAsync.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/financialAccounts/InterestTierScheduleServiceAsync.kt new file mode 100644 index 00000000..cbd4fceb --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/financialAccounts/InterestTierScheduleServiceAsync.kt @@ -0,0 +1,405 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.async.financialAccounts + +import com.lithic.api.core.ClientOptions +import com.lithic.api.core.RequestOptions +import com.lithic.api.core.http.HttpResponse +import com.lithic.api.core.http.HttpResponseFor +import com.lithic.api.models.FinancialAccountInterestTierScheduleCreateParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleDeleteParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleListPageAsync +import com.lithic.api.models.FinancialAccountInterestTierScheduleListParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleRetrieveParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleUpdateParams +import com.lithic.api.models.InterestTierSchedule +import java.time.LocalDate +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface InterestTierScheduleServiceAsync { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): InterestTierScheduleServiceAsync + + /** Create a new interest tier schedule entry for a supported financial account */ + fun create( + financialAccountToken: String, + params: FinancialAccountInterestTierScheduleCreateParams, + ): CompletableFuture = + create(financialAccountToken, params, RequestOptions.none()) + + /** @see create */ + fun create( + financialAccountToken: String, + params: FinancialAccountInterestTierScheduleCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + create( + params.toBuilder().financialAccountToken(financialAccountToken).build(), + requestOptions, + ) + + /** @see create */ + fun create( + params: FinancialAccountInterestTierScheduleCreateParams + ): CompletableFuture = create(params, RequestOptions.none()) + + /** @see create */ + fun create( + params: FinancialAccountInterestTierScheduleCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** Get a specific interest tier schedule by effective date */ + fun retrieve( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleRetrieveParams, + ): CompletableFuture = + retrieve(effectiveDate, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve(params.toBuilder().effectiveDate(effectiveDate).build(), requestOptions) + + /** @see retrieve */ + fun retrieve( + params: FinancialAccountInterestTierScheduleRetrieveParams + ): CompletableFuture = retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: FinancialAccountInterestTierScheduleRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** Update an existing interest tier schedule */ + fun update( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleUpdateParams, + ): CompletableFuture = + update(effectiveDate, params, RequestOptions.none()) + + /** @see update */ + fun update( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + update(params.toBuilder().effectiveDate(effectiveDate).build(), requestOptions) + + /** @see update */ + fun update( + params: FinancialAccountInterestTierScheduleUpdateParams + ): CompletableFuture = update(params, RequestOptions.none()) + + /** @see update */ + fun update( + params: FinancialAccountInterestTierScheduleUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * List interest tier schedules for a financial account with optional date filtering. + * + * If no date parameters are provided, returns all tier schedules. If date parameters are + * provided, uses filtering to return matching schedules (max 100). + * - for_date: Returns exact match (takes precedence over other dates) + * - before_date: Returns schedules with effective_date <= before_date + * - after_date: Returns schedules with effective_date >= after_date + * - Both before_date and after_date: Returns schedules in range + */ + fun list( + financialAccountToken: String + ): CompletableFuture = + list(financialAccountToken, FinancialAccountInterestTierScheduleListParams.none()) + + /** @see list */ + fun list( + financialAccountToken: String, + params: FinancialAccountInterestTierScheduleListParams = + FinancialAccountInterestTierScheduleListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + list( + params.toBuilder().financialAccountToken(financialAccountToken).build(), + requestOptions, + ) + + /** @see list */ + fun list( + financialAccountToken: String, + params: FinancialAccountInterestTierScheduleListParams = + FinancialAccountInterestTierScheduleListParams.none(), + ): CompletableFuture = + list(financialAccountToken, params, RequestOptions.none()) + + /** @see list */ + fun list( + params: FinancialAccountInterestTierScheduleListParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see list */ + fun list( + params: FinancialAccountInterestTierScheduleListParams + ): CompletableFuture = + list(params, RequestOptions.none()) + + /** @see list */ + fun list( + financialAccountToken: String, + requestOptions: RequestOptions, + ): CompletableFuture = + list( + financialAccountToken, + FinancialAccountInterestTierScheduleListParams.none(), + requestOptions, + ) + + /** + * Delete an interest tier schedule entry. + * + * Returns: + * - 400 Bad Request: Invalid effective_date format OR attempting to delete the earliest tier + * schedule entry for a non-PENDING account + * - 404 Not Found: Tier schedule entry not found for the given effective_date OR ledger account + * not found + * + * Note: PENDING accounts can delete the earliest tier schedule entry (account hasn't opened + * yet). Active/non-PENDING accounts cannot delete the earliest entry to prevent orphaning the + * account. + * + * If the deleted tier schedule has a past effective_date and the account is ACTIVE, the loan + * tape rebuild configuration will be updated to trigger rebuilds from that date. + */ + fun delete( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleDeleteParams, + ): CompletableFuture = delete(effectiveDate, params, RequestOptions.none()) + + /** @see delete */ + fun delete( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().effectiveDate(effectiveDate).build(), requestOptions) + + /** @see delete */ + fun delete(params: FinancialAccountInterestTierScheduleDeleteParams): CompletableFuture = + delete(params, RequestOptions.none()) + + /** @see delete */ + fun delete( + params: FinancialAccountInterestTierScheduleDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** + * A view of [InterestTierScheduleServiceAsync] that provides access to raw HTTP responses for + * each method. + */ + interface WithRawResponse { + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions( + modifier: Consumer + ): InterestTierScheduleServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `post + * /v1/financial_accounts/{financial_account_token}/interest_tier_schedule`, but is + * otherwise the same as [InterestTierScheduleServiceAsync.create]. + */ + fun create( + financialAccountToken: String, + params: FinancialAccountInterestTierScheduleCreateParams, + ): CompletableFuture> = + create(financialAccountToken, params, RequestOptions.none()) + + /** @see create */ + fun create( + financialAccountToken: String, + params: FinancialAccountInterestTierScheduleCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + create( + params.toBuilder().financialAccountToken(financialAccountToken).build(), + requestOptions, + ) + + /** @see create */ + fun create( + params: FinancialAccountInterestTierScheduleCreateParams + ): CompletableFuture> = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + params: FinancialAccountInterestTierScheduleCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get + * /v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}`, + * but is otherwise the same as [InterestTierScheduleServiceAsync.retrieve]. + */ + fun retrieve( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleRetrieveParams, + ): CompletableFuture> = + retrieve(effectiveDate, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve(params.toBuilder().effectiveDate(effectiveDate).build(), requestOptions) + + /** @see retrieve */ + fun retrieve( + params: FinancialAccountInterestTierScheduleRetrieveParams + ): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: FinancialAccountInterestTierScheduleRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `put + * /v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}`, + * but is otherwise the same as [InterestTierScheduleServiceAsync.update]. + */ + fun update( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleUpdateParams, + ): CompletableFuture> = + update(effectiveDate, params, RequestOptions.none()) + + /** @see update */ + fun update( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + update(params.toBuilder().effectiveDate(effectiveDate).build(), requestOptions) + + /** @see update */ + fun update( + params: FinancialAccountInterestTierScheduleUpdateParams + ): CompletableFuture> = + update(params, RequestOptions.none()) + + /** @see update */ + fun update( + params: FinancialAccountInterestTierScheduleUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** + * Returns a raw HTTP response for `get + * /v1/financial_accounts/{financial_account_token}/interest_tier_schedule`, but is + * otherwise the same as [InterestTierScheduleServiceAsync.list]. + */ + fun list( + financialAccountToken: String + ): CompletableFuture> = + list(financialAccountToken, FinancialAccountInterestTierScheduleListParams.none()) + + /** @see list */ + fun list( + financialAccountToken: String, + params: FinancialAccountInterestTierScheduleListParams = + FinancialAccountInterestTierScheduleListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + list( + params.toBuilder().financialAccountToken(financialAccountToken).build(), + requestOptions, + ) + + /** @see list */ + fun list( + financialAccountToken: String, + params: FinancialAccountInterestTierScheduleListParams = + FinancialAccountInterestTierScheduleListParams.none(), + ): CompletableFuture> = + list(financialAccountToken, params, RequestOptions.none()) + + /** @see list */ + fun list( + params: FinancialAccountInterestTierScheduleListParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see list */ + fun list( + params: FinancialAccountInterestTierScheduleListParams + ): CompletableFuture> = + list(params, RequestOptions.none()) + + /** @see list */ + fun list( + financialAccountToken: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + list( + financialAccountToken, + FinancialAccountInterestTierScheduleListParams.none(), + requestOptions, + ) + + /** + * Returns a raw HTTP response for `delete + * /v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}`, + * but is otherwise the same as [InterestTierScheduleServiceAsync.delete]. + */ + fun delete( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleDeleteParams, + ): CompletableFuture = delete(effectiveDate, params, RequestOptions.none()) + + /** @see delete */ + fun delete( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + delete(params.toBuilder().effectiveDate(effectiveDate).build(), requestOptions) + + /** @see delete */ + fun delete( + params: FinancialAccountInterestTierScheduleDeleteParams + ): CompletableFuture = delete(params, RequestOptions.none()) + + /** @see delete */ + fun delete( + params: FinancialAccountInterestTierScheduleDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + } +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/financialAccounts/InterestTierScheduleServiceAsyncImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/financialAccounts/InterestTierScheduleServiceAsyncImpl.kt new file mode 100644 index 00000000..20ce35cb --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/financialAccounts/InterestTierScheduleServiceAsyncImpl.kt @@ -0,0 +1,299 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.async.financialAccounts + +import com.lithic.api.core.ClientOptions +import com.lithic.api.core.RequestOptions +import com.lithic.api.core.checkRequired +import com.lithic.api.core.handlers.emptyHandler +import com.lithic.api.core.handlers.errorBodyHandler +import com.lithic.api.core.handlers.errorHandler +import com.lithic.api.core.handlers.jsonHandler +import com.lithic.api.core.http.HttpMethod +import com.lithic.api.core.http.HttpRequest +import com.lithic.api.core.http.HttpResponse +import com.lithic.api.core.http.HttpResponse.Handler +import com.lithic.api.core.http.HttpResponseFor +import com.lithic.api.core.http.json +import com.lithic.api.core.http.parseable +import com.lithic.api.core.prepareAsync +import com.lithic.api.models.FinancialAccountInterestTierScheduleCreateParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleDeleteParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleListPageAsync +import com.lithic.api.models.FinancialAccountInterestTierScheduleListPageResponse +import com.lithic.api.models.FinancialAccountInterestTierScheduleListParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleRetrieveParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleUpdateParams +import com.lithic.api.models.InterestTierSchedule +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull + +class InterestTierScheduleServiceAsyncImpl +internal constructor(private val clientOptions: ClientOptions) : InterestTierScheduleServiceAsync { + + private val withRawResponse: InterestTierScheduleServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): InterestTierScheduleServiceAsync.WithRawResponse = + withRawResponse + + override fun withOptions( + modifier: Consumer + ): InterestTierScheduleServiceAsync = + InterestTierScheduleServiceAsyncImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + override fun create( + params: FinancialAccountInterestTierScheduleCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // post /v1/financial_accounts/{financial_account_token}/interest_tier_schedule + withRawResponse().create(params, requestOptions).thenApply { it.parse() } + + override fun retrieve( + params: FinancialAccountInterestTierScheduleRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get + // /v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date} + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + override fun update( + params: FinancialAccountInterestTierScheduleUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // put + // /v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date} + withRawResponse().update(params, requestOptions).thenApply { it.parse() } + + override fun list( + params: FinancialAccountInterestTierScheduleListParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/financial_accounts/{financial_account_token}/interest_tier_schedule + withRawResponse().list(params, requestOptions).thenApply { it.parse() } + + override fun delete( + params: FinancialAccountInterestTierScheduleDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // delete + // /v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date} + withRawResponse().delete(params, requestOptions).thenAccept {} + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + InterestTierScheduleServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): InterestTierScheduleServiceAsync.WithRawResponse = + InterestTierScheduleServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: FinancialAccountInterestTierScheduleCreateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("financialAccountToken", params.financialAccountToken().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "v1", + "financial_accounts", + params._pathParam(0), + "interest_tier_schedule", + ) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun retrieve( + params: FinancialAccountInterestTierScheduleRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("effectiveDate", params.effectiveDate().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "v1", + "financial_accounts", + params._pathParam(0), + "interest_tier_schedule", + params._pathParam(1), + ) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun update( + params: FinancialAccountInterestTierScheduleUpdateParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("effectiveDate", params.effectiveDate().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "v1", + "financial_accounts", + params._pathParam(0), + "interest_tier_schedule", + params._pathParam(1), + ) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + + private val listHandler: Handler = + jsonHandler( + clientOptions.jsonMapper + ) + + override fun list( + params: FinancialAccountInterestTierScheduleListParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("financialAccountToken", params.financialAccountToken().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "v1", + "financial_accounts", + params._pathParam(0), + "interest_tier_schedule", + ) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + FinancialAccountInterestTierScheduleListPageAsync.builder() + .service(InterestTierScheduleServiceAsyncImpl(clientOptions)) + .streamHandlerExecutor(clientOptions.streamHandlerExecutor) + .params(params) + .response(it) + .build() + } + } + } + } + + private val deleteHandler: Handler = emptyHandler() + + override fun delete( + params: FinancialAccountInterestTierScheduleDeleteParams, + requestOptions: RequestOptions, + ): CompletableFuture { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("effectiveDate", params.effectiveDate().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "v1", + "financial_accounts", + params._pathParam(0), + "interest_tier_schedule", + params._pathParam(1), + ) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response.use { deleteHandler.handle(it) } + } + } + } + } +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/financialAccounts/LoanTapeConfigurationServiceAsync.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/financialAccounts/LoanTapeConfigurationServiceAsync.kt new file mode 100644 index 00000000..40a7b901 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/financialAccounts/LoanTapeConfigurationServiceAsync.kt @@ -0,0 +1,144 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.async.financialAccounts + +import com.lithic.api.core.ClientOptions +import com.lithic.api.core.RequestOptions +import com.lithic.api.core.http.HttpResponseFor +import com.lithic.api.models.FinancialAccountLoanTapeConfigurationRetrieveParams +import com.lithic.api.models.LoanTapeConfiguration +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer + +interface LoanTapeConfigurationServiceAsync { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): LoanTapeConfigurationServiceAsync + + /** Get the loan tape configuration for a given financial account. */ + fun retrieve(financialAccountToken: String): CompletableFuture = + retrieve(financialAccountToken, FinancialAccountLoanTapeConfigurationRetrieveParams.none()) + + /** @see retrieve */ + fun retrieve( + financialAccountToken: String, + params: FinancialAccountLoanTapeConfigurationRetrieveParams = + FinancialAccountLoanTapeConfigurationRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture = + retrieve( + params.toBuilder().financialAccountToken(financialAccountToken).build(), + requestOptions, + ) + + /** @see retrieve */ + fun retrieve( + financialAccountToken: String, + params: FinancialAccountLoanTapeConfigurationRetrieveParams = + FinancialAccountLoanTapeConfigurationRetrieveParams.none(), + ): CompletableFuture = + retrieve(financialAccountToken, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: FinancialAccountLoanTapeConfigurationRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture + + /** @see retrieve */ + fun retrieve( + params: FinancialAccountLoanTapeConfigurationRetrieveParams + ): CompletableFuture = retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + financialAccountToken: String, + requestOptions: RequestOptions, + ): CompletableFuture = + retrieve( + financialAccountToken, + FinancialAccountLoanTapeConfigurationRetrieveParams.none(), + requestOptions, + ) + + /** + * A view of [LoanTapeConfigurationServiceAsync] that provides access to raw HTTP responses for + * each method. + */ + interface WithRawResponse { + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions( + modifier: Consumer + ): LoanTapeConfigurationServiceAsync.WithRawResponse + + /** + * Returns a raw HTTP response for `get + * /v1/financial_accounts/{financial_account_token}/loan_tape_configuration`, but is + * otherwise the same as [LoanTapeConfigurationServiceAsync.retrieve]. + */ + fun retrieve( + financialAccountToken: String + ): CompletableFuture> = + retrieve( + financialAccountToken, + FinancialAccountLoanTapeConfigurationRetrieveParams.none(), + ) + + /** @see retrieve */ + fun retrieve( + financialAccountToken: String, + params: FinancialAccountLoanTapeConfigurationRetrieveParams = + FinancialAccountLoanTapeConfigurationRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> = + retrieve( + params.toBuilder().financialAccountToken(financialAccountToken).build(), + requestOptions, + ) + + /** @see retrieve */ + fun retrieve( + financialAccountToken: String, + params: FinancialAccountLoanTapeConfigurationRetrieveParams = + FinancialAccountLoanTapeConfigurationRetrieveParams.none(), + ): CompletableFuture> = + retrieve(financialAccountToken, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: FinancialAccountLoanTapeConfigurationRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): CompletableFuture> + + /** @see retrieve */ + fun retrieve( + params: FinancialAccountLoanTapeConfigurationRetrieveParams + ): CompletableFuture> = + retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + financialAccountToken: String, + requestOptions: RequestOptions, + ): CompletableFuture> = + retrieve( + financialAccountToken, + FinancialAccountLoanTapeConfigurationRetrieveParams.none(), + requestOptions, + ) + } +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/financialAccounts/LoanTapeConfigurationServiceAsyncImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/financialAccounts/LoanTapeConfigurationServiceAsyncImpl.kt new file mode 100644 index 00000000..8db9e452 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/async/financialAccounts/LoanTapeConfigurationServiceAsyncImpl.kt @@ -0,0 +1,99 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.async.financialAccounts + +import com.lithic.api.core.ClientOptions +import com.lithic.api.core.RequestOptions +import com.lithic.api.core.checkRequired +import com.lithic.api.core.handlers.errorBodyHandler +import com.lithic.api.core.handlers.errorHandler +import com.lithic.api.core.handlers.jsonHandler +import com.lithic.api.core.http.HttpMethod +import com.lithic.api.core.http.HttpRequest +import com.lithic.api.core.http.HttpResponse +import com.lithic.api.core.http.HttpResponse.Handler +import com.lithic.api.core.http.HttpResponseFor +import com.lithic.api.core.http.parseable +import com.lithic.api.core.prepareAsync +import com.lithic.api.models.FinancialAccountLoanTapeConfigurationRetrieveParams +import com.lithic.api.models.LoanTapeConfiguration +import java.util.concurrent.CompletableFuture +import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull + +class LoanTapeConfigurationServiceAsyncImpl +internal constructor(private val clientOptions: ClientOptions) : LoanTapeConfigurationServiceAsync { + + private val withRawResponse: LoanTapeConfigurationServiceAsync.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): LoanTapeConfigurationServiceAsync.WithRawResponse = + withRawResponse + + override fun withOptions( + modifier: Consumer + ): LoanTapeConfigurationServiceAsync = + LoanTapeConfigurationServiceAsyncImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + override fun retrieve( + params: FinancialAccountLoanTapeConfigurationRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture = + // get /v1/financial_accounts/{financial_account_token}/loan_tape_configuration + withRawResponse().retrieve(params, requestOptions).thenApply { it.parse() } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + LoanTapeConfigurationServiceAsync.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): LoanTapeConfigurationServiceAsync.WithRawResponse = + LoanTapeConfigurationServiceAsyncImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun retrieve( + params: FinancialAccountLoanTapeConfigurationRetrieveParams, + requestOptions: RequestOptions, + ): CompletableFuture> { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("financialAccountToken", params.financialAccountToken().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "v1", + "financial_accounts", + params._pathParam(0), + "loan_tape_configuration", + ) + .build() + .prepareAsync(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + return request + .thenComposeAsync { clientOptions.httpClient.executeAsync(it, requestOptions) } + .thenApply { response -> + errorHandler.handle(response).parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } + } +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/AccountHolderService.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/AccountHolderService.kt index b2f1c4af..f81503f2 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/AccountHolderService.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/AccountHolderService.kt @@ -25,6 +25,7 @@ import com.lithic.api.models.Document import com.lithic.api.models.Kyb import com.lithic.api.models.Kyc import com.lithic.api.models.KycExempt +import com.lithic.api.services.blocking.accountHolders.EntityService import java.util.function.Consumer interface AccountHolderService { @@ -41,6 +42,8 @@ interface AccountHolderService { */ fun withOptions(modifier: Consumer): AccountHolderService + fun entities(): EntityService + /** * Create an account holder and initiate the appropriate onboarding workflow. Account holders * and accounts have a 1:1 relationship. When an account holder is successfully created an @@ -387,6 +390,8 @@ interface AccountHolderService { modifier: Consumer ): AccountHolderService.WithRawResponse + fun entities(): EntityService.WithRawResponse + /** * Returns a raw HTTP response for `post /v1/account_holders`, but is otherwise the same as * [AccountHolderService.create]. diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/AccountHolderServiceImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/AccountHolderServiceImpl.kt index 332a9803..d4901c93 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/AccountHolderServiceImpl.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/AccountHolderServiceImpl.kt @@ -33,6 +33,8 @@ import com.lithic.api.models.AccountHolderUpdateParams import com.lithic.api.models.AccountHolderUpdateResponse import com.lithic.api.models.AccountHolderUploadDocumentParams import com.lithic.api.models.Document +import com.lithic.api.services.blocking.accountHolders.EntityService +import com.lithic.api.services.blocking.accountHolders.EntityServiceImpl import java.time.Duration import java.util.function.Consumer import kotlin.jvm.optionals.getOrNull @@ -44,11 +46,15 @@ class AccountHolderServiceImpl internal constructor(private val clientOptions: C WithRawResponseImpl(clientOptions) } + private val entities: EntityService by lazy { EntityServiceImpl(clientOptions) } + override fun withRawResponse(): AccountHolderService.WithRawResponse = withRawResponse override fun withOptions(modifier: Consumer): AccountHolderService = AccountHolderServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + override fun entities(): EntityService = entities + override fun create( params: AccountHolderCreateParams, requestOptions: RequestOptions, @@ -118,6 +124,10 @@ class AccountHolderServiceImpl internal constructor(private val clientOptions: C private val errorHandler: Handler = errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + private val entities: EntityService.WithRawResponse by lazy { + EntityServiceImpl.WithRawResponseImpl(clientOptions) + } + override fun withOptions( modifier: Consumer ): AccountHolderService.WithRawResponse = @@ -125,6 +135,8 @@ class AccountHolderServiceImpl internal constructor(private val clientOptions: C clientOptions.toBuilder().apply(modifier::accept).build() ) + override fun entities(): EntityService.WithRawResponse = entities + private val createHandler: Handler = jsonHandler(clientOptions.jsonMapper) diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/CardServiceImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/CardServiceImpl.kt index bbba30ed..9a1991ad 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/CardServiceImpl.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/CardServiceImpl.kt @@ -41,13 +41,12 @@ import com.lithic.api.services.blocking.cards.BalanceService import com.lithic.api.services.blocking.cards.BalanceServiceImpl import com.lithic.api.services.blocking.cards.FinancialTransactionService import com.lithic.api.services.blocking.cards.FinancialTransactionServiceImpl -import java.net.URI +import java.net.URLEncoder import java.util.Base64 import java.util.function.Consumer import javax.crypto.Mac import javax.crypto.spec.SecretKeySpec import kotlin.jvm.optionals.getOrNull -import org.apache.hc.core5.net.URIBuilder class CardServiceImpl internal constructor(private val clientOptions: ClientOptions) : CardService { @@ -318,6 +317,7 @@ class CardServiceImpl internal constructor(private val clientOptions: ClientOpti .method(HttpMethod.GET) .baseUrl(clientOptions.baseUrl()) .addPathSegments("v1", "embed", "card") + .putHeader("Accept", "text/html") .build() .prepare(clientOptions, params) val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) @@ -527,6 +527,7 @@ class CardServiceImpl internal constructor(private val clientOptions: ClientOpti val request = HttpRequest.builder() .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) .addPathSegments("v1", "embed", "card") .putQueryParam("embed_request", embed_request) .putQueryParam("hmac", embed_request_hmac) @@ -552,10 +553,14 @@ class CardServiceImpl internal constructor(private val clientOptions: ClientOpti val embed_request_hmac = Base64.getEncoder().encodeToString(mac.doFinal(embed_request.toByteArray())) - return URIBuilder(URI.create(clientOptions.baseUrl())) - .appendPathSegments("embed", "card") - .addParameter("embed_request", embed_request) - .addParameter("hmac", embed_request_hmac) - .toString() + return buildString { + append(clientOptions.baseUrl()) + if (!endsWith("/")) append("/") + append("embed/card") + append("?embed_request=") + append(URLEncoder.encode(embed_request, "UTF-8")) + append("&hmac=") + append(URLEncoder.encode(embed_request_hmac, "UTF-8")) + } } } diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/FinancialAccountService.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/FinancialAccountService.kt index a89d18a0..eee234e3 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/FinancialAccountService.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/FinancialAccountService.kt @@ -18,6 +18,8 @@ import com.lithic.api.models.FinancialAccountUpdateStatusParams import com.lithic.api.services.blocking.financialAccounts.BalanceService import com.lithic.api.services.blocking.financialAccounts.CreditConfigurationService import com.lithic.api.services.blocking.financialAccounts.FinancialTransactionService +import com.lithic.api.services.blocking.financialAccounts.InterestTierScheduleService +import com.lithic.api.services.blocking.financialAccounts.LoanTapeConfigurationService import com.lithic.api.services.blocking.financialAccounts.LoanTapeService import com.lithic.api.services.blocking.financialAccounts.StatementService import java.util.function.Consumer @@ -46,6 +48,10 @@ interface FinancialAccountService { fun loanTapes(): LoanTapeService + fun loanTapeConfiguration(): LoanTapeConfigurationService + + fun interestTierSchedule(): InterestTierScheduleService + /** Create a new financial account */ fun create(params: FinancialAccountCreateParams): FinancialAccount = create(params, RequestOptions.none()) @@ -223,6 +229,10 @@ interface FinancialAccountService { fun loanTapes(): LoanTapeService.WithRawResponse + fun loanTapeConfiguration(): LoanTapeConfigurationService.WithRawResponse + + fun interestTierSchedule(): InterestTierScheduleService.WithRawResponse + /** * Returns a raw HTTP response for `post /v1/financial_accounts`, but is otherwise the same * as [FinancialAccountService.create]. diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/FinancialAccountServiceImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/FinancialAccountServiceImpl.kt index 7e23c495..27ce794a 100644 --- a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/FinancialAccountServiceImpl.kt +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/FinancialAccountServiceImpl.kt @@ -32,6 +32,10 @@ import com.lithic.api.services.blocking.financialAccounts.CreditConfigurationSer import com.lithic.api.services.blocking.financialAccounts.CreditConfigurationServiceImpl import com.lithic.api.services.blocking.financialAccounts.FinancialTransactionService import com.lithic.api.services.blocking.financialAccounts.FinancialTransactionServiceImpl +import com.lithic.api.services.blocking.financialAccounts.InterestTierScheduleService +import com.lithic.api.services.blocking.financialAccounts.InterestTierScheduleServiceImpl +import com.lithic.api.services.blocking.financialAccounts.LoanTapeConfigurationService +import com.lithic.api.services.blocking.financialAccounts.LoanTapeConfigurationServiceImpl import com.lithic.api.services.blocking.financialAccounts.LoanTapeService import com.lithic.api.services.blocking.financialAccounts.LoanTapeServiceImpl import com.lithic.api.services.blocking.financialAccounts.StatementService @@ -60,6 +64,14 @@ class FinancialAccountServiceImpl internal constructor(private val clientOptions private val loanTapes: LoanTapeService by lazy { LoanTapeServiceImpl(clientOptions) } + private val loanTapeConfiguration: LoanTapeConfigurationService by lazy { + LoanTapeConfigurationServiceImpl(clientOptions) + } + + private val interestTierSchedule: InterestTierScheduleService by lazy { + InterestTierScheduleServiceImpl(clientOptions) + } + override fun withRawResponse(): FinancialAccountService.WithRawResponse = withRawResponse override fun withOptions(modifier: Consumer): FinancialAccountService = @@ -75,6 +87,10 @@ class FinancialAccountServiceImpl internal constructor(private val clientOptions override fun loanTapes(): LoanTapeService = loanTapes + override fun loanTapeConfiguration(): LoanTapeConfigurationService = loanTapeConfiguration + + override fun interestTierSchedule(): InterestTierScheduleService = interestTierSchedule + override fun create( params: FinancialAccountCreateParams, requestOptions: RequestOptions, @@ -144,6 +160,14 @@ class FinancialAccountServiceImpl internal constructor(private val clientOptions LoanTapeServiceImpl.WithRawResponseImpl(clientOptions) } + private val loanTapeConfiguration: LoanTapeConfigurationService.WithRawResponse by lazy { + LoanTapeConfigurationServiceImpl.WithRawResponseImpl(clientOptions) + } + + private val interestTierSchedule: InterestTierScheduleService.WithRawResponse by lazy { + InterestTierScheduleServiceImpl.WithRawResponseImpl(clientOptions) + } + override fun withOptions( modifier: Consumer ): FinancialAccountService.WithRawResponse = @@ -163,6 +187,12 @@ class FinancialAccountServiceImpl internal constructor(private val clientOptions override fun loanTapes(): LoanTapeService.WithRawResponse = loanTapes + override fun loanTapeConfiguration(): LoanTapeConfigurationService.WithRawResponse = + loanTapeConfiguration + + override fun interestTierSchedule(): InterestTierScheduleService.WithRawResponse = + interestTierSchedule + private val createHandler: Handler = jsonHandler(clientOptions.jsonMapper) diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/accountHolders/EntityService.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/accountHolders/EntityService.kt new file mode 100644 index 00000000..e54c0b0c --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/accountHolders/EntityService.kt @@ -0,0 +1,161 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.blocking.accountHolders + +import com.google.errorprone.annotations.MustBeClosed +import com.lithic.api.core.ClientOptions +import com.lithic.api.core.RequestOptions +import com.lithic.api.core.http.HttpResponseFor +import com.lithic.api.models.AccountHolderEntity +import com.lithic.api.models.AccountHolderEntityCreateParams +import com.lithic.api.models.AccountHolderEntityDeleteParams +import com.lithic.api.models.EntityCreateResponse +import java.util.function.Consumer + +interface EntityService { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): EntityService + + /** + * Create a new beneficial owner or replace the control person entity on an existing KYB account + * holder. This endpoint is only applicable for account holders enrolled through a KYB workflow + * with the Persona KYB provider. A new control person can only replace the existing one. A + * maximum of 4 beneficial owners can be associated with an account holder. + */ + fun create( + accountHolderToken: String, + params: AccountHolderEntityCreateParams, + ): EntityCreateResponse = create(accountHolderToken, params, RequestOptions.none()) + + /** @see create */ + fun create( + accountHolderToken: String, + params: AccountHolderEntityCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): EntityCreateResponse = + create(params.toBuilder().accountHolderToken(accountHolderToken).build(), requestOptions) + + /** @see create */ + fun create(params: AccountHolderEntityCreateParams): EntityCreateResponse = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + params: AccountHolderEntityCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): EntityCreateResponse + + /** + * Deactivate a beneficial owner entity on an existing KYB account holder. Only beneficial owner + * entities can be deactivated. + */ + fun delete(entityToken: String, params: AccountHolderEntityDeleteParams): AccountHolderEntity = + delete(entityToken, params, RequestOptions.none()) + + /** @see delete */ + fun delete( + entityToken: String, + params: AccountHolderEntityDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): AccountHolderEntity = + delete(params.toBuilder().entityToken(entityToken).build(), requestOptions) + + /** @see delete */ + fun delete(params: AccountHolderEntityDeleteParams): AccountHolderEntity = + delete(params, RequestOptions.none()) + + /** @see delete */ + fun delete( + params: AccountHolderEntityDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): AccountHolderEntity + + /** A view of [EntityService] that provides access to raw HTTP responses for each method. */ + interface WithRawResponse { + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): EntityService.WithRawResponse + + /** + * Returns a raw HTTP response for `post + * /v1/account_holders/{account_holder_token}/entities`, but is otherwise the same as + * [EntityService.create]. + */ + @MustBeClosed + fun create( + accountHolderToken: String, + params: AccountHolderEntityCreateParams, + ): HttpResponseFor = + create(accountHolderToken, params, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + accountHolderToken: String, + params: AccountHolderEntityCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create( + params.toBuilder().accountHolderToken(accountHolderToken).build(), + requestOptions, + ) + + /** @see create */ + @MustBeClosed + fun create(params: AccountHolderEntityCreateParams): HttpResponseFor = + create(params, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + params: AccountHolderEntityCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `delete + * /v1/account_holders/{account_holder_token}/entities/{entity_token}`, but is otherwise the + * same as [EntityService.delete]. + */ + @MustBeClosed + fun delete( + entityToken: String, + params: AccountHolderEntityDeleteParams, + ): HttpResponseFor = delete(entityToken, params, RequestOptions.none()) + + /** @see delete */ + @MustBeClosed + fun delete( + entityToken: String, + params: AccountHolderEntityDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + delete(params.toBuilder().entityToken(entityToken).build(), requestOptions) + + /** @see delete */ + @MustBeClosed + fun delete(params: AccountHolderEntityDeleteParams): HttpResponseFor = + delete(params, RequestOptions.none()) + + /** @see delete */ + @MustBeClosed + fun delete( + params: AccountHolderEntityDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + } +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/accountHolders/EntityServiceImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/accountHolders/EntityServiceImpl.kt new file mode 100644 index 00000000..bff41a24 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/accountHolders/EntityServiceImpl.kt @@ -0,0 +1,133 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.blocking.accountHolders + +import com.lithic.api.core.ClientOptions +import com.lithic.api.core.RequestOptions +import com.lithic.api.core.checkRequired +import com.lithic.api.core.handlers.errorBodyHandler +import com.lithic.api.core.handlers.errorHandler +import com.lithic.api.core.handlers.jsonHandler +import com.lithic.api.core.http.HttpMethod +import com.lithic.api.core.http.HttpRequest +import com.lithic.api.core.http.HttpResponse +import com.lithic.api.core.http.HttpResponse.Handler +import com.lithic.api.core.http.HttpResponseFor +import com.lithic.api.core.http.json +import com.lithic.api.core.http.parseable +import com.lithic.api.core.prepare +import com.lithic.api.models.AccountHolderEntity +import com.lithic.api.models.AccountHolderEntityCreateParams +import com.lithic.api.models.AccountHolderEntityDeleteParams +import com.lithic.api.models.EntityCreateResponse +import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull + +class EntityServiceImpl internal constructor(private val clientOptions: ClientOptions) : + EntityService { + + private val withRawResponse: EntityService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): EntityService.WithRawResponse = withRawResponse + + override fun withOptions(modifier: Consumer): EntityService = + EntityServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun create( + params: AccountHolderEntityCreateParams, + requestOptions: RequestOptions, + ): EntityCreateResponse = + // post /v1/account_holders/{account_holder_token}/entities + withRawResponse().create(params, requestOptions).parse() + + override fun delete( + params: AccountHolderEntityDeleteParams, + requestOptions: RequestOptions, + ): AccountHolderEntity = + // delete /v1/account_holders/{account_holder_token}/entities/{entity_token} + withRawResponse().delete(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + EntityService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): EntityService.WithRawResponse = + EntityServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: AccountHolderEntityCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("accountHolderToken", params.accountHolderToken().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments("v1", "account_holders", params._pathParam(0), "entities") + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val deleteHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun delete( + params: AccountHolderEntityDeleteParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("entityToken", params.entityToken().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "v1", + "account_holders", + params._pathParam(0), + "entities", + params._pathParam(1), + ) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { deleteHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/financialAccounts/InterestTierScheduleService.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/financialAccounts/InterestTierScheduleService.kt new file mode 100644 index 00000000..6b5b434a --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/financialAccounts/InterestTierScheduleService.kt @@ -0,0 +1,411 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.blocking.financialAccounts + +import com.google.errorprone.annotations.MustBeClosed +import com.lithic.api.core.ClientOptions +import com.lithic.api.core.RequestOptions +import com.lithic.api.core.http.HttpResponse +import com.lithic.api.core.http.HttpResponseFor +import com.lithic.api.models.FinancialAccountInterestTierScheduleCreateParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleDeleteParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleListPage +import com.lithic.api.models.FinancialAccountInterestTierScheduleListParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleRetrieveParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleUpdateParams +import com.lithic.api.models.InterestTierSchedule +import java.time.LocalDate +import java.util.function.Consumer + +interface InterestTierScheduleService { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): InterestTierScheduleService + + /** Create a new interest tier schedule entry for a supported financial account */ + fun create( + financialAccountToken: String, + params: FinancialAccountInterestTierScheduleCreateParams, + ): InterestTierSchedule = create(financialAccountToken, params, RequestOptions.none()) + + /** @see create */ + fun create( + financialAccountToken: String, + params: FinancialAccountInterestTierScheduleCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): InterestTierSchedule = + create( + params.toBuilder().financialAccountToken(financialAccountToken).build(), + requestOptions, + ) + + /** @see create */ + fun create(params: FinancialAccountInterestTierScheduleCreateParams): InterestTierSchedule = + create(params, RequestOptions.none()) + + /** @see create */ + fun create( + params: FinancialAccountInterestTierScheduleCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): InterestTierSchedule + + /** Get a specific interest tier schedule by effective date */ + fun retrieve( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleRetrieveParams, + ): InterestTierSchedule = retrieve(effectiveDate, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): InterestTierSchedule = + retrieve(params.toBuilder().effectiveDate(effectiveDate).build(), requestOptions) + + /** @see retrieve */ + fun retrieve(params: FinancialAccountInterestTierScheduleRetrieveParams): InterestTierSchedule = + retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: FinancialAccountInterestTierScheduleRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): InterestTierSchedule + + /** Update an existing interest tier schedule */ + fun update( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleUpdateParams, + ): InterestTierSchedule = update(effectiveDate, params, RequestOptions.none()) + + /** @see update */ + fun update( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): InterestTierSchedule = + update(params.toBuilder().effectiveDate(effectiveDate).build(), requestOptions) + + /** @see update */ + fun update(params: FinancialAccountInterestTierScheduleUpdateParams): InterestTierSchedule = + update(params, RequestOptions.none()) + + /** @see update */ + fun update( + params: FinancialAccountInterestTierScheduleUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): InterestTierSchedule + + /** + * List interest tier schedules for a financial account with optional date filtering. + * + * If no date parameters are provided, returns all tier schedules. If date parameters are + * provided, uses filtering to return matching schedules (max 100). + * - for_date: Returns exact match (takes precedence over other dates) + * - before_date: Returns schedules with effective_date <= before_date + * - after_date: Returns schedules with effective_date >= after_date + * - Both before_date and after_date: Returns schedules in range + */ + fun list(financialAccountToken: String): FinancialAccountInterestTierScheduleListPage = + list(financialAccountToken, FinancialAccountInterestTierScheduleListParams.none()) + + /** @see list */ + fun list( + financialAccountToken: String, + params: FinancialAccountInterestTierScheduleListParams = + FinancialAccountInterestTierScheduleListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): FinancialAccountInterestTierScheduleListPage = + list( + params.toBuilder().financialAccountToken(financialAccountToken).build(), + requestOptions, + ) + + /** @see list */ + fun list( + financialAccountToken: String, + params: FinancialAccountInterestTierScheduleListParams = + FinancialAccountInterestTierScheduleListParams.none(), + ): FinancialAccountInterestTierScheduleListPage = + list(financialAccountToken, params, RequestOptions.none()) + + /** @see list */ + fun list( + params: FinancialAccountInterestTierScheduleListParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): FinancialAccountInterestTierScheduleListPage + + /** @see list */ + fun list( + params: FinancialAccountInterestTierScheduleListParams + ): FinancialAccountInterestTierScheduleListPage = list(params, RequestOptions.none()) + + /** @see list */ + fun list( + financialAccountToken: String, + requestOptions: RequestOptions, + ): FinancialAccountInterestTierScheduleListPage = + list( + financialAccountToken, + FinancialAccountInterestTierScheduleListParams.none(), + requestOptions, + ) + + /** + * Delete an interest tier schedule entry. + * + * Returns: + * - 400 Bad Request: Invalid effective_date format OR attempting to delete the earliest tier + * schedule entry for a non-PENDING account + * - 404 Not Found: Tier schedule entry not found for the given effective_date OR ledger account + * not found + * + * Note: PENDING accounts can delete the earliest tier schedule entry (account hasn't opened + * yet). Active/non-PENDING accounts cannot delete the earliest entry to prevent orphaning the + * account. + * + * If the deleted tier schedule has a past effective_date and the account is ACTIVE, the loan + * tape rebuild configuration will be updated to trigger rebuilds from that date. + */ + fun delete(effectiveDate: LocalDate, params: FinancialAccountInterestTierScheduleDeleteParams) = + delete(effectiveDate, params, RequestOptions.none()) + + /** @see delete */ + fun delete( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ) = delete(params.toBuilder().effectiveDate(effectiveDate).build(), requestOptions) + + /** @see delete */ + fun delete(params: FinancialAccountInterestTierScheduleDeleteParams) = + delete(params, RequestOptions.none()) + + /** @see delete */ + fun delete( + params: FinancialAccountInterestTierScheduleDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ) + + /** + * A view of [InterestTierScheduleService] that provides access to raw HTTP responses for each + * method. + */ + interface WithRawResponse { + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions( + modifier: Consumer + ): InterestTierScheduleService.WithRawResponse + + /** + * Returns a raw HTTP response for `post + * /v1/financial_accounts/{financial_account_token}/interest_tier_schedule`, but is + * otherwise the same as [InterestTierScheduleService.create]. + */ + @MustBeClosed + fun create( + financialAccountToken: String, + params: FinancialAccountInterestTierScheduleCreateParams, + ): HttpResponseFor = + create(financialAccountToken, params, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + financialAccountToken: String, + params: FinancialAccountInterestTierScheduleCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + create( + params.toBuilder().financialAccountToken(financialAccountToken).build(), + requestOptions, + ) + + /** @see create */ + @MustBeClosed + fun create( + params: FinancialAccountInterestTierScheduleCreateParams + ): HttpResponseFor = create(params, RequestOptions.none()) + + /** @see create */ + @MustBeClosed + fun create( + params: FinancialAccountInterestTierScheduleCreateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get + * /v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}`, + * but is otherwise the same as [InterestTierScheduleService.retrieve]. + */ + @MustBeClosed + fun retrieve( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleRetrieveParams, + ): HttpResponseFor = + retrieve(effectiveDate, params, RequestOptions.none()) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve(params.toBuilder().effectiveDate(effectiveDate).build(), requestOptions) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + params: FinancialAccountInterestTierScheduleRetrieveParams + ): HttpResponseFor = retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + params: FinancialAccountInterestTierScheduleRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `put + * /v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}`, + * but is otherwise the same as [InterestTierScheduleService.update]. + */ + @MustBeClosed + fun update( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleUpdateParams, + ): HttpResponseFor = + update(effectiveDate, params, RequestOptions.none()) + + /** @see update */ + @MustBeClosed + fun update( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + update(params.toBuilder().effectiveDate(effectiveDate).build(), requestOptions) + + /** @see update */ + @MustBeClosed + fun update( + params: FinancialAccountInterestTierScheduleUpdateParams + ): HttpResponseFor = update(params, RequestOptions.none()) + + /** @see update */ + @MustBeClosed + fun update( + params: FinancialAccountInterestTierScheduleUpdateParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** + * Returns a raw HTTP response for `get + * /v1/financial_accounts/{financial_account_token}/interest_tier_schedule`, but is + * otherwise the same as [InterestTierScheduleService.list]. + */ + @MustBeClosed + fun list( + financialAccountToken: String + ): HttpResponseFor = + list(financialAccountToken, FinancialAccountInterestTierScheduleListParams.none()) + + /** @see list */ + @MustBeClosed + fun list( + financialAccountToken: String, + params: FinancialAccountInterestTierScheduleListParams = + FinancialAccountInterestTierScheduleListParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + list( + params.toBuilder().financialAccountToken(financialAccountToken).build(), + requestOptions, + ) + + /** @see list */ + @MustBeClosed + fun list( + financialAccountToken: String, + params: FinancialAccountInterestTierScheduleListParams = + FinancialAccountInterestTierScheduleListParams.none(), + ): HttpResponseFor = + list(financialAccountToken, params, RequestOptions.none()) + + /** @see list */ + @MustBeClosed + fun list( + params: FinancialAccountInterestTierScheduleListParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see list */ + @MustBeClosed + fun list( + params: FinancialAccountInterestTierScheduleListParams + ): HttpResponseFor = + list(params, RequestOptions.none()) + + /** @see list */ + @MustBeClosed + fun list( + financialAccountToken: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + list( + financialAccountToken, + FinancialAccountInterestTierScheduleListParams.none(), + requestOptions, + ) + + /** + * Returns a raw HTTP response for `delete + * /v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date}`, + * but is otherwise the same as [InterestTierScheduleService.delete]. + */ + @MustBeClosed + fun delete( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleDeleteParams, + ): HttpResponse = delete(effectiveDate, params, RequestOptions.none()) + + /** @see delete */ + @MustBeClosed + fun delete( + effectiveDate: LocalDate, + params: FinancialAccountInterestTierScheduleDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse = + delete(params.toBuilder().effectiveDate(effectiveDate).build(), requestOptions) + + /** @see delete */ + @MustBeClosed + fun delete(params: FinancialAccountInterestTierScheduleDeleteParams): HttpResponse = + delete(params, RequestOptions.none()) + + /** @see delete */ + @MustBeClosed + fun delete( + params: FinancialAccountInterestTierScheduleDeleteParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponse + } +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/financialAccounts/InterestTierScheduleServiceImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/financialAccounts/InterestTierScheduleServiceImpl.kt new file mode 100644 index 00000000..e50de894 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/financialAccounts/InterestTierScheduleServiceImpl.kt @@ -0,0 +1,280 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.blocking.financialAccounts + +import com.lithic.api.core.ClientOptions +import com.lithic.api.core.RequestOptions +import com.lithic.api.core.checkRequired +import com.lithic.api.core.handlers.emptyHandler +import com.lithic.api.core.handlers.errorBodyHandler +import com.lithic.api.core.handlers.errorHandler +import com.lithic.api.core.handlers.jsonHandler +import com.lithic.api.core.http.HttpMethod +import com.lithic.api.core.http.HttpRequest +import com.lithic.api.core.http.HttpResponse +import com.lithic.api.core.http.HttpResponse.Handler +import com.lithic.api.core.http.HttpResponseFor +import com.lithic.api.core.http.json +import com.lithic.api.core.http.parseable +import com.lithic.api.core.prepare +import com.lithic.api.models.FinancialAccountInterestTierScheduleCreateParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleDeleteParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleListPage +import com.lithic.api.models.FinancialAccountInterestTierScheduleListPageResponse +import com.lithic.api.models.FinancialAccountInterestTierScheduleListParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleRetrieveParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleUpdateParams +import com.lithic.api.models.InterestTierSchedule +import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull + +class InterestTierScheduleServiceImpl +internal constructor(private val clientOptions: ClientOptions) : InterestTierScheduleService { + + private val withRawResponse: InterestTierScheduleService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): InterestTierScheduleService.WithRawResponse = withRawResponse + + override fun withOptions( + modifier: Consumer + ): InterestTierScheduleService = + InterestTierScheduleServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun create( + params: FinancialAccountInterestTierScheduleCreateParams, + requestOptions: RequestOptions, + ): InterestTierSchedule = + // post /v1/financial_accounts/{financial_account_token}/interest_tier_schedule + withRawResponse().create(params, requestOptions).parse() + + override fun retrieve( + params: FinancialAccountInterestTierScheduleRetrieveParams, + requestOptions: RequestOptions, + ): InterestTierSchedule = + // get + // /v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date} + withRawResponse().retrieve(params, requestOptions).parse() + + override fun update( + params: FinancialAccountInterestTierScheduleUpdateParams, + requestOptions: RequestOptions, + ): InterestTierSchedule = + // put + // /v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date} + withRawResponse().update(params, requestOptions).parse() + + override fun list( + params: FinancialAccountInterestTierScheduleListParams, + requestOptions: RequestOptions, + ): FinancialAccountInterestTierScheduleListPage = + // get /v1/financial_accounts/{financial_account_token}/interest_tier_schedule + withRawResponse().list(params, requestOptions).parse() + + override fun delete( + params: FinancialAccountInterestTierScheduleDeleteParams, + requestOptions: RequestOptions, + ) { + // delete + // /v1/financial_accounts/{financial_account_token}/interest_tier_schedule/{effective_date} + withRawResponse().delete(params, requestOptions) + } + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + InterestTierScheduleService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): InterestTierScheduleService.WithRawResponse = + InterestTierScheduleServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val createHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun create( + params: FinancialAccountInterestTierScheduleCreateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("financialAccountToken", params.financialAccountToken().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.POST) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "v1", + "financial_accounts", + params._pathParam(0), + "interest_tier_schedule", + ) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { createHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun retrieve( + params: FinancialAccountInterestTierScheduleRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("effectiveDate", params.effectiveDate().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "v1", + "financial_accounts", + params._pathParam(0), + "interest_tier_schedule", + params._pathParam(1), + ) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val updateHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun update( + params: FinancialAccountInterestTierScheduleUpdateParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("effectiveDate", params.effectiveDate().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.PUT) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "v1", + "financial_accounts", + params._pathParam(0), + "interest_tier_schedule", + params._pathParam(1), + ) + .body(json(clientOptions.jsonMapper, params._body())) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { updateHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + + private val listHandler: Handler = + jsonHandler( + clientOptions.jsonMapper + ) + + override fun list( + params: FinancialAccountInterestTierScheduleListParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("financialAccountToken", params.financialAccountToken().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "v1", + "financial_accounts", + params._pathParam(0), + "interest_tier_schedule", + ) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { listHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + .let { + FinancialAccountInterestTierScheduleListPage.builder() + .service(InterestTierScheduleServiceImpl(clientOptions)) + .params(params) + .response(it) + .build() + } + } + } + + private val deleteHandler: Handler = emptyHandler() + + override fun delete( + params: FinancialAccountInterestTierScheduleDeleteParams, + requestOptions: RequestOptions, + ): HttpResponse { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("effectiveDate", params.effectiveDate().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.DELETE) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "v1", + "financial_accounts", + params._pathParam(0), + "interest_tier_schedule", + params._pathParam(1), + ) + .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response.use { deleteHandler.handle(it) } + } + } + } +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/financialAccounts/LoanTapeConfigurationService.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/financialAccounts/LoanTapeConfigurationService.kt new file mode 100644 index 00000000..ef462669 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/financialAccounts/LoanTapeConfigurationService.kt @@ -0,0 +1,146 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.blocking.financialAccounts + +import com.google.errorprone.annotations.MustBeClosed +import com.lithic.api.core.ClientOptions +import com.lithic.api.core.RequestOptions +import com.lithic.api.core.http.HttpResponseFor +import com.lithic.api.models.FinancialAccountLoanTapeConfigurationRetrieveParams +import com.lithic.api.models.LoanTapeConfiguration +import java.util.function.Consumer + +interface LoanTapeConfigurationService { + + /** + * Returns a view of this service that provides access to raw HTTP responses for each method. + */ + fun withRawResponse(): WithRawResponse + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions(modifier: Consumer): LoanTapeConfigurationService + + /** Get the loan tape configuration for a given financial account. */ + fun retrieve(financialAccountToken: String): LoanTapeConfiguration = + retrieve(financialAccountToken, FinancialAccountLoanTapeConfigurationRetrieveParams.none()) + + /** @see retrieve */ + fun retrieve( + financialAccountToken: String, + params: FinancialAccountLoanTapeConfigurationRetrieveParams = + FinancialAccountLoanTapeConfigurationRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): LoanTapeConfiguration = + retrieve( + params.toBuilder().financialAccountToken(financialAccountToken).build(), + requestOptions, + ) + + /** @see retrieve */ + fun retrieve( + financialAccountToken: String, + params: FinancialAccountLoanTapeConfigurationRetrieveParams = + FinancialAccountLoanTapeConfigurationRetrieveParams.none(), + ): LoanTapeConfiguration = retrieve(financialAccountToken, params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + params: FinancialAccountLoanTapeConfigurationRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): LoanTapeConfiguration + + /** @see retrieve */ + fun retrieve( + params: FinancialAccountLoanTapeConfigurationRetrieveParams + ): LoanTapeConfiguration = retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + fun retrieve( + financialAccountToken: String, + requestOptions: RequestOptions, + ): LoanTapeConfiguration = + retrieve( + financialAccountToken, + FinancialAccountLoanTapeConfigurationRetrieveParams.none(), + requestOptions, + ) + + /** + * A view of [LoanTapeConfigurationService] that provides access to raw HTTP responses for each + * method. + */ + interface WithRawResponse { + + /** + * Returns a view of this service with the given option modifications applied. + * + * The original service is not modified. + */ + fun withOptions( + modifier: Consumer + ): LoanTapeConfigurationService.WithRawResponse + + /** + * Returns a raw HTTP response for `get + * /v1/financial_accounts/{financial_account_token}/loan_tape_configuration`, but is + * otherwise the same as [LoanTapeConfigurationService.retrieve]. + */ + @MustBeClosed + fun retrieve(financialAccountToken: String): HttpResponseFor = + retrieve( + financialAccountToken, + FinancialAccountLoanTapeConfigurationRetrieveParams.none(), + ) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + financialAccountToken: String, + params: FinancialAccountLoanTapeConfigurationRetrieveParams = + FinancialAccountLoanTapeConfigurationRetrieveParams.none(), + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor = + retrieve( + params.toBuilder().financialAccountToken(financialAccountToken).build(), + requestOptions, + ) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + financialAccountToken: String, + params: FinancialAccountLoanTapeConfigurationRetrieveParams = + FinancialAccountLoanTapeConfigurationRetrieveParams.none(), + ): HttpResponseFor = + retrieve(financialAccountToken, params, RequestOptions.none()) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + params: FinancialAccountLoanTapeConfigurationRetrieveParams, + requestOptions: RequestOptions = RequestOptions.none(), + ): HttpResponseFor + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + params: FinancialAccountLoanTapeConfigurationRetrieveParams + ): HttpResponseFor = retrieve(params, RequestOptions.none()) + + /** @see retrieve */ + @MustBeClosed + fun retrieve( + financialAccountToken: String, + requestOptions: RequestOptions, + ): HttpResponseFor = + retrieve( + financialAccountToken, + FinancialAccountLoanTapeConfigurationRetrieveParams.none(), + requestOptions, + ) + } +} diff --git a/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/financialAccounts/LoanTapeConfigurationServiceImpl.kt b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/financialAccounts/LoanTapeConfigurationServiceImpl.kt new file mode 100644 index 00000000..d7070036 --- /dev/null +++ b/lithic-java-core/src/main/kotlin/com/lithic/api/services/blocking/financialAccounts/LoanTapeConfigurationServiceImpl.kt @@ -0,0 +1,92 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.blocking.financialAccounts + +import com.lithic.api.core.ClientOptions +import com.lithic.api.core.RequestOptions +import com.lithic.api.core.checkRequired +import com.lithic.api.core.handlers.errorBodyHandler +import com.lithic.api.core.handlers.errorHandler +import com.lithic.api.core.handlers.jsonHandler +import com.lithic.api.core.http.HttpMethod +import com.lithic.api.core.http.HttpRequest +import com.lithic.api.core.http.HttpResponse +import com.lithic.api.core.http.HttpResponse.Handler +import com.lithic.api.core.http.HttpResponseFor +import com.lithic.api.core.http.parseable +import com.lithic.api.core.prepare +import com.lithic.api.models.FinancialAccountLoanTapeConfigurationRetrieveParams +import com.lithic.api.models.LoanTapeConfiguration +import java.util.function.Consumer +import kotlin.jvm.optionals.getOrNull + +class LoanTapeConfigurationServiceImpl +internal constructor(private val clientOptions: ClientOptions) : LoanTapeConfigurationService { + + private val withRawResponse: LoanTapeConfigurationService.WithRawResponse by lazy { + WithRawResponseImpl(clientOptions) + } + + override fun withRawResponse(): LoanTapeConfigurationService.WithRawResponse = withRawResponse + + override fun withOptions( + modifier: Consumer + ): LoanTapeConfigurationService = + LoanTapeConfigurationServiceImpl(clientOptions.toBuilder().apply(modifier::accept).build()) + + override fun retrieve( + params: FinancialAccountLoanTapeConfigurationRetrieveParams, + requestOptions: RequestOptions, + ): LoanTapeConfiguration = + // get /v1/financial_accounts/{financial_account_token}/loan_tape_configuration + withRawResponse().retrieve(params, requestOptions).parse() + + class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) : + LoanTapeConfigurationService.WithRawResponse { + + private val errorHandler: Handler = + errorHandler(errorBodyHandler(clientOptions.jsonMapper)) + + override fun withOptions( + modifier: Consumer + ): LoanTapeConfigurationService.WithRawResponse = + LoanTapeConfigurationServiceImpl.WithRawResponseImpl( + clientOptions.toBuilder().apply(modifier::accept).build() + ) + + private val retrieveHandler: Handler = + jsonHandler(clientOptions.jsonMapper) + + override fun retrieve( + params: FinancialAccountLoanTapeConfigurationRetrieveParams, + requestOptions: RequestOptions, + ): HttpResponseFor { + // We check here instead of in the params builder because this can be specified + // positionally or in the params class. + checkRequired("financialAccountToken", params.financialAccountToken().getOrNull()) + val request = + HttpRequest.builder() + .method(HttpMethod.GET) + .baseUrl(clientOptions.baseUrl()) + .addPathSegments( + "v1", + "financial_accounts", + params._pathParam(0), + "loan_tape_configuration", + ) + .build() + .prepare(clientOptions, params) + val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) + val response = clientOptions.httpClient.execute(request, requestOptions) + return errorHandler.handle(response).parseable { + response + .use { retrieveHandler.handle(it) } + .also { + if (requestOptions.responseValidation!!) { + it.validate() + } + } + } + } + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/core/http/HttpRequestBodiesTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/core/http/HttpRequestBodiesTest.kt new file mode 100644 index 00000000..95c05301 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/core/http/HttpRequestBodiesTest.kt @@ -0,0 +1,729 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.core.http + +import com.lithic.api.core.MultipartField +import com.lithic.api.core.jsonMapper +import java.io.ByteArrayOutputStream +import java.io.InputStream +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class HttpRequestBodiesTest { + + @Test + fun multipartFormData_serializesFieldWithFilename() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "file" to + MultipartField.builder() + .value("hello") + .filename("hello.txt") + .contentType("text/plain") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(output.size().toLong()).isEqualTo(body.contentLength()) + val boundary = body.contentType()!!.substringAfter("multipart/form-data; boundary=") + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="file"; filename="hello.txt" + |Content-Type: text/plain + | + |hello + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesFieldWithoutFilename() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "field" to + MultipartField.builder() + .value("value") + .contentType("text/plain") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(output.size().toLong()).isEqualTo(body.contentLength()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="field" + |Content-Type: text/plain + | + |value + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesInputStream() { + // Use `.buffered()` to get a non-ByteArrayInputStream, which hits the non-repeatable code + // path. + val inputStream = "stream content".byteInputStream().buffered() + val body = + multipartFormData( + jsonMapper(), + mapOf( + "data" to + MultipartField.builder() + .value(inputStream) + .contentType("application/octet-stream") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isFalse() + assertThat(body.contentLength()).isEqualTo(-1L) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="data" + |Content-Type: application/octet-stream + | + |stream content + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesByteArray() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "binary" to + MultipartField.builder() + .value("abc".toByteArray()) + .contentType("application/octet-stream") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="binary" + |Content-Type: application/octet-stream + | + |abc + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesBooleanValue() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "flag" to + MultipartField.builder() + .value(true) + .contentType("text/plain") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="flag" + |Content-Type: text/plain + | + |true + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesNumberValue() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "count" to + MultipartField.builder().value(42).contentType("text/plain").build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="count" + |Content-Type: text/plain + | + |42 + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesNullValueAsNoParts() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "present" to + MultipartField.builder() + .value("yes") + .contentType("text/plain") + .build(), + "absent" to + MultipartField.builder() + .value(null as String?) + .contentType("text/plain") + .build(), + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="present" + |Content-Type: text/plain + | + |yes + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesArray() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "items" to + MultipartField.builder>() + .value(listOf("alpha", "beta", "gamma")) + .contentType("text/plain") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="items" + |Content-Type: text/plain + | + |alpha,beta,gamma + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesObjectAsNestedParts() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "meta" to + MultipartField.builder>() + .value(mapOf("key1" to "val1", "key2" to "val2")) + .contentType("text/plain") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="meta[key1]" + |Content-Type: text/plain + | + |val1 + |--$boundary + |Content-Disposition: form-data; name="meta[key2]" + |Content-Type: text/plain + | + |val2 + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesMultipleFields() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "name" to + MultipartField.builder() + .value("Alice") + .contentType("text/plain") + .build(), + "age" to + MultipartField.builder().value(30).contentType("text/plain").build(), + "file" to + MultipartField.builder() + .value("file contents") + .filename("doc.txt") + .contentType("text/plain") + .build(), + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="name" + |Content-Type: text/plain + | + |Alice + |--$boundary + |Content-Disposition: form-data; name="age" + |Content-Type: text/plain + | + |30 + |--$boundary + |Content-Disposition: form-data; name="file"; filename="doc.txt" + |Content-Type: text/plain + | + |file contents + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_quotesSpecialCharactersInNameAndFilename() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "field\nname" to + MultipartField.builder() + .value("value") + .filename("file\r\"name.txt") + .contentType("text/plain") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="field%0Aname"; filename="file%0D%22name.txt" + |Content-Type: text/plain + | + |value + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_writeIsRepeatable() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "field" to + MultipartField.builder() + .value("repeatable") + .contentType("text/plain") + .build() + ), + ) + + val output1 = ByteArrayOutputStream() + body.writeTo(output1) + val output2 = ByteArrayOutputStream() + body.writeTo(output2) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output1.size().toLong()) + val boundary = boundary(body) + val expected = + """ + |--$boundary + |Content-Disposition: form-data; name="field" + |Content-Type: text/plain + | + |repeatable + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + assertThat(output1.toString("UTF-8")).isEqualTo(expected) + assertThat(output2.toString("UTF-8")).isEqualTo(expected) + } + + @Test + fun multipartFormData_serializesByteArrayInputStream() { + // ByteArrayInputStream is specifically handled as repeatable with known content length. + val inputStream = "byte array stream".byteInputStream() + val body = + multipartFormData( + jsonMapper(), + mapOf( + "data" to + MultipartField.builder() + .value(inputStream) + .contentType("application/octet-stream") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="data" + |Content-Type: application/octet-stream + | + |byte array stream + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesInputStreamWithFilename() { + // Use `.buffered()` to get a non-ByteArrayInputStream, which hits the non-repeatable code + // path. + val inputStream = "file data".byteInputStream().buffered() + val body = + multipartFormData( + jsonMapper(), + mapOf( + "upload" to + MultipartField.builder() + .value(inputStream) + .filename("upload.bin") + .contentType("application/octet-stream") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isFalse() + assertThat(body.contentLength()).isEqualTo(-1L) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="upload"; filename="upload.bin" + |Content-Type: application/octet-stream + | + |file data + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesNestedArrayInObject() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "data" to + MultipartField.builder>>() + .value(mapOf("tags" to listOf("a", "b"))) + .contentType("text/plain") + .build() + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="data[tags]" + |Content-Type: text/plain + | + |a,b + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_contentLengthIsUnknownWhenInputStreamPresent() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "text" to + MultipartField.builder() + .value("hello") + .contentType("text/plain") + .build(), + "stream" to + MultipartField.builder() + // Use `.buffered()` to get a non-ByteArrayInputStream, which hits the + // non-repeatable code path. + .value("data".byteInputStream().buffered()) + .contentType("application/octet-stream") + .build(), + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isFalse() + assertThat(body.contentLength()).isEqualTo(-1L) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="text" + |Content-Type: text/plain + | + |hello + |--$boundary + |Content-Disposition: form-data; name="stream" + |Content-Type: application/octet-stream + | + |data + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesEmptyArray() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "required" to + MultipartField.builder() + .value("present") + .contentType("text/plain") + .build(), + "items" to + MultipartField.builder>() + .value(emptyList()) + .contentType("text/plain") + .build(), + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="required" + |Content-Type: text/plain + | + |present + |--$boundary + |Content-Disposition: form-data; name="items" + |Content-Type: text/plain + | + | + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + @Test + fun multipartFormData_serializesEmptyObject() { + val body = + multipartFormData( + jsonMapper(), + mapOf( + "required" to + MultipartField.builder() + .value("present") + .contentType("text/plain") + .build(), + "meta" to + MultipartField.builder>() + .value(emptyMap()) + .contentType("text/plain") + .build(), + ), + ) + + val output = ByteArrayOutputStream() + body.writeTo(output) + + assertThat(body.repeatable()).isTrue() + assertThat(body.contentLength()).isEqualTo(output.size().toLong()) + val boundary = boundary(body) + assertThat(output.toString("UTF-8")) + .isEqualTo( + """ + |--$boundary + |Content-Disposition: form-data; name="required" + |Content-Type: text/plain + | + |present + |--$boundary-- + | + """ + .trimMargin() + .replace("\n", "\r\n") + ) + } + + private fun boundary(body: HttpRequestBody): String = + body.contentType()!!.substringAfter("multipart/form-data; boundary=") +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/core/http/RetryingHttpClientTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/core/http/RetryingHttpClientTest.kt index 29d7ab18..58cde824 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/core/http/RetryingHttpClientTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/core/http/RetryingHttpClientTest.kt @@ -1,6 +1,17 @@ +// File generated from our OpenAPI spec by Stainless. + package com.lithic.api.core.http -import com.github.tomakehurst.wiremock.client.WireMock.* +import com.github.tomakehurst.wiremock.client.WireMock.equalTo +import com.github.tomakehurst.wiremock.client.WireMock.matching +import com.github.tomakehurst.wiremock.client.WireMock.ok +import com.github.tomakehurst.wiremock.client.WireMock.post +import com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor +import com.github.tomakehurst.wiremock.client.WireMock.resetAllScenarios +import com.github.tomakehurst.wiremock.client.WireMock.serviceUnavailable +import com.github.tomakehurst.wiremock.client.WireMock.stubFor +import com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo +import com.github.tomakehurst.wiremock.client.WireMock.verify import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo import com.github.tomakehurst.wiremock.junit5.WireMockTest import com.github.tomakehurst.wiremock.stubbing.Scenario diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderEntityCreateParamsTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderEntityCreateParamsTest.kt new file mode 100644 index 00000000..ed13568d --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderEntityCreateParamsTest.kt @@ -0,0 +1,153 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class AccountHolderEntityCreateParamsTest { + + @Test + fun create() { + AccountHolderEntityCreateParams.builder() + .accountHolderToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .address( + AccountHolderEntityCreateParams.Address.builder() + .address1("300 Normal Forest Way") + .city("Portland") + .country("USA") + .postalCode("90210") + .state("OR") + .address2("address2") + .build() + ) + .dob("1991-03-08T08:00:00Z") + .email("tim@left-earth.com") + .firstName("Timmy") + .governmentId("211-23-1412") + .lastName("Turner") + .phoneNumber("+15555555555") + .type(AccountHolderEntityCreateParams.EntityType.BENEFICIAL_OWNER_INDIVIDUAL) + .build() + } + + @Test + fun pathParams() { + val params = + AccountHolderEntityCreateParams.builder() + .accountHolderToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .address( + AccountHolderEntityCreateParams.Address.builder() + .address1("300 Normal Forest Way") + .city("Portland") + .country("USA") + .postalCode("90210") + .state("OR") + .build() + ) + .dob("1991-03-08T08:00:00Z") + .email("tim@left-earth.com") + .firstName("Timmy") + .governmentId("211-23-1412") + .lastName("Turner") + .phoneNumber("+15555555555") + .type(AccountHolderEntityCreateParams.EntityType.BENEFICIAL_OWNER_INDIVIDUAL) + .build() + + assertThat(params._pathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun body() { + val params = + AccountHolderEntityCreateParams.builder() + .accountHolderToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .address( + AccountHolderEntityCreateParams.Address.builder() + .address1("300 Normal Forest Way") + .city("Portland") + .country("USA") + .postalCode("90210") + .state("OR") + .address2("address2") + .build() + ) + .dob("1991-03-08T08:00:00Z") + .email("tim@left-earth.com") + .firstName("Timmy") + .governmentId("211-23-1412") + .lastName("Turner") + .phoneNumber("+15555555555") + .type(AccountHolderEntityCreateParams.EntityType.BENEFICIAL_OWNER_INDIVIDUAL) + .build() + + val body = params._body() + + assertThat(body.address()) + .isEqualTo( + AccountHolderEntityCreateParams.Address.builder() + .address1("300 Normal Forest Way") + .city("Portland") + .country("USA") + .postalCode("90210") + .state("OR") + .address2("address2") + .build() + ) + assertThat(body.dob()).isEqualTo("1991-03-08T08:00:00Z") + assertThat(body.email()).isEqualTo("tim@left-earth.com") + assertThat(body.firstName()).isEqualTo("Timmy") + assertThat(body.governmentId()).isEqualTo("211-23-1412") + assertThat(body.lastName()).isEqualTo("Turner") + assertThat(body.phoneNumber()).isEqualTo("+15555555555") + assertThat(body.type()) + .isEqualTo(AccountHolderEntityCreateParams.EntityType.BENEFICIAL_OWNER_INDIVIDUAL) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + AccountHolderEntityCreateParams.builder() + .accountHolderToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .address( + AccountHolderEntityCreateParams.Address.builder() + .address1("300 Normal Forest Way") + .city("Portland") + .country("USA") + .postalCode("90210") + .state("OR") + .build() + ) + .dob("1991-03-08T08:00:00Z") + .email("tim@left-earth.com") + .firstName("Timmy") + .governmentId("211-23-1412") + .lastName("Turner") + .phoneNumber("+15555555555") + .type(AccountHolderEntityCreateParams.EntityType.BENEFICIAL_OWNER_INDIVIDUAL) + .build() + + val body = params._body() + + assertThat(body.address()) + .isEqualTo( + AccountHolderEntityCreateParams.Address.builder() + .address1("300 Normal Forest Way") + .city("Portland") + .country("USA") + .postalCode("90210") + .state("OR") + .build() + ) + assertThat(body.dob()).isEqualTo("1991-03-08T08:00:00Z") + assertThat(body.email()).isEqualTo("tim@left-earth.com") + assertThat(body.firstName()).isEqualTo("Timmy") + assertThat(body.governmentId()).isEqualTo("211-23-1412") + assertThat(body.lastName()).isEqualTo("Turner") + assertThat(body.phoneNumber()).isEqualTo("+15555555555") + assertThat(body.type()) + .isEqualTo(AccountHolderEntityCreateParams.EntityType.BENEFICIAL_OWNER_INDIVIDUAL) + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderEntityDeleteParamsTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderEntityDeleteParamsTest.kt new file mode 100644 index 00000000..37677ac6 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderEntityDeleteParamsTest.kt @@ -0,0 +1,31 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class AccountHolderEntityDeleteParamsTest { + + @Test + fun create() { + AccountHolderEntityDeleteParams.builder() + .accountHolderToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .entityToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + } + + @Test + fun pathParams() { + val params = + AccountHolderEntityDeleteParams.builder() + .accountHolderToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .entityToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + + assertThat(params._pathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(params._pathParam(1)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + // out-of-bound path param + assertThat(params._pathParam(2)).isEqualTo("") + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderEntityTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderEntityTest.kt new file mode 100644 index 00000000..f75d9091 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/AccountHolderEntityTest.kt @@ -0,0 +1,96 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.lithic.api.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class AccountHolderEntityTest { + + @Test + fun create() { + val accountHolderEntity = + AccountHolderEntity.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .accountHolderToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .address( + AccountHolderEntity.Address.builder() + .address1("123 Old Forest Way") + .city("Omaha") + .country("USA") + .postalCode("68022") + .state("NE") + .address2("address2") + .build() + ) + .dob("1991-03-08 08:00:00") + .email("tom@middle-earth.com") + .firstName("Tom") + .lastName("Bombadil") + .phoneNumber("+15555555555") + .status(AccountHolderEntity.EntityStatus.ACCEPTED) + .type(AccountHolderEntity.EntityType.BENEFICIAL_OWNER_INDIVIDUAL) + .build() + + assertThat(accountHolderEntity.token()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(accountHolderEntity.accountHolderToken()) + .isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(accountHolderEntity.address()) + .isEqualTo( + AccountHolderEntity.Address.builder() + .address1("123 Old Forest Way") + .city("Omaha") + .country("USA") + .postalCode("68022") + .state("NE") + .address2("address2") + .build() + ) + assertThat(accountHolderEntity.dob()).contains("1991-03-08 08:00:00") + assertThat(accountHolderEntity.email()).contains("tom@middle-earth.com") + assertThat(accountHolderEntity.firstName()).contains("Tom") + assertThat(accountHolderEntity.lastName()).contains("Bombadil") + assertThat(accountHolderEntity.phoneNumber()).contains("+15555555555") + assertThat(accountHolderEntity.status()) + .isEqualTo(AccountHolderEntity.EntityStatus.ACCEPTED) + assertThat(accountHolderEntity.type()) + .isEqualTo(AccountHolderEntity.EntityType.BENEFICIAL_OWNER_INDIVIDUAL) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val accountHolderEntity = + AccountHolderEntity.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .accountHolderToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .address( + AccountHolderEntity.Address.builder() + .address1("123 Old Forest Way") + .city("Omaha") + .country("USA") + .postalCode("68022") + .state("NE") + .address2("address2") + .build() + ) + .dob("1991-03-08 08:00:00") + .email("tom@middle-earth.com") + .firstName("Tom") + .lastName("Bombadil") + .phoneNumber("+15555555555") + .status(AccountHolderEntity.EntityStatus.ACCEPTED) + .type(AccountHolderEntity.EntityType.BENEFICIAL_OWNER_INDIVIDUAL) + .build() + + val roundtrippedAccountHolderEntity = + jsonMapper.readValue( + jsonMapper.writeValueAsString(accountHolderEntity), + jacksonTypeRef(), + ) + + assertThat(roundtrippedAccountHolderEntity).isEqualTo(accountHolderEntity) + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/CategoryTierTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/CategoryTierTest.kt new file mode 100644 index 00000000..79e32c1c --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/CategoryTierTest.kt @@ -0,0 +1,33 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.lithic.api.core.jsonMapper +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class CategoryTierTest { + + @Test + fun create() { + val categoryTier = CategoryTier.builder().capRate("cap_rate").rate("rate").build() + + assertThat(categoryTier.capRate()).contains("cap_rate") + assertThat(categoryTier.rate()).contains("rate") + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val categoryTier = CategoryTier.builder().capRate("cap_rate").rate("rate").build() + + val roundtrippedCategoryTier = + jsonMapper.readValue( + jsonMapper.writeValueAsString(categoryTier), + jacksonTypeRef(), + ) + + assertThat(roundtrippedCategoryTier).isEqualTo(categoryTier) + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/EntityCreateResponseTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/EntityCreateResponseTest.kt new file mode 100644 index 00000000..ab8ce669 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/EntityCreateResponseTest.kt @@ -0,0 +1,77 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.lithic.api.core.jsonMapper +import java.time.OffsetDateTime +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class EntityCreateResponseTest { + + @Test + fun create() { + val entityCreateResponse = + EntityCreateResponse.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .accountHolderToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .addRequiredDocument( + RequiredDocument.builder() + .entityToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addStatusReason("string") + .addValidDocument("string") + .build() + ) + .status(EntityCreateResponse.EntityStatus.ACCEPTED) + .addStatusReason(EntityCreateResponse.StatusReasons.ADDRESS_VERIFICATION_FAILURE) + .build() + + assertThat(entityCreateResponse.token()).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(entityCreateResponse.accountHolderToken()) + .isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(entityCreateResponse.created()) + .isEqualTo(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + assertThat(entityCreateResponse.requiredDocuments()) + .containsExactly( + RequiredDocument.builder() + .entityToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addStatusReason("string") + .addValidDocument("string") + .build() + ) + assertThat(entityCreateResponse.status()) + .isEqualTo(EntityCreateResponse.EntityStatus.ACCEPTED) + assertThat(entityCreateResponse.statusReasons()) + .containsExactly(EntityCreateResponse.StatusReasons.ADDRESS_VERIFICATION_FAILURE) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val entityCreateResponse = + EntityCreateResponse.builder() + .token("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .accountHolderToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .created(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .addRequiredDocument( + RequiredDocument.builder() + .entityToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .addStatusReason("string") + .addValidDocument("string") + .build() + ) + .status(EntityCreateResponse.EntityStatus.ACCEPTED) + .addStatusReason(EntityCreateResponse.StatusReasons.ADDRESS_VERIFICATION_FAILURE) + .build() + + val roundtrippedEntityCreateResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(entityCreateResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedEntityCreateResponse).isEqualTo(entityCreateResponse) + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleCreateParamsTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleCreateParamsTest.kt new file mode 100644 index 00000000..86b85cfc --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleCreateParamsTest.kt @@ -0,0 +1,96 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.lithic.api.core.JsonValue +import java.time.LocalDate +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class FinancialAccountInterestTierScheduleCreateParamsTest { + + @Test + fun create() { + FinancialAccountInterestTierScheduleCreateParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .interestTierSchedule( + InterestTierSchedule.builder() + .creditProductToken("credit_product_token") + .effectiveDate(LocalDate.parse("2019-12-27")) + .tierName("tier_name") + .tierRates(JsonValue.from(mapOf())) + .build() + ) + .build() + } + + @Test + fun pathParams() { + val params = + FinancialAccountInterestTierScheduleCreateParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .interestTierSchedule( + InterestTierSchedule.builder() + .creditProductToken("credit_product_token") + .effectiveDate(LocalDate.parse("2019-12-27")) + .build() + ) + .build() + + assertThat(params._pathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun body() { + val params = + FinancialAccountInterestTierScheduleCreateParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .interestTierSchedule( + InterestTierSchedule.builder() + .creditProductToken("credit_product_token") + .effectiveDate(LocalDate.parse("2019-12-27")) + .tierName("tier_name") + .tierRates(JsonValue.from(mapOf())) + .build() + ) + .build() + + val body = params._body() + + assertThat(body) + .isEqualTo( + InterestTierSchedule.builder() + .creditProductToken("credit_product_token") + .effectiveDate(LocalDate.parse("2019-12-27")) + .tierName("tier_name") + .tierRates(JsonValue.from(mapOf())) + .build() + ) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + FinancialAccountInterestTierScheduleCreateParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .interestTierSchedule( + InterestTierSchedule.builder() + .creditProductToken("credit_product_token") + .effectiveDate(LocalDate.parse("2019-12-27")) + .build() + ) + .build() + + val body = params._body() + + assertThat(body) + .isEqualTo( + InterestTierSchedule.builder() + .creditProductToken("credit_product_token") + .effectiveDate(LocalDate.parse("2019-12-27")) + .build() + ) + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleDeleteParamsTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleDeleteParamsTest.kt new file mode 100644 index 00000000..c4d13a45 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleDeleteParamsTest.kt @@ -0,0 +1,32 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import java.time.LocalDate +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class FinancialAccountInterestTierScheduleDeleteParamsTest { + + @Test + fun create() { + FinancialAccountInterestTierScheduleDeleteParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .effectiveDate(LocalDate.parse("2019-12-27")) + .build() + } + + @Test + fun pathParams() { + val params = + FinancialAccountInterestTierScheduleDeleteParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .effectiveDate(LocalDate.parse("2019-12-27")) + .build() + + assertThat(params._pathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(params._pathParam(1)).isEqualTo("2019-12-27") + // out-of-bound path param + assertThat(params._pathParam(2)).isEqualTo("") + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListPageResponseTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListPageResponseTest.kt new file mode 100644 index 00000000..bf1d5dd8 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListPageResponseTest.kt @@ -0,0 +1,66 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.lithic.api.core.JsonValue +import com.lithic.api.core.jsonMapper +import java.time.LocalDate +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class FinancialAccountInterestTierScheduleListPageResponseTest { + + @Test + fun create() { + val financialAccountInterestTierScheduleListPageResponse = + FinancialAccountInterestTierScheduleListPageResponse.builder() + .addData( + InterestTierSchedule.builder() + .creditProductToken("credit_product_token") + .effectiveDate(LocalDate.parse("2019-12-27")) + .tierName("tier_name") + .tierRates(JsonValue.from(mapOf())) + .build() + ) + .hasMore(true) + .build() + + assertThat(financialAccountInterestTierScheduleListPageResponse.data()) + .containsExactly( + InterestTierSchedule.builder() + .creditProductToken("credit_product_token") + .effectiveDate(LocalDate.parse("2019-12-27")) + .tierName("tier_name") + .tierRates(JsonValue.from(mapOf())) + .build() + ) + assertThat(financialAccountInterestTierScheduleListPageResponse.hasMore()).isEqualTo(true) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val financialAccountInterestTierScheduleListPageResponse = + FinancialAccountInterestTierScheduleListPageResponse.builder() + .addData( + InterestTierSchedule.builder() + .creditProductToken("credit_product_token") + .effectiveDate(LocalDate.parse("2019-12-27")) + .tierName("tier_name") + .tierRates(JsonValue.from(mapOf())) + .build() + ) + .hasMore(true) + .build() + + val roundtrippedFinancialAccountInterestTierScheduleListPageResponse = + jsonMapper.readValue( + jsonMapper.writeValueAsString(financialAccountInterestTierScheduleListPageResponse), + jacksonTypeRef(), + ) + + assertThat(roundtrippedFinancialAccountInterestTierScheduleListPageResponse) + .isEqualTo(financialAccountInterestTierScheduleListPageResponse) + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListParamsTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListParamsTest.kt new file mode 100644 index 00000000..d2765691 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleListParamsTest.kt @@ -0,0 +1,67 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.lithic.api.core.http.QueryParams +import java.time.LocalDate +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class FinancialAccountInterestTierScheduleListParamsTest { + + @Test + fun create() { + FinancialAccountInterestTierScheduleListParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .afterDate(LocalDate.parse("2019-12-27")) + .beforeDate(LocalDate.parse("2019-12-27")) + .forDate(LocalDate.parse("2019-12-27")) + .build() + } + + @Test + fun pathParams() { + val params = + FinancialAccountInterestTierScheduleListParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + + assertThat(params._pathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } + + @Test + fun queryParams() { + val params = + FinancialAccountInterestTierScheduleListParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .afterDate(LocalDate.parse("2019-12-27")) + .beforeDate(LocalDate.parse("2019-12-27")) + .forDate(LocalDate.parse("2019-12-27")) + .build() + + val queryParams = params._queryParams() + + assertThat(queryParams) + .isEqualTo( + QueryParams.builder() + .put("after_date", "2019-12-27") + .put("before_date", "2019-12-27") + .put("for_date", "2019-12-27") + .build() + ) + } + + @Test + fun queryParamsWithoutOptionalFields() { + val params = + FinancialAccountInterestTierScheduleListParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + + val queryParams = params._queryParams() + + assertThat(queryParams).isEqualTo(QueryParams.builder().build()) + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleRetrieveParamsTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleRetrieveParamsTest.kt new file mode 100644 index 00000000..b9eea005 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleRetrieveParamsTest.kt @@ -0,0 +1,32 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import java.time.LocalDate +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class FinancialAccountInterestTierScheduleRetrieveParamsTest { + + @Test + fun create() { + FinancialAccountInterestTierScheduleRetrieveParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .effectiveDate(LocalDate.parse("2019-12-27")) + .build() + } + + @Test + fun pathParams() { + val params = + FinancialAccountInterestTierScheduleRetrieveParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .effectiveDate(LocalDate.parse("2019-12-27")) + .build() + + assertThat(params._pathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(params._pathParam(1)).isEqualTo("2019-12-27") + // out-of-bound path param + assertThat(params._pathParam(2)).isEqualTo("") + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleUpdateParamsTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleUpdateParamsTest.kt new file mode 100644 index 00000000..8d6e0acd --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountInterestTierScheduleUpdateParamsTest.kt @@ -0,0 +1,62 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.lithic.api.core.JsonValue +import java.time.LocalDate +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class FinancialAccountInterestTierScheduleUpdateParamsTest { + + @Test + fun create() { + FinancialAccountInterestTierScheduleUpdateParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .effectiveDate(LocalDate.parse("2019-12-27")) + .tierName("tier_name") + .tierRates(JsonValue.from(mapOf())) + .build() + } + + @Test + fun pathParams() { + val params = + FinancialAccountInterestTierScheduleUpdateParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .effectiveDate(LocalDate.parse("2019-12-27")) + .build() + + assertThat(params._pathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(params._pathParam(1)).isEqualTo("2019-12-27") + // out-of-bound path param + assertThat(params._pathParam(2)).isEqualTo("") + } + + @Test + fun body() { + val params = + FinancialAccountInterestTierScheduleUpdateParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .effectiveDate(LocalDate.parse("2019-12-27")) + .tierName("tier_name") + .tierRates(JsonValue.from(mapOf())) + .build() + + val body = params._body() + + assertThat(body.tierName()).contains("tier_name") + assertThat(body._tierRates()).isEqualTo(JsonValue.from(mapOf())) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + FinancialAccountInterestTierScheduleUpdateParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .effectiveDate(LocalDate.parse("2019-12-27")) + .build() + + val body = params._body() + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountLoanTapeConfigurationRetrieveParamsTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountLoanTapeConfigurationRetrieveParamsTest.kt new file mode 100644 index 00000000..9fb5ca4a --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/FinancialAccountLoanTapeConfigurationRetrieveParamsTest.kt @@ -0,0 +1,28 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class FinancialAccountLoanTapeConfigurationRetrieveParamsTest { + + @Test + fun create() { + FinancialAccountLoanTapeConfigurationRetrieveParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + } + + @Test + fun pathParams() { + val params = + FinancialAccountLoanTapeConfigurationRetrieveParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + + assertThat(params._pathParam(0)).isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + // out-of-bound path param + assertThat(params._pathParam(1)).isEqualTo("") + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/InterestTierScheduleTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/InterestTierScheduleTest.kt new file mode 100644 index 00000000..dc6a7af2 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/InterestTierScheduleTest.kt @@ -0,0 +1,50 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.lithic.api.core.JsonValue +import com.lithic.api.core.jsonMapper +import java.time.LocalDate +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class InterestTierScheduleTest { + + @Test + fun create() { + val interestTierSchedule = + InterestTierSchedule.builder() + .creditProductToken("credit_product_token") + .effectiveDate(LocalDate.parse("2019-12-27")) + .tierName("tier_name") + .tierRates(JsonValue.from(mapOf())) + .build() + + assertThat(interestTierSchedule.creditProductToken()).isEqualTo("credit_product_token") + assertThat(interestTierSchedule.effectiveDate()).isEqualTo(LocalDate.parse("2019-12-27")) + assertThat(interestTierSchedule.tierName()).contains("tier_name") + assertThat(interestTierSchedule._tierRates()) + .isEqualTo(JsonValue.from(mapOf())) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val interestTierSchedule = + InterestTierSchedule.builder() + .creditProductToken("credit_product_token") + .effectiveDate(LocalDate.parse("2019-12-27")) + .tierName("tier_name") + .tierRates(JsonValue.from(mapOf())) + .build() + + val roundtrippedInterestTierSchedule = + jsonMapper.readValue( + jsonMapper.writeValueAsString(interestTierSchedule), + jacksonTypeRef(), + ) + + assertThat(roundtrippedInterestTierSchedule).isEqualTo(interestTierSchedule) + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/LoanTapeConfigurationTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/LoanTapeConfigurationTest.kt new file mode 100644 index 00000000..d1b3ffe1 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/LoanTapeConfigurationTest.kt @@ -0,0 +1,82 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.lithic.api.core.jsonMapper +import java.time.LocalDate +import java.time.OffsetDateTime +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class LoanTapeConfigurationTest { + + @Test + fun create() { + val loanTapeConfiguration = + LoanTapeConfiguration.builder() + .createdAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .instanceToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .updatedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .creditProductToken("credit_product_token") + .loanTapeRebuildConfiguration( + LoanTapeRebuildConfiguration.builder() + .rebuildNeeded(true) + .lastRebuild(LocalDate.parse("2019-12-27")) + .rebuildFrom(LocalDate.parse("2019-12-27")) + .build() + ) + .tierScheduleChangedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .build() + + assertThat(loanTapeConfiguration.createdAt()) + .isEqualTo(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + assertThat(loanTapeConfiguration.financialAccountToken()) + .isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(loanTapeConfiguration.instanceToken()) + .isEqualTo("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + assertThat(loanTapeConfiguration.updatedAt()) + .isEqualTo(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + assertThat(loanTapeConfiguration.creditProductToken()).contains("credit_product_token") + assertThat(loanTapeConfiguration.loanTapeRebuildConfiguration()) + .contains( + LoanTapeRebuildConfiguration.builder() + .rebuildNeeded(true) + .lastRebuild(LocalDate.parse("2019-12-27")) + .rebuildFrom(LocalDate.parse("2019-12-27")) + .build() + ) + assertThat(loanTapeConfiguration.tierScheduleChangedAt()) + .contains(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val loanTapeConfiguration = + LoanTapeConfiguration.builder() + .createdAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .instanceToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .updatedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .creditProductToken("credit_product_token") + .loanTapeRebuildConfiguration( + LoanTapeRebuildConfiguration.builder() + .rebuildNeeded(true) + .lastRebuild(LocalDate.parse("2019-12-27")) + .rebuildFrom(LocalDate.parse("2019-12-27")) + .build() + ) + .tierScheduleChangedAt(OffsetDateTime.parse("2019-12-27T18:11:19.117Z")) + .build() + + val roundtrippedLoanTapeConfiguration = + jsonMapper.readValue( + jsonMapper.writeValueAsString(loanTapeConfiguration), + jacksonTypeRef(), + ) + + assertThat(roundtrippedLoanTapeConfiguration).isEqualTo(loanTapeConfiguration) + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/models/LoanTapeRebuildConfigurationTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/models/LoanTapeRebuildConfigurationTest.kt new file mode 100644 index 00000000..836ae966 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/models/LoanTapeRebuildConfigurationTest.kt @@ -0,0 +1,47 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.models + +import com.fasterxml.jackson.module.kotlin.jacksonTypeRef +import com.lithic.api.core.jsonMapper +import java.time.LocalDate +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +internal class LoanTapeRebuildConfigurationTest { + + @Test + fun create() { + val loanTapeRebuildConfiguration = + LoanTapeRebuildConfiguration.builder() + .rebuildNeeded(true) + .lastRebuild(LocalDate.parse("2019-12-27")) + .rebuildFrom(LocalDate.parse("2019-12-27")) + .build() + + assertThat(loanTapeRebuildConfiguration.rebuildNeeded()).isEqualTo(true) + assertThat(loanTapeRebuildConfiguration.lastRebuild()) + .contains(LocalDate.parse("2019-12-27")) + assertThat(loanTapeRebuildConfiguration.rebuildFrom()) + .contains(LocalDate.parse("2019-12-27")) + } + + @Test + fun roundtrip() { + val jsonMapper = jsonMapper() + val loanTapeRebuildConfiguration = + LoanTapeRebuildConfiguration.builder() + .rebuildNeeded(true) + .lastRebuild(LocalDate.parse("2019-12-27")) + .rebuildFrom(LocalDate.parse("2019-12-27")) + .build() + + val roundtrippedLoanTapeRebuildConfiguration = + jsonMapper.readValue( + jsonMapper.writeValueAsString(loanTapeRebuildConfiguration), + jacksonTypeRef(), + ) + + assertThat(roundtrippedLoanTapeRebuildConfiguration).isEqualTo(loanTapeRebuildConfiguration) + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/accountHolders/EntityServiceAsyncTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/accountHolders/EntityServiceAsyncTest.kt new file mode 100644 index 00000000..8b1e1220 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/accountHolders/EntityServiceAsyncTest.kt @@ -0,0 +1,72 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.async.accountHolders + +import com.lithic.api.TestServerExtension +import com.lithic.api.client.okhttp.LithicOkHttpClientAsync +import com.lithic.api.models.AccountHolderEntityCreateParams +import com.lithic.api.models.AccountHolderEntityDeleteParams +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class EntityServiceAsyncTest { + + @Test + fun create() { + val client = + LithicOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val entityServiceAsync = client.accountHolders().entities() + + val entityFuture = + entityServiceAsync.create( + AccountHolderEntityCreateParams.builder() + .accountHolderToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .address( + AccountHolderEntityCreateParams.Address.builder() + .address1("300 Normal Forest Way") + .city("Portland") + .country("USA") + .postalCode("90210") + .state("OR") + .address2("address2") + .build() + ) + .dob("1991-03-08T08:00:00Z") + .email("tim@left-earth.com") + .firstName("Timmy") + .governmentId("211-23-1412") + .lastName("Turner") + .phoneNumber("+15555555555") + .type(AccountHolderEntityCreateParams.EntityType.BENEFICIAL_OWNER_INDIVIDUAL) + .build() + ) + + val entity = entityFuture.get() + entity.validate() + } + + @Test + fun delete() { + val client = + LithicOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val entityServiceAsync = client.accountHolders().entities() + + val accountHolderEntityFuture = + entityServiceAsync.delete( + AccountHolderEntityDeleteParams.builder() + .accountHolderToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .entityToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + val accountHolderEntity = accountHolderEntityFuture.get() + accountHolderEntity.validate() + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/financialAccounts/InterestTierScheduleServiceAsyncTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/financialAccounts/InterestTierScheduleServiceAsyncTest.kt new file mode 100644 index 00000000..e3b1e7c1 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/financialAccounts/InterestTierScheduleServiceAsyncTest.kt @@ -0,0 +1,127 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.async.financialAccounts + +import com.lithic.api.TestServerExtension +import com.lithic.api.client.okhttp.LithicOkHttpClientAsync +import com.lithic.api.core.JsonValue +import com.lithic.api.models.FinancialAccountInterestTierScheduleCreateParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleDeleteParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleRetrieveParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleUpdateParams +import com.lithic.api.models.InterestTierSchedule +import java.time.LocalDate +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class InterestTierScheduleServiceAsyncTest { + + @Test + fun create() { + val client = + LithicOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val interestTierScheduleServiceAsync = client.financialAccounts().interestTierSchedule() + + val interestTierScheduleFuture = + interestTierScheduleServiceAsync.create( + FinancialAccountInterestTierScheduleCreateParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .interestTierSchedule( + InterestTierSchedule.builder() + .creditProductToken("credit_product_token") + .effectiveDate(LocalDate.parse("2019-12-27")) + .tierName("tier_name") + .tierRates(JsonValue.from(mapOf())) + .build() + ) + .build() + ) + + val interestTierSchedule = interestTierScheduleFuture.get() + interestTierSchedule.validate() + } + + @Test + fun retrieve() { + val client = + LithicOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val interestTierScheduleServiceAsync = client.financialAccounts().interestTierSchedule() + + val interestTierScheduleFuture = + interestTierScheduleServiceAsync.retrieve( + FinancialAccountInterestTierScheduleRetrieveParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .effectiveDate(LocalDate.parse("2019-12-27")) + .build() + ) + + val interestTierSchedule = interestTierScheduleFuture.get() + interestTierSchedule.validate() + } + + @Test + fun update() { + val client = + LithicOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val interestTierScheduleServiceAsync = client.financialAccounts().interestTierSchedule() + + val interestTierScheduleFuture = + interestTierScheduleServiceAsync.update( + FinancialAccountInterestTierScheduleUpdateParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .effectiveDate(LocalDate.parse("2019-12-27")) + .tierName("tier_name") + .tierRates(JsonValue.from(mapOf())) + .build() + ) + + val interestTierSchedule = interestTierScheduleFuture.get() + interestTierSchedule.validate() + } + + @Test + fun list() { + val client = + LithicOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val interestTierScheduleServiceAsync = client.financialAccounts().interestTierSchedule() + + val pageFuture = + interestTierScheduleServiceAsync.list("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + + val page = pageFuture.get() + page.response().validate() + } + + @Test + fun delete() { + val client = + LithicOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val interestTierScheduleServiceAsync = client.financialAccounts().interestTierSchedule() + + val future = + interestTierScheduleServiceAsync.delete( + FinancialAccountInterestTierScheduleDeleteParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .effectiveDate(LocalDate.parse("2019-12-27")) + .build() + ) + + val response = future.get() + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/financialAccounts/LoanTapeConfigurationServiceAsyncTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/financialAccounts/LoanTapeConfigurationServiceAsyncTest.kt new file mode 100644 index 00000000..ed893c18 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/async/financialAccounts/LoanTapeConfigurationServiceAsyncTest.kt @@ -0,0 +1,28 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.async.financialAccounts + +import com.lithic.api.TestServerExtension +import com.lithic.api.client.okhttp.LithicOkHttpClientAsync +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class LoanTapeConfigurationServiceAsyncTest { + + @Test + fun retrieve() { + val client = + LithicOkHttpClientAsync.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val loanTapeConfigurationServiceAsync = client.financialAccounts().loanTapeConfiguration() + + val loanTapeConfigurationFuture = + loanTapeConfigurationServiceAsync.retrieve("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + + val loanTapeConfiguration = loanTapeConfigurationFuture.get() + loanTapeConfiguration.validate() + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/CardServiceTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/CardServiceTest.kt index e24c6e1d..3c03e597 100644 --- a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/CardServiceTest.kt +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/CardServiceTest.kt @@ -7,6 +7,8 @@ import com.lithic.api.client.okhttp.LithicOkHttpClient import com.lithic.api.models.CardConvertPhysicalParams import com.lithic.api.models.CardCreateParams import com.lithic.api.models.CardEmbedParams +import com.lithic.api.models.CardGetEmbedHtmlParams +import com.lithic.api.models.CardGetEmbedUrlParams import com.lithic.api.models.CardProvisionParams import com.lithic.api.models.CardReissueParams import com.lithic.api.models.CardRenewParams @@ -16,6 +18,7 @@ import com.lithic.api.models.CardWebProvisionParams import com.lithic.api.models.Carrier import com.lithic.api.models.ShippingAddress import com.lithic.api.models.SpendLimitDuration +import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -342,4 +345,34 @@ internal class CardServiceTest { response.validate() } + + @Test + fun callGetEmbedHtml() { + val client = + LithicOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("test-api-key") + .webhookSecret("string") + .build() + val cardService = client.cards() + val cardEmbedResponse = + cardService.getEmbedHtml(CardGetEmbedHtmlParams.builder().token("foo").build()) + println(cardEmbedResponse) + assertThat(cardEmbedResponse).contains("") + } + + @Test + fun callGetEmbedUrl() { + val client = + LithicOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("test-api-key") + .webhookSecret("string") + .build() + val cardService = client.cards() + val cardEmbedUrl = + cardService.getEmbedUrl(CardGetEmbedUrlParams.builder().token("foo").build()) + println(cardEmbedUrl) + assertThat(cardEmbedUrl).contains("hmac") + } } diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/accountHolders/EntityServiceTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/accountHolders/EntityServiceTest.kt new file mode 100644 index 00000000..ae45c235 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/accountHolders/EntityServiceTest.kt @@ -0,0 +1,70 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.blocking.accountHolders + +import com.lithic.api.TestServerExtension +import com.lithic.api.client.okhttp.LithicOkHttpClient +import com.lithic.api.models.AccountHolderEntityCreateParams +import com.lithic.api.models.AccountHolderEntityDeleteParams +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class EntityServiceTest { + + @Test + fun create() { + val client = + LithicOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val entityService = client.accountHolders().entities() + + val entity = + entityService.create( + AccountHolderEntityCreateParams.builder() + .accountHolderToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .address( + AccountHolderEntityCreateParams.Address.builder() + .address1("300 Normal Forest Way") + .city("Portland") + .country("USA") + .postalCode("90210") + .state("OR") + .address2("address2") + .build() + ) + .dob("1991-03-08T08:00:00Z") + .email("tim@left-earth.com") + .firstName("Timmy") + .governmentId("211-23-1412") + .lastName("Turner") + .phoneNumber("+15555555555") + .type(AccountHolderEntityCreateParams.EntityType.BENEFICIAL_OWNER_INDIVIDUAL) + .build() + ) + + entity.validate() + } + + @Test + fun delete() { + val client = + LithicOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val entityService = client.accountHolders().entities() + + val accountHolderEntity = + entityService.delete( + AccountHolderEntityDeleteParams.builder() + .accountHolderToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .entityToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .build() + ) + + accountHolderEntity.validate() + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/financialAccounts/InterestTierScheduleServiceTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/financialAccounts/InterestTierScheduleServiceTest.kt new file mode 100644 index 00000000..2489e02f --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/financialAccounts/InterestTierScheduleServiceTest.kt @@ -0,0 +1,119 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.blocking.financialAccounts + +import com.lithic.api.TestServerExtension +import com.lithic.api.client.okhttp.LithicOkHttpClient +import com.lithic.api.core.JsonValue +import com.lithic.api.models.FinancialAccountInterestTierScheduleCreateParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleDeleteParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleRetrieveParams +import com.lithic.api.models.FinancialAccountInterestTierScheduleUpdateParams +import com.lithic.api.models.InterestTierSchedule +import java.time.LocalDate +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class InterestTierScheduleServiceTest { + + @Test + fun create() { + val client = + LithicOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val interestTierScheduleService = client.financialAccounts().interestTierSchedule() + + val interestTierSchedule = + interestTierScheduleService.create( + FinancialAccountInterestTierScheduleCreateParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .interestTierSchedule( + InterestTierSchedule.builder() + .creditProductToken("credit_product_token") + .effectiveDate(LocalDate.parse("2019-12-27")) + .tierName("tier_name") + .tierRates(JsonValue.from(mapOf())) + .build() + ) + .build() + ) + + interestTierSchedule.validate() + } + + @Test + fun retrieve() { + val client = + LithicOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val interestTierScheduleService = client.financialAccounts().interestTierSchedule() + + val interestTierSchedule = + interestTierScheduleService.retrieve( + FinancialAccountInterestTierScheduleRetrieveParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .effectiveDate(LocalDate.parse("2019-12-27")) + .build() + ) + + interestTierSchedule.validate() + } + + @Test + fun update() { + val client = + LithicOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val interestTierScheduleService = client.financialAccounts().interestTierSchedule() + + val interestTierSchedule = + interestTierScheduleService.update( + FinancialAccountInterestTierScheduleUpdateParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .effectiveDate(LocalDate.parse("2019-12-27")) + .tierName("tier_name") + .tierRates(JsonValue.from(mapOf())) + .build() + ) + + interestTierSchedule.validate() + } + + @Test + fun list() { + val client = + LithicOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val interestTierScheduleService = client.financialAccounts().interestTierSchedule() + + val page = interestTierScheduleService.list("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + + page.response().validate() + } + + @Test + fun delete() { + val client = + LithicOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val interestTierScheduleService = client.financialAccounts().interestTierSchedule() + + interestTierScheduleService.delete( + FinancialAccountInterestTierScheduleDeleteParams.builder() + .financialAccountToken("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + .effectiveDate(LocalDate.parse("2019-12-27")) + .build() + ) + } +} diff --git a/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/financialAccounts/LoanTapeConfigurationServiceTest.kt b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/financialAccounts/LoanTapeConfigurationServiceTest.kt new file mode 100644 index 00000000..210ff531 --- /dev/null +++ b/lithic-java-core/src/test/kotlin/com/lithic/api/services/blocking/financialAccounts/LoanTapeConfigurationServiceTest.kt @@ -0,0 +1,27 @@ +// File generated from our OpenAPI spec by Stainless. + +package com.lithic.api.services.blocking.financialAccounts + +import com.lithic.api.TestServerExtension +import com.lithic.api.client.okhttp.LithicOkHttpClient +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + +@ExtendWith(TestServerExtension::class) +internal class LoanTapeConfigurationServiceTest { + + @Test + fun retrieve() { + val client = + LithicOkHttpClient.builder() + .baseUrl(TestServerExtension.BASE_URL) + .apiKey("My Lithic API Key") + .build() + val loanTapeConfigurationService = client.financialAccounts().loanTapeConfiguration() + + val loanTapeConfiguration = + loanTapeConfigurationService.retrieve("182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e") + + loanTapeConfiguration.validate() + } +}