chore: refactor payment collection setPaymentSession (#2928)

**What**

Only use `setPaymentSessionsBatch` in `setPaymentSession` to reuse the logic as it is the same behavior. One for a unique session and the other one for multiple sessions.
This refactoring reduce the risk of introducing bugs when working around payment session if it needs to be changed (which is currently happening as part of the payment refactoring) and having to change it in less places instead of more and more places
This commit is contained in:
Adrien de Peretti
2023-01-05 16:22:12 +01:00
committed by GitHub
parent c07ffb6165
commit 3d200c41f9
3 changed files with 39 additions and 83 deletions

View File

@@ -0,0 +1,5 @@
---
"@medusajs/medusa": patch
---
chore: refactor payment collection setPaymentSession

View File

@@ -66,6 +66,13 @@ describe("PaymentCollectionService", () => {
region_id: IdMap.getId("region1"),
amount: 35000,
status: PaymentCollectionStatus.AUTHORIZED,
region: {
payment_providers: [
{
id: IdMap.getId("region1_provider1"),
},
],
},
}
const zeroSample = {

View File

@@ -2,7 +2,7 @@ import { DeepPartial, EntityManager } from "typeorm"
import { isDefined, MedusaError } from "medusa-core-utils"
import { FindConfig } from "../types/common"
import { buildQuery, setMetadata } from "../utils"
import { buildQuery, isString, setMetadata } from "../utils"
import { PaymentCollectionRepository } from "../repositories/payment-collection"
import {
PaymentCollection,
@@ -225,13 +225,13 @@ export default class PaymentCollectionService extends TransactionBaseService {
/**
* Manages multiple payment sessions of a payment collection.
* @param paymentCollectionId - the id of the payment collection
* @param paymentCollectionOrId - the id of the payment collection
* @param sessionsInput - array containing payment session info
* @param customerId - the id of the customer
* @return the payment collection and its payment sessions.
*/
async setPaymentSessionsBatch(
paymentCollectionId: string,
paymentCollectionOrId: string | PaymentCollection,
sessionsInput: PaymentCollectionsSessionsBatchInput[],
customerId: string
): Promise<PaymentCollection> {
@@ -240,9 +240,15 @@ export default class PaymentCollectionService extends TransactionBaseService {
this.paymentCollectionRepository_
)
const payCol = await this.retrieve(paymentCollectionId, {
relations: ["region", "region.payment_providers", "payment_sessions"],
})
const payCol: PaymentCollection = isString(paymentCollectionOrId)
? await this.retrieve(paymentCollectionOrId, {
relations: [
"region",
"region.payment_providers",
"payment_sessions",
],
})
: paymentCollectionOrId
if (payCol.status !== PaymentCollectionStatus.NOT_PAID) {
throw new MedusaError(
@@ -362,25 +368,14 @@ export default class PaymentCollectionService extends TransactionBaseService {
sessionInput: PaymentCollectionsSessionsInput,
customerId: string
): Promise<PaymentCollection> {
return await this.atomicPhase_(async (manager: EntityManager) => {
const paymentCollectionRepository = manager.getCustomRepository(
this.paymentCollectionRepository_
)
return await this.atomicPhase_(async () => {
const payCol = await this.retrieve(paymentCollectionId, {
relations: ["region", "region.payment_providers", "payment_sessions"],
})
if (payCol.status !== PaymentCollectionStatus.NOT_PAID) {
throw new MedusaError(
MedusaError.Types.NOT_ALLOWED,
`Cannot set payment sessions for a payment collection with status ${payCol.status}`
)
}
const hasProvider = payCol?.region?.payment_providers
.map((p) => p.id)
.includes(sessionInput.provider_id)
const hasProvider = payCol?.region?.payment_providers.find(
(p) => p.id === sessionInput.provider_id
)
if (!hasProvider) {
throw new MedusaError(
@@ -389,72 +384,21 @@ export default class PaymentCollectionService extends TransactionBaseService {
)
}
const customer = !isDefined(customerId)
? null
: await this.customerService_
.withTransaction(manager)
.retrieve(customerId, {
select: ["id", "email", "metadata"],
})
.catch(() => null)
const paymentSessions: PaymentSession[] = []
const inputData: PaymentSessionInput = {
cart: {
email: customer?.email || "",
context: {},
shipping_methods: [],
shipping_address: null,
id: "",
},
resource_id: payCol.id,
currency_code: payCol.currency_code,
amount: payCol.amount,
provider_id: sessionInput.provider_id,
customer,
}
const existingSession = payCol.payment_sessions?.find(
(sess) => sessionInput.provider_id === sess?.provider_id
)
if (existingSession) {
const paymentSession = await this.paymentProviderService_
.withTransaction(manager)
.updateSession(existingSession, inputData)
paymentSessions.push(paymentSession)
} else {
const paymentSession = await this.paymentProviderService_
.withTransaction(manager)
.createSession(inputData)
paymentSessions.push(paymentSession)
const removeSessions: PaymentSession[] = payCol.payment_sessions.filter(
({ id }) => id != paymentSession.id
)
if (removeSessions.length) {
await paymentCollectionRepository.delete(
removeSessions.map((sess) => sess.id)
)
const paymentProviderTx =
this.paymentProviderService_.withTransaction(manager)
Promise.all(
removeSessions.map(async (sess) =>
paymentProviderTx.deleteSession(sess)
)
).catch(() => void 0)
}
}
payCol.payment_sessions = paymentSessions
return await paymentCollectionRepository.save(payCol)
return await this.setPaymentSessionsBatch(
payCol,
[
{
...sessionInput,
amount: payCol.amount,
session_id: existingSession?.id,
},
],
customerId
)
})
}