diff --git a/.release-please-manifest.json b/.release-please-manifest.json index e6a02ed0a..68764d436 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.307.0" + ".": "0.308.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 24b3407c3..160b294b4 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 216 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/increase%2Fincrease-f53b2a737b80cf584e4c30b143f41b7afe73bce6c02e00ccd09ff36d30e3d913.yml -openapi_spec_hash: eda3be244729410eb2747752c40a1124 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/increase%2Fincrease-a6d99e6e3e405acf3e592e273aa1c5d519ed4f1157d0f87f1dcf21e7710f59b5.yml +openapi_spec_hash: f1f21c7331c905f2e5549978454059dc config_hash: 632b628b59d8f0b717153b3d8133f6cb diff --git a/CHANGELOG.md b/CHANGELOG.md index 7083b70be..75d9fbf1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.308.0 (2025-08-28) + +Full Changelog: [v0.307.0...v0.308.0](https://github.com/Increase/increase-java/compare/v0.307.0...v0.308.0) + +### Features + +* **api:** api update ([6e33c80](https://github.com/Increase/increase-java/commit/6e33c80f8694f44e4b480b447a3f69c29db58e23)) + ## 0.307.0 (2025-08-28) Full Changelog: [v0.306.0...v0.307.0](https://github.com/Increase/increase-java/compare/v0.306.0...v0.307.0) diff --git a/README.md b/README.md index fd94cec08..c93b6eeb6 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.increase.api/increase-java)](https://central.sonatype.com/artifact/com.increase.api/increase-java/0.307.0) -[![javadoc](https://javadoc.io/badge2/com.increase.api/increase-java/0.307.0/javadoc.svg)](https://javadoc.io/doc/com.increase.api/increase-java/0.307.0) +[![Maven Central](https://img.shields.io/maven-central/v/com.increase.api/increase-java)](https://central.sonatype.com/artifact/com.increase.api/increase-java/0.308.0) +[![javadoc](https://javadoc.io/badge2/com.increase.api/increase-java/0.308.0/javadoc.svg)](https://javadoc.io/doc/com.increase.api/increase-java/0.308.0) @@ -13,7 +13,7 @@ The Increase Java SDK is similar to the Increase Kotlin SDK but with minor diffe -The REST API documentation can be found on [increase.com](https://increase.com/documentation). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.increase.api/increase-java/0.307.0). +The REST API documentation can be found on [increase.com](https://increase.com/documentation). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.increase.api/increase-java/0.308.0). @@ -24,7 +24,7 @@ The REST API documentation can be found on [increase.com](https://increase.com/d ### Gradle ```kotlin -implementation("com.increase.api:increase-java:0.307.0") +implementation("com.increase.api:increase-java:0.308.0") ``` ### Maven @@ -33,7 +33,7 @@ implementation("com.increase.api:increase-java:0.307.0") com.increase.api increase-java - 0.307.0 + 0.308.0 ``` diff --git a/build.gradle.kts b/build.gradle.kts index 4a4d27de0..de32f5afe 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ repositories { allprojects { group = "com.increase.api" - version = "0.307.0" // x-release-please-version + version = "0.308.0" // x-release-please-version } subprojects { diff --git a/increase-java-core/src/main/kotlin/com/increase/api/models/simulations/achtransfers/AchTransferSettleParams.kt b/increase-java-core/src/main/kotlin/com/increase/api/models/simulations/achtransfers/AchTransferSettleParams.kt index 2658e0b9b..8d610f0b8 100644 --- a/increase-java-core/src/main/kotlin/com/increase/api/models/simulations/achtransfers/AchTransferSettleParams.kt +++ b/increase-java-core/src/main/kotlin/com/increase/api/models/simulations/achtransfers/AchTransferSettleParams.kt @@ -2,11 +2,20 @@ package com.increase.api.models.simulations.achtransfers +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.increase.api.core.Enum +import com.increase.api.core.ExcludeMissing +import com.increase.api.core.JsonField +import com.increase.api.core.JsonMissing import com.increase.api.core.JsonValue import com.increase.api.core.Params import com.increase.api.core.http.Headers import com.increase.api.core.http.QueryParams -import com.increase.api.core.toImmutable +import com.increase.api.errors.IncreaseInvalidDataException +import java.util.Collections import java.util.Objects import java.util.Optional import kotlin.jvm.optionals.getOrNull @@ -16,21 +25,42 @@ import kotlin.jvm.optionals.getOrNull * transfer must first have a `status` of `pending_submission` or `submitted`. For convenience, if * the transfer is in `status`: `pending_submission`, the simulation will also submit the transfer. * Without this simulation the transfer will eventually settle on its own following the same Federal - * Reserve timeline as in production. + * Reserve timeline as in production. Additionally, you can specify the behavior of the inbound + * funds hold that is created when the ACH Transfer is settled. If no behavior is specified, the + * inbound funds hold will be released immediately in order for the funds to be available for use. */ class AchTransferSettleParams private constructor( private val achTransferId: String?, + private val body: Body, private val additionalHeaders: Headers, private val additionalQueryParams: QueryParams, - private val additionalBodyProperties: Map, ) : Params { /** The identifier of the ACH Transfer you wish to become settled. */ fun achTransferId(): Optional = Optional.ofNullable(achTransferId) - /** Additional body properties to send with the request. */ - fun _additionalBodyProperties(): Map = additionalBodyProperties + /** + * The behavior of the inbound funds hold that is created when the ACH Transfer is settled. If + * no behavior is specified, the inbound funds hold will be released immediately in order for + * the funds to be available for use. + * + * @throws IncreaseInvalidDataException if the JSON field has an unexpected type (e.g. if the + * server responded with an unexpected value). + */ + fun inboundFundsHoldBehavior(): Optional = + body.inboundFundsHoldBehavior() + + /** + * Returns the raw JSON value of [inboundFundsHoldBehavior]. + * + * Unlike [inboundFundsHoldBehavior], this method doesn't throw if the JSON field has an + * unexpected type. + */ + fun _inboundFundsHoldBehavior(): JsonField = + body._inboundFundsHoldBehavior() + + fun _additionalBodyProperties(): Map = body._additionalProperties() /** Additional headers to send with the request. */ fun _additionalHeaders(): Headers = additionalHeaders @@ -52,17 +82,16 @@ private constructor( class Builder internal constructor() { private var achTransferId: String? = null + private var body: Body.Builder = Body.builder() private var additionalHeaders: Headers.Builder = Headers.builder() private var additionalQueryParams: QueryParams.Builder = QueryParams.builder() - private var additionalBodyProperties: MutableMap = mutableMapOf() @JvmSynthetic internal fun from(achTransferSettleParams: AchTransferSettleParams) = apply { achTransferId = achTransferSettleParams.achTransferId + body = achTransferSettleParams.body.toBuilder() additionalHeaders = achTransferSettleParams.additionalHeaders.toBuilder() additionalQueryParams = achTransferSettleParams.additionalQueryParams.toBuilder() - additionalBodyProperties = - achTransferSettleParams.additionalBodyProperties.toMutableMap() } /** The identifier of the ACH Transfer you wish to become settled. */ @@ -72,6 +101,54 @@ private constructor( fun achTransferId(achTransferId: Optional) = achTransferId(achTransferId.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: + * - [inboundFundsHoldBehavior] + */ + fun body(body: Body) = apply { this.body = body.toBuilder() } + + /** + * The behavior of the inbound funds hold that is created when the ACH Transfer is settled. + * If no behavior is specified, the inbound funds hold will be released immediately in order + * for the funds to be available for use. + */ + fun inboundFundsHoldBehavior(inboundFundsHoldBehavior: InboundFundsHoldBehavior) = apply { + body.inboundFundsHoldBehavior(inboundFundsHoldBehavior) + } + + /** + * Sets [Builder.inboundFundsHoldBehavior] to an arbitrary JSON value. + * + * You should usually call [Builder.inboundFundsHoldBehavior] with a well-typed + * [InboundFundsHoldBehavior] value instead. This method is primarily for setting the field + * to an undocumented or not yet supported value. + */ + fun inboundFundsHoldBehavior( + inboundFundsHoldBehavior: JsonField + ) = apply { body.inboundFundsHoldBehavior(inboundFundsHoldBehavior) } + + 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) @@ -170,28 +247,6 @@ private constructor( 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 [AchTransferSettleParams]. * @@ -200,14 +255,13 @@ private constructor( fun build(): AchTransferSettleParams = AchTransferSettleParams( achTransferId, + body.build(), additionalHeaders.build(), additionalQueryParams.build(), - additionalBodyProperties.toImmutable(), ) } - fun _body(): Optional> = - Optional.ofNullable(additionalBodyProperties.ifEmpty { null }) + fun _body(): Body = body fun _pathParam(index: Int): String = when (index) { @@ -219,6 +273,313 @@ private constructor( override fun _queryParams(): QueryParams = additionalQueryParams + class Body + private constructor( + private val inboundFundsHoldBehavior: JsonField, + private val additionalProperties: MutableMap, + ) { + + @JsonCreator + private constructor( + @JsonProperty("inbound_funds_hold_behavior") + @ExcludeMissing + inboundFundsHoldBehavior: JsonField = JsonMissing.of() + ) : this(inboundFundsHoldBehavior, mutableMapOf()) + + /** + * The behavior of the inbound funds hold that is created when the ACH Transfer is settled. + * If no behavior is specified, the inbound funds hold will be released immediately in order + * for the funds to be available for use. + * + * @throws IncreaseInvalidDataException if the JSON field has an unexpected type (e.g. if + * the server responded with an unexpected value). + */ + fun inboundFundsHoldBehavior(): Optional = + inboundFundsHoldBehavior.getOptional("inbound_funds_hold_behavior") + + /** + * Returns the raw JSON value of [inboundFundsHoldBehavior]. + * + * Unlike [inboundFundsHoldBehavior], this method doesn't throw if the JSON field has an + * unexpected type. + */ + @JsonProperty("inbound_funds_hold_behavior") + @ExcludeMissing + fun _inboundFundsHoldBehavior(): JsonField = + inboundFundsHoldBehavior + + @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 [Body]. */ + @JvmStatic fun builder() = Builder() + } + + /** A builder for [Body]. */ + class Builder internal constructor() { + + private var inboundFundsHoldBehavior: JsonField = + JsonMissing.of() + private var additionalProperties: MutableMap = mutableMapOf() + + @JvmSynthetic + internal fun from(body: Body) = apply { + inboundFundsHoldBehavior = body.inboundFundsHoldBehavior + additionalProperties = body.additionalProperties.toMutableMap() + } + + /** + * The behavior of the inbound funds hold that is created when the ACH Transfer is + * settled. If no behavior is specified, the inbound funds hold will be released + * immediately in order for the funds to be available for use. + */ + fun inboundFundsHoldBehavior(inboundFundsHoldBehavior: InboundFundsHoldBehavior) = + inboundFundsHoldBehavior(JsonField.of(inboundFundsHoldBehavior)) + + /** + * Sets [Builder.inboundFundsHoldBehavior] to an arbitrary JSON value. + * + * You should usually call [Builder.inboundFundsHoldBehavior] with a well-typed + * [InboundFundsHoldBehavior] value instead. This method is primarily for setting the + * field to an undocumented or not yet supported value. + */ + fun inboundFundsHoldBehavior( + inboundFundsHoldBehavior: JsonField + ) = apply { this.inboundFundsHoldBehavior = inboundFundsHoldBehavior } + + 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 [Body]. + * + * Further updates to this [Builder] will not mutate the returned instance. + */ + fun build(): Body = Body(inboundFundsHoldBehavior, additionalProperties.toMutableMap()) + } + + private var validated: Boolean = false + + fun validate(): Body = apply { + if (validated) { + return@apply + } + + inboundFundsHoldBehavior().ifPresent { it.validate() } + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: IncreaseInvalidDataException) { + 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 = + (inboundFundsHoldBehavior.asKnown().getOrNull()?.validity() ?: 0) + + override fun equals(other: Any?): Boolean { + if (this === other) { + return true + } + + return other is Body && + inboundFundsHoldBehavior == other.inboundFundsHoldBehavior && + additionalProperties == other.additionalProperties + } + + private val hashCode: Int by lazy { + Objects.hash(inboundFundsHoldBehavior, additionalProperties) + } + + override fun hashCode(): Int = hashCode + + override fun toString() = + "Body{inboundFundsHoldBehavior=$inboundFundsHoldBehavior, additionalProperties=$additionalProperties}" + } + + /** + * The behavior of the inbound funds hold that is created when the ACH Transfer is settled. If + * no behavior is specified, the inbound funds hold will be released immediately in order for + * the funds to be available for use. + */ + class InboundFundsHoldBehavior + @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 { + + /** Release the inbound funds hold immediately. */ + @JvmField val RELEASE_IMMEDIATELY = of("release_immediately") + + /** Release the inbound funds hold on the default schedule. */ + @JvmField val RELEASE_ON_DEFAULT_SCHEDULE = of("release_on_default_schedule") + + @JvmStatic fun of(value: String) = InboundFundsHoldBehavior(JsonField.of(value)) + } + + /** An enum containing [InboundFundsHoldBehavior]'s known values. */ + enum class Known { + /** Release the inbound funds hold immediately. */ + RELEASE_IMMEDIATELY, + /** Release the inbound funds hold on the default schedule. */ + RELEASE_ON_DEFAULT_SCHEDULE, + } + + /** + * An enum containing [InboundFundsHoldBehavior]'s known values, as well as an [_UNKNOWN] + * member. + * + * An instance of [InboundFundsHoldBehavior] 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 { + /** Release the inbound funds hold immediately. */ + RELEASE_IMMEDIATELY, + /** Release the inbound funds hold on the default schedule. */ + RELEASE_ON_DEFAULT_SCHEDULE, + /** + * An enum member indicating that [InboundFundsHoldBehavior] 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) { + RELEASE_IMMEDIATELY -> Value.RELEASE_IMMEDIATELY + RELEASE_ON_DEFAULT_SCHEDULE -> Value.RELEASE_ON_DEFAULT_SCHEDULE + 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 IncreaseInvalidDataException if this class instance's value is a not a known + * member. + */ + fun known(): Known = + when (this) { + RELEASE_IMMEDIATELY -> Known.RELEASE_IMMEDIATELY + RELEASE_ON_DEFAULT_SCHEDULE -> Known.RELEASE_ON_DEFAULT_SCHEDULE + else -> + throw IncreaseInvalidDataException("Unknown InboundFundsHoldBehavior: $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 IncreaseInvalidDataException if this class instance's value does not have the + * expected primitive type. + */ + fun asString(): String = + _value().asString().orElseThrow { + IncreaseInvalidDataException("Value is not a String") + } + + private var validated: Boolean = false + + fun validate(): InboundFundsHoldBehavior = apply { + if (validated) { + return@apply + } + + known() + validated = true + } + + fun isValid(): Boolean = + try { + validate() + true + } catch (e: IncreaseInvalidDataException) { + 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 InboundFundsHoldBehavior && value == other.value + } + + override fun hashCode() = value.hashCode() + + override fun toString() = value.toString() + } + override fun equals(other: Any?): Boolean { if (this === other) { return true @@ -226,19 +587,14 @@ private constructor( return other is AchTransferSettleParams && achTransferId == other.achTransferId && + body == other.body && additionalHeaders == other.additionalHeaders && - additionalQueryParams == other.additionalQueryParams && - additionalBodyProperties == other.additionalBodyProperties + additionalQueryParams == other.additionalQueryParams } override fun hashCode(): Int = - Objects.hash( - achTransferId, - additionalHeaders, - additionalQueryParams, - additionalBodyProperties, - ) + Objects.hash(achTransferId, body, additionalHeaders, additionalQueryParams) override fun toString() = - "AchTransferSettleParams{achTransferId=$achTransferId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams, additionalBodyProperties=$additionalBodyProperties}" + "AchTransferSettleParams{achTransferId=$achTransferId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}" } diff --git a/increase-java-core/src/main/kotlin/com/increase/api/services/async/simulations/AchTransferServiceAsync.kt b/increase-java-core/src/main/kotlin/com/increase/api/services/async/simulations/AchTransferServiceAsync.kt index 03cb367ee..d304bb1fd 100644 --- a/increase-java-core/src/main/kotlin/com/increase/api/services/async/simulations/AchTransferServiceAsync.kt +++ b/increase-java-core/src/main/kotlin/com/increase/api/services/async/simulations/AchTransferServiceAsync.kt @@ -142,7 +142,10 @@ interface AchTransferServiceAsync { * transfer must first have a `status` of `pending_submission` or `submitted`. For convenience, * if the transfer is in `status`: `pending_submission`, the simulation will also submit the * transfer. Without this simulation the transfer will eventually settle on its own following - * the same Federal Reserve timeline as in production. + * the same Federal Reserve timeline as in production. Additionally, you can specify the + * behavior of the inbound funds hold that is created when the ACH Transfer is settled. If no + * behavior is specified, the inbound funds hold will be released immediately in order for the + * funds to be available for use. */ fun settle(achTransferId: String): CompletableFuture = settle(achTransferId, AchTransferSettleParams.none()) diff --git a/increase-java-core/src/main/kotlin/com/increase/api/services/async/simulations/AchTransferServiceAsyncImpl.kt b/increase-java-core/src/main/kotlin/com/increase/api/services/async/simulations/AchTransferServiceAsyncImpl.kt index 4c1be49ea..19a270bce 100644 --- a/increase-java-core/src/main/kotlin/com/increase/api/services/async/simulations/AchTransferServiceAsyncImpl.kt +++ b/increase-java-core/src/main/kotlin/com/increase/api/services/async/simulations/AchTransferServiceAsyncImpl.kt @@ -215,7 +215,7 @@ class AchTransferServiceAsyncImpl internal constructor(private val clientOptions .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) .addPathSegments("simulations", "ach_transfers", params._pathParam(0), "settle") - .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .body(json(clientOptions.jsonMapper, params._body())) .build() .prepareAsync(clientOptions, params) val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) diff --git a/increase-java-core/src/main/kotlin/com/increase/api/services/blocking/simulations/AchTransferService.kt b/increase-java-core/src/main/kotlin/com/increase/api/services/blocking/simulations/AchTransferService.kt index 0cde604bd..c629b5081 100644 --- a/increase-java-core/src/main/kotlin/com/increase/api/services/blocking/simulations/AchTransferService.kt +++ b/increase-java-core/src/main/kotlin/com/increase/api/services/blocking/simulations/AchTransferService.kt @@ -135,7 +135,10 @@ interface AchTransferService { * transfer must first have a `status` of `pending_submission` or `submitted`. For convenience, * if the transfer is in `status`: `pending_submission`, the simulation will also submit the * transfer. Without this simulation the transfer will eventually settle on its own following - * the same Federal Reserve timeline as in production. + * the same Federal Reserve timeline as in production. Additionally, you can specify the + * behavior of the inbound funds hold that is created when the ACH Transfer is settled. If no + * behavior is specified, the inbound funds hold will be released immediately in order for the + * funds to be available for use. */ fun settle(achTransferId: String): AchTransfer = settle(achTransferId, AchTransferSettleParams.none()) diff --git a/increase-java-core/src/main/kotlin/com/increase/api/services/blocking/simulations/AchTransferServiceImpl.kt b/increase-java-core/src/main/kotlin/com/increase/api/services/blocking/simulations/AchTransferServiceImpl.kt index 17b97cfbe..0d272f03e 100644 --- a/increase-java-core/src/main/kotlin/com/increase/api/services/blocking/simulations/AchTransferServiceImpl.kt +++ b/increase-java-core/src/main/kotlin/com/increase/api/services/blocking/simulations/AchTransferServiceImpl.kt @@ -203,7 +203,7 @@ class AchTransferServiceImpl internal constructor(private val clientOptions: Cli .method(HttpMethod.POST) .baseUrl(clientOptions.baseUrl()) .addPathSegments("simulations", "ach_transfers", params._pathParam(0), "settle") - .apply { params._body().ifPresent { body(json(clientOptions.jsonMapper, it)) } } + .body(json(clientOptions.jsonMapper, params._body())) .build() .prepare(clientOptions, params) val requestOptions = requestOptions.applyDefaults(RequestOptions.from(clientOptions)) diff --git a/increase-java-core/src/test/kotlin/com/increase/api/models/simulations/achtransfers/AchTransferSettleParamsTest.kt b/increase-java-core/src/test/kotlin/com/increase/api/models/simulations/achtransfers/AchTransferSettleParamsTest.kt index 369e77e28..57288bb6f 100644 --- a/increase-java-core/src/test/kotlin/com/increase/api/models/simulations/achtransfers/AchTransferSettleParamsTest.kt +++ b/increase-java-core/src/test/kotlin/com/increase/api/models/simulations/achtransfers/AchTransferSettleParamsTest.kt @@ -9,7 +9,12 @@ internal class AchTransferSettleParamsTest { @Test fun create() { - AchTransferSettleParams.builder().achTransferId("ach_transfer_uoxatyh3lt5evrsdvo7q").build() + AchTransferSettleParams.builder() + .achTransferId("ach_transfer_uoxatyh3lt5evrsdvo7q") + .inboundFundsHoldBehavior( + AchTransferSettleParams.InboundFundsHoldBehavior.RELEASE_IMMEDIATELY + ) + .build() } @Test @@ -23,4 +28,30 @@ internal class AchTransferSettleParamsTest { // out-of-bound path param assertThat(params._pathParam(1)).isEqualTo("") } + + @Test + fun body() { + val params = + AchTransferSettleParams.builder() + .achTransferId("ach_transfer_uoxatyh3lt5evrsdvo7q") + .inboundFundsHoldBehavior( + AchTransferSettleParams.InboundFundsHoldBehavior.RELEASE_IMMEDIATELY + ) + .build() + + val body = params._body() + + assertThat(body.inboundFundsHoldBehavior()) + .contains(AchTransferSettleParams.InboundFundsHoldBehavior.RELEASE_IMMEDIATELY) + } + + @Test + fun bodyWithoutOptionalFields() { + val params = + AchTransferSettleParams.builder() + .achTransferId("ach_transfer_uoxatyh3lt5evrsdvo7q") + .build() + + val body = params._body() + } } diff --git a/increase-java-core/src/test/kotlin/com/increase/api/services/async/simulations/AchTransferServiceAsyncTest.kt b/increase-java-core/src/test/kotlin/com/increase/api/services/async/simulations/AchTransferServiceAsyncTest.kt index c508cabbd..01ede4cce 100644 --- a/increase-java-core/src/test/kotlin/com/increase/api/services/async/simulations/AchTransferServiceAsyncTest.kt +++ b/increase-java-core/src/test/kotlin/com/increase/api/services/async/simulations/AchTransferServiceAsyncTest.kt @@ -6,6 +6,7 @@ import com.increase.api.TestServerExtension import com.increase.api.client.okhttp.IncreaseOkHttpClientAsync import com.increase.api.models.simulations.achtransfers.AchTransferCreateNotificationOfChangeParams import com.increase.api.models.simulations.achtransfers.AchTransferReturnParams +import com.increase.api.models.simulations.achtransfers.AchTransferSettleParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -83,7 +84,15 @@ internal class AchTransferServiceAsyncTest { .build() val achTransferServiceAsync = client.simulations().achTransfers() - val achTransferFuture = achTransferServiceAsync.settle("ach_transfer_uoxatyh3lt5evrsdvo7q") + val achTransferFuture = + achTransferServiceAsync.settle( + AchTransferSettleParams.builder() + .achTransferId("ach_transfer_uoxatyh3lt5evrsdvo7q") + .inboundFundsHoldBehavior( + AchTransferSettleParams.InboundFundsHoldBehavior.RELEASE_IMMEDIATELY + ) + .build() + ) val achTransfer = achTransferFuture.get() achTransfer.validate() diff --git a/increase-java-core/src/test/kotlin/com/increase/api/services/blocking/simulations/AchTransferServiceTest.kt b/increase-java-core/src/test/kotlin/com/increase/api/services/blocking/simulations/AchTransferServiceTest.kt index 7934291be..bffba47d1 100644 --- a/increase-java-core/src/test/kotlin/com/increase/api/services/blocking/simulations/AchTransferServiceTest.kt +++ b/increase-java-core/src/test/kotlin/com/increase/api/services/blocking/simulations/AchTransferServiceTest.kt @@ -6,6 +6,7 @@ import com.increase.api.TestServerExtension import com.increase.api.client.okhttp.IncreaseOkHttpClient import com.increase.api.models.simulations.achtransfers.AchTransferCreateNotificationOfChangeParams import com.increase.api.models.simulations.achtransfers.AchTransferReturnParams +import com.increase.api.models.simulations.achtransfers.AchTransferSettleParams import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -79,7 +80,15 @@ internal class AchTransferServiceTest { .build() val achTransferService = client.simulations().achTransfers() - val achTransfer = achTransferService.settle("ach_transfer_uoxatyh3lt5evrsdvo7q") + val achTransfer = + achTransferService.settle( + AchTransferSettleParams.builder() + .achTransferId("ach_transfer_uoxatyh3lt5evrsdvo7q") + .inboundFundsHoldBehavior( + AchTransferSettleParams.InboundFundsHoldBehavior.RELEASE_IMMEDIATELY + ) + .build() + ) achTransfer.validate() }