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
|
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 =
|
const kycM2mEndpoint =
|
||||||
process.env.KYC_M2M_GRAPHQL_ENDPOINT ?? 'https://kyc.optovia.ru/graphql/m2m'
|
process.env.KYC_M2M_GRAPHQL_ENDPOINT ?? 'https://kyc.optovia.ru/graphql/m2m'
|
||||||
const exchangeM2mEndpoint =
|
const exchangeM2mEndpoint =
|
||||||
@@ -131,3 +143,30 @@ export async function lockCurrencyPrice(input: {
|
|||||||
)
|
)
|
||||||
return data.lockCurrencyPrice
|
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 { ensureDemoWorkspaceData } from '../demo-workspace.js'
|
||||||
import {
|
import {
|
||||||
lockCurrencyPrice,
|
lockCurrencyPrice,
|
||||||
|
convertCurrencyForDisplay,
|
||||||
resolveKycPricingContext,
|
resolveKycPricingContext,
|
||||||
|
type DisplayCurrencyConversion,
|
||||||
type KycPricingContext,
|
type KycPricingContext,
|
||||||
type LockedCurrencyPrice,
|
type LockedCurrencyPrice,
|
||||||
} from '../pricing-context.js'
|
} from '../pricing-context.js'
|
||||||
@@ -112,6 +114,8 @@ export const teamTypeDefs = `#graphql
|
|||||||
sourceCurrency: String
|
sourceCurrency: String
|
||||||
clientAmount: Float!
|
clientAmount: Float!
|
||||||
clientCurrency: String!
|
clientCurrency: String!
|
||||||
|
displayAmount: Float!
|
||||||
|
displayCurrency: String!
|
||||||
exchangeRate: Float
|
exchangeRate: Float
|
||||||
exchangeRateSnapshotUuid: String
|
exchangeRateSnapshotUuid: String
|
||||||
exchangeRateProvider: String
|
exchangeRateProvider: String
|
||||||
@@ -216,6 +220,8 @@ export const teamTypeDefs = `#graphql
|
|||||||
sourceCurrency: String
|
sourceCurrency: String
|
||||||
clientAmount: Float!
|
clientAmount: Float!
|
||||||
clientCurrency: String!
|
clientCurrency: String!
|
||||||
|
displayAmount: Float!
|
||||||
|
displayCurrency: String!
|
||||||
exchangeRate: Float
|
exchangeRate: Float
|
||||||
exchangeRateSnapshotUuid: String
|
exchangeRateSnapshotUuid: String
|
||||||
exchangeRateProvider: String
|
exchangeRateProvider: String
|
||||||
@@ -362,10 +368,10 @@ export const teamTypeDefs = `#graphql
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
getTeamOrders: [Order]
|
getTeamOrders(displayCurrency: String!): [Order]
|
||||||
getOrder(orderUuid: String!): Order
|
getOrder(orderUuid: String!, displayCurrency: String!): Order
|
||||||
quotations(status: String): [Quotation!]!
|
quotations(status: String, displayCurrency: String!): [Quotation!]!
|
||||||
quotation(quotationUuid: String!): Quotation
|
quotation(quotationUuid: String!, displayCurrency: String!): Quotation
|
||||||
tariffReferences(status: String): [TariffReference!]!
|
tariffReferences(status: String): [TariffReference!]!
|
||||||
tariffReference(tariffReferenceUuid: String!): TariffReference
|
tariffReference(tariffReferenceUuid: String!): TariffReference
|
||||||
quotationTariffMatches(quotationUuid: String!): [QuotationTariffMatch!]!
|
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 {
|
return {
|
||||||
uuid: item.uuid,
|
uuid: item.uuid,
|
||||||
teamUuid: item.teamUuid,
|
teamUuid: item.teamUuid,
|
||||||
@@ -582,6 +593,8 @@ function mapQuotation(item: QuotationWithRelations) {
|
|||||||
sourceCurrency: item.sourceCurrency,
|
sourceCurrency: item.sourceCurrency,
|
||||||
clientAmount: Number(item.clientAmount),
|
clientAmount: Number(item.clientAmount),
|
||||||
clientCurrency: item.clientCurrency,
|
clientCurrency: item.clientCurrency,
|
||||||
|
displayAmount,
|
||||||
|
displayCurrency,
|
||||||
exchangeRate: numberFromDecimal(item.exchangeRate),
|
exchangeRate: numberFromDecimal(item.exchangeRate),
|
||||||
exchangeRateSnapshotUuid: item.exchangeRateSnapshotUuid,
|
exchangeRateSnapshotUuid: item.exchangeRateSnapshotUuid,
|
||||||
exchangeRateProvider: item.exchangeRateProvider,
|
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 progress = orderLocationProgress(item.status)
|
||||||
const locationLatitude = interpolateCoordinate(item.sourceLatitude, item.destinationLatitude, progress)
|
const locationLatitude = interpolateCoordinate(item.sourceLatitude, item.destinationLatitude, progress)
|
||||||
const locationLongitude = interpolateCoordinate(item.sourceLongitude, item.destinationLongitude, progress)
|
const locationLongitude = interpolateCoordinate(item.sourceLongitude, item.destinationLongitude, progress)
|
||||||
@@ -615,6 +633,8 @@ function mapLocalOrder(item: OrderWithRelations) {
|
|||||||
sourceCurrency: item.sourceCurrency,
|
sourceCurrency: item.sourceCurrency,
|
||||||
clientAmount: Number(item.clientAmount),
|
clientAmount: Number(item.clientAmount),
|
||||||
clientCurrency: item.clientCurrency,
|
clientCurrency: item.clientCurrency,
|
||||||
|
displayAmount,
|
||||||
|
displayCurrency,
|
||||||
exchangeRate: numberFromDecimal(item.exchangeRate),
|
exchangeRate: numberFromDecimal(item.exchangeRate),
|
||||||
exchangeRateSnapshotUuid: item.exchangeRateSnapshotUuid,
|
exchangeRateSnapshotUuid: item.exchangeRateSnapshotUuid,
|
||||||
exchangeRateProvider: item.exchangeRateProvider,
|
exchangeRateProvider: item.exchangeRateProvider,
|
||||||
@@ -1133,7 +1153,7 @@ async function refreshTeamQuotations(teamUuid: string, actor: { userId: string;
|
|||||||
|
|
||||||
export const teamResolvers = {
|
export const teamResolvers = {
|
||||||
Query: {
|
Query: {
|
||||||
getTeamOrders: async (_: unknown, __: unknown, ctx: AuthContext) => {
|
getTeamOrders: async (_: unknown, args: { displayCurrency: string }, ctx: AuthContext) => {
|
||||||
const access = assertTeamAccess(ctx)
|
const access = assertTeamAccess(ctx)
|
||||||
await ensureClientWorkspaceData(access)
|
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 access = assertTeamAccess(ctx)
|
||||||
|
|
||||||
const order = await prisma.order.findFirst({
|
const order = await prisma.order.findFirst({
|
||||||
@@ -1161,10 +1188,16 @@ export const teamResolvers = {
|
|||||||
include: orderInclude,
|
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)
|
const access = assertTeamAccess(ctx)
|
||||||
await ensureClientWorkspaceData(access)
|
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 access = assertTeamAccess(ctx)
|
||||||
const item = await prisma.quotation.findFirst({
|
const item = await prisma.quotation.findFirst({
|
||||||
where: {
|
where: {
|
||||||
@@ -1191,7 +1231,13 @@ export const teamResolvers = {
|
|||||||
},
|
},
|
||||||
include: quotationInclude,
|
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) => {
|
tariffReferences: async (_: unknown, args: { status?: string | null }, ctx: AuthContext) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user