Expose live display currency for transactions
Build and deploy Docker image / build (push) Successful in 1m25s
Build and deploy Docker image / build (push) Successful in 1m25s
This commit is contained in:
+1
-1
Submodule graphql-contracts updated: e2627cb00d...1ea758ddd4
@@ -25,6 +25,18 @@ export type LockedCurrencyPrice = {
|
||||
pricingCountryCode: string
|
||||
}
|
||||
|
||||
export type DisplayCurrencyConversion = {
|
||||
sourceAmount: number
|
||||
sourceCurrency: string
|
||||
displayAmount: number
|
||||
displayCurrency: string
|
||||
exchangeRate: number
|
||||
rateSnapshotUuid: string | null
|
||||
rateEffectiveDate: string
|
||||
rateQuotedAt: string
|
||||
provider: string
|
||||
}
|
||||
|
||||
const kycM2mEndpoint =
|
||||
process.env.KYC_M2M_GRAPHQL_ENDPOINT ?? 'https://kyc.optovia.ru/graphql/m2m'
|
||||
const exchangeM2mEndpoint =
|
||||
@@ -131,3 +143,30 @@ export async function lockCurrencyPrice(input: {
|
||||
)
|
||||
return data.lockCurrencyPrice
|
||||
}
|
||||
|
||||
export async function convertCurrencyForDisplay(input: {
|
||||
amount: number
|
||||
sourceCurrency: string
|
||||
displayCurrency: string
|
||||
}): Promise<DisplayCurrencyConversion> {
|
||||
const data = await requestGraphql<{
|
||||
convertCurrencyForDisplay: DisplayCurrencyConversion
|
||||
}>(
|
||||
exchangeM2mEndpoint,
|
||||
`query OrdersConvertCurrencyForDisplay($input: ConvertCurrencyForDisplayInput!) {
|
||||
convertCurrencyForDisplay(input: $input) {
|
||||
sourceAmount
|
||||
sourceCurrency
|
||||
displayAmount
|
||||
displayCurrency
|
||||
exchangeRate
|
||||
rateSnapshotUuid
|
||||
rateEffectiveDate
|
||||
rateQuotedAt
|
||||
provider
|
||||
}
|
||||
}`,
|
||||
{ input },
|
||||
)
|
||||
return data.convertCurrencyForDisplay
|
||||
}
|
||||
|
||||
+60
-14
@@ -11,7 +11,9 @@ import { prisma } from '../db.js'
|
||||
import { ensureDemoWorkspaceData } from '../demo-workspace.js'
|
||||
import {
|
||||
lockCurrencyPrice,
|
||||
convertCurrencyForDisplay,
|
||||
resolveKycPricingContext,
|
||||
type DisplayCurrencyConversion,
|
||||
type KycPricingContext,
|
||||
type LockedCurrencyPrice,
|
||||
} from '../pricing-context.js'
|
||||
@@ -112,6 +114,8 @@ export const teamTypeDefs = `#graphql
|
||||
sourceCurrency: String
|
||||
clientAmount: Float!
|
||||
clientCurrency: String!
|
||||
displayAmount: Float!
|
||||
displayCurrency: String!
|
||||
exchangeRate: Float
|
||||
exchangeRateSnapshotUuid: String
|
||||
exchangeRateProvider: String
|
||||
@@ -216,6 +220,8 @@ export const teamTypeDefs = `#graphql
|
||||
sourceCurrency: String
|
||||
clientAmount: Float!
|
||||
clientCurrency: String!
|
||||
displayAmount: Float!
|
||||
displayCurrency: String!
|
||||
exchangeRate: Float
|
||||
exchangeRateSnapshotUuid: String
|
||||
exchangeRateProvider: String
|
||||
@@ -362,10 +368,10 @@ export const teamTypeDefs = `#graphql
|
||||
}
|
||||
|
||||
type Query {
|
||||
getTeamOrders: [Order]
|
||||
getOrder(orderUuid: String!): Order
|
||||
quotations(status: String): [Quotation!]!
|
||||
quotation(quotationUuid: String!): Quotation
|
||||
getTeamOrders(displayCurrency: String!): [Order]
|
||||
getOrder(orderUuid: String!, displayCurrency: String!): Order
|
||||
quotations(status: String, displayCurrency: String!): [Quotation!]!
|
||||
quotation(quotationUuid: String!, displayCurrency: String!): Quotation
|
||||
tariffReferences(status: String): [TariffReference!]!
|
||||
tariffReference(tariffReferenceUuid: String!): TariffReference
|
||||
quotationTariffMatches(quotationUuid: String!): [QuotationTariffMatch!]!
|
||||
@@ -547,7 +553,12 @@ function mapQuotationChange(item: PrismaQuotationChange) {
|
||||
}
|
||||
}
|
||||
|
||||
function mapQuotation(item: QuotationWithRelations) {
|
||||
function mapQuotation(
|
||||
item: QuotationWithRelations,
|
||||
display?: DisplayCurrencyConversion,
|
||||
) {
|
||||
const displayAmount = display?.displayAmount ?? Number(item.clientAmount)
|
||||
const displayCurrency = display?.displayCurrency ?? item.clientCurrency
|
||||
return {
|
||||
uuid: item.uuid,
|
||||
teamUuid: item.teamUuid,
|
||||
@@ -582,6 +593,8 @@ function mapQuotation(item: QuotationWithRelations) {
|
||||
sourceCurrency: item.sourceCurrency,
|
||||
clientAmount: Number(item.clientAmount),
|
||||
clientCurrency: item.clientCurrency,
|
||||
displayAmount,
|
||||
displayCurrency,
|
||||
exchangeRate: numberFromDecimal(item.exchangeRate),
|
||||
exchangeRateSnapshotUuid: item.exchangeRateSnapshotUuid,
|
||||
exchangeRateProvider: item.exchangeRateProvider,
|
||||
@@ -600,7 +613,12 @@ function mapQuotation(item: QuotationWithRelations) {
|
||||
}
|
||||
}
|
||||
|
||||
function mapLocalOrder(item: OrderWithRelations) {
|
||||
function mapLocalOrder(
|
||||
item: OrderWithRelations,
|
||||
display?: DisplayCurrencyConversion,
|
||||
) {
|
||||
const displayAmount = display?.displayAmount ?? Number(item.clientAmount)
|
||||
const displayCurrency = display?.displayCurrency ?? item.clientCurrency
|
||||
const progress = orderLocationProgress(item.status)
|
||||
const locationLatitude = interpolateCoordinate(item.sourceLatitude, item.destinationLatitude, progress)
|
||||
const locationLongitude = interpolateCoordinate(item.sourceLongitude, item.destinationLongitude, progress)
|
||||
@@ -615,6 +633,8 @@ function mapLocalOrder(item: OrderWithRelations) {
|
||||
sourceCurrency: item.sourceCurrency,
|
||||
clientAmount: Number(item.clientAmount),
|
||||
clientCurrency: item.clientCurrency,
|
||||
displayAmount,
|
||||
displayCurrency,
|
||||
exchangeRate: numberFromDecimal(item.exchangeRate),
|
||||
exchangeRateSnapshotUuid: item.exchangeRateSnapshotUuid,
|
||||
exchangeRateProvider: item.exchangeRateProvider,
|
||||
@@ -1133,7 +1153,7 @@ async function refreshTeamQuotations(teamUuid: string, actor: { userId: string;
|
||||
|
||||
export const teamResolvers = {
|
||||
Query: {
|
||||
getTeamOrders: async (_: unknown, __: unknown, ctx: AuthContext) => {
|
||||
getTeamOrders: async (_: unknown, args: { displayCurrency: string }, ctx: AuthContext) => {
|
||||
const access = assertTeamAccess(ctx)
|
||||
await ensureClientWorkspaceData(access)
|
||||
|
||||
@@ -1147,10 +1167,17 @@ export const teamResolvers = {
|
||||
},
|
||||
})
|
||||
|
||||
return localOrders.map(mapLocalOrder)
|
||||
return Promise.all(localOrders.map(async item => mapLocalOrder(
|
||||
item,
|
||||
await convertCurrencyForDisplay({
|
||||
amount: Number(item.clientAmount),
|
||||
sourceCurrency: item.clientCurrency,
|
||||
displayCurrency: args.displayCurrency,
|
||||
}),
|
||||
)))
|
||||
},
|
||||
|
||||
getOrder: async (_: unknown, args: { orderUuid: string }, ctx: AuthContext) => {
|
||||
getOrder: async (_: unknown, args: { orderUuid: string; displayCurrency: string }, ctx: AuthContext) => {
|
||||
const access = assertTeamAccess(ctx)
|
||||
|
||||
const order = await prisma.order.findFirst({
|
||||
@@ -1161,10 +1188,16 @@ export const teamResolvers = {
|
||||
include: orderInclude,
|
||||
})
|
||||
|
||||
return order ? mapLocalOrder(order) : null
|
||||
if (order === null) return null
|
||||
const display = await convertCurrencyForDisplay({
|
||||
amount: Number(order.clientAmount),
|
||||
sourceCurrency: order.clientCurrency,
|
||||
displayCurrency: args.displayCurrency,
|
||||
})
|
||||
return mapLocalOrder(order, display)
|
||||
},
|
||||
|
||||
quotations: async (_: unknown, args: { status?: string | null }, ctx: AuthContext) => {
|
||||
quotations: async (_: unknown, args: { status?: string | null; displayCurrency: string }, ctx: AuthContext) => {
|
||||
const access = assertTeamAccess(ctx)
|
||||
await ensureClientWorkspaceData(access)
|
||||
|
||||
@@ -1179,10 +1212,17 @@ export const teamResolvers = {
|
||||
},
|
||||
})
|
||||
|
||||
return items.map(mapQuotation)
|
||||
return Promise.all(items.map(async item => mapQuotation(
|
||||
item,
|
||||
await convertCurrencyForDisplay({
|
||||
amount: Number(item.clientAmount),
|
||||
sourceCurrency: item.clientCurrency,
|
||||
displayCurrency: args.displayCurrency,
|
||||
}),
|
||||
)))
|
||||
},
|
||||
|
||||
quotation: async (_: unknown, args: { quotationUuid: string }, ctx: AuthContext) => {
|
||||
quotation: async (_: unknown, args: { quotationUuid: string; displayCurrency: string }, ctx: AuthContext) => {
|
||||
const access = assertTeamAccess(ctx)
|
||||
const item = await prisma.quotation.findFirst({
|
||||
where: {
|
||||
@@ -1191,7 +1231,13 @@ export const teamResolvers = {
|
||||
},
|
||||
include: quotationInclude,
|
||||
})
|
||||
return item ? mapQuotation(item) : null
|
||||
if (item === null) return null
|
||||
const display = await convertCurrencyForDisplay({
|
||||
amount: Number(item.clientAmount),
|
||||
sourceCurrency: item.clientCurrency,
|
||||
displayCurrency: args.displayCurrency,
|
||||
})
|
||||
return mapQuotation(item, display)
|
||||
},
|
||||
|
||||
tariffReferences: async (_: unknown, args: { status?: string | null }, ctx: AuthContext) => {
|
||||
|
||||
Reference in New Issue
Block a user