Use geo offers for quote results
All checks were successful
Build Docker Image / build (push) Successful in 5m9s
All checks were successful
Build Docker Image / build (push) Successful in 5m9s
This commit is contained in:
@@ -34,7 +34,8 @@
|
|||||||
:quantity="offer.quantity"
|
:quantity="offer.quantity"
|
||||||
:currency="offer.currency"
|
:currency="offer.currency"
|
||||||
:unit="offer.unit"
|
:unit="offer.unit"
|
||||||
:stages="[]"
|
:stages="getOfferStages(offer)"
|
||||||
|
:total-time-seconds="offer.routes?.[0]?.totalTimeSeconds ?? null"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -48,6 +49,7 @@ interface Offer {
|
|||||||
productName?: string | null
|
productName?: string | null
|
||||||
productUuid?: string | null
|
productUuid?: string | null
|
||||||
supplierName?: string | null
|
supplierName?: string | null
|
||||||
|
supplierUuid?: string | null
|
||||||
quantity?: number | string | null
|
quantity?: number | string | null
|
||||||
unit?: string | null
|
unit?: string | null
|
||||||
pricePerUnit?: number | string | null
|
pricePerUnit?: number | string | null
|
||||||
@@ -55,6 +57,15 @@ interface Offer {
|
|||||||
locationName?: string | null
|
locationName?: string | null
|
||||||
locationCountry?: string | null
|
locationCountry?: string | null
|
||||||
locationCountryCode?: string | null
|
locationCountryCode?: string | null
|
||||||
|
routes?: Array<{
|
||||||
|
totalTimeSeconds?: number | null
|
||||||
|
stages?: Array<{
|
||||||
|
transportType?: string | null
|
||||||
|
distanceKm?: number | null
|
||||||
|
travelTimeSeconds?: number | null
|
||||||
|
fromName?: string | null
|
||||||
|
} | null> | null
|
||||||
|
} | null> | null
|
||||||
}
|
}
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -69,4 +80,17 @@ const props = defineProps<{
|
|||||||
const offersWithPrice = computed(() =>
|
const offersWithPrice = computed(() =>
|
||||||
(props.offers || []).filter(o => o?.pricePerUnit != null)
|
(props.offers || []).filter(o => o?.pricePerUnit != null)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const getOfferStages = (offer: Offer) => {
|
||||||
|
const route = offer.routes?.[0]
|
||||||
|
if (!route?.stages) return []
|
||||||
|
return route.stages
|
||||||
|
.filter((stage): stage is NonNullable<typeof stage> => stage !== null)
|
||||||
|
.map((stage) => ({
|
||||||
|
transportType: stage.transportType,
|
||||||
|
distanceKm: stage.distanceKm,
|
||||||
|
travelTimeSeconds: stage.travelTimeSeconds,
|
||||||
|
fromName: stage.fromName
|
||||||
|
}))
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -83,11 +83,33 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { GetOffersDocument, GetOfferDocument, type GetOffersQueryVariables, type GetOffersQueryResult } from '~/composables/graphql/public/exchange-generated'
|
import { GetOffersDocument, GetOfferDocument, type GetOffersQueryVariables } from '~/composables/graphql/public/exchange-generated'
|
||||||
|
import { GetNodeDocument, NearestOffersDocument } from '~/composables/graphql/public/geo-generated'
|
||||||
import type { MapBounds } from '~/components/catalog/CatalogMap.vue'
|
import type { MapBounds } from '~/components/catalog/CatalogMap.vue'
|
||||||
|
|
||||||
// Offer type from search results
|
type QuoteOffer = {
|
||||||
type OfferResult = NonNullable<NonNullable<GetOffersQueryResult['getOffers']>[number]>
|
uuid: string
|
||||||
|
productUuid?: string | null
|
||||||
|
productName?: string | null
|
||||||
|
supplierUuid?: string | null
|
||||||
|
supplierName?: string | null
|
||||||
|
teamUuid?: string | null
|
||||||
|
quantity?: number | string | null
|
||||||
|
unit?: string | null
|
||||||
|
pricePerUnit?: number | string | null
|
||||||
|
currency?: string | null
|
||||||
|
locationName?: string | null
|
||||||
|
locationCountry?: string | null
|
||||||
|
routes?: Array<{
|
||||||
|
totalTimeSeconds?: number | null
|
||||||
|
stages?: Array<{
|
||||||
|
transportType?: string | null
|
||||||
|
distanceKm?: number | null
|
||||||
|
travelTimeSeconds?: number | null
|
||||||
|
fromName?: string | null
|
||||||
|
} | null> | null
|
||||||
|
} | null> | null
|
||||||
|
}
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: 'topnav'
|
layout: 'topnav'
|
||||||
@@ -393,7 +415,7 @@ const relatedPoints = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Offers data for quote results
|
// Offers data for quote results
|
||||||
const offers = ref<OfferResult[]>([])
|
const offers = ref<QuoteOffer[]>([])
|
||||||
const offersLoading = ref(false)
|
const offersLoading = ref(false)
|
||||||
const showQuoteResults = ref(false)
|
const showQuoteResults = ref(false)
|
||||||
|
|
||||||
@@ -574,24 +596,69 @@ const onSearch = async () => {
|
|||||||
showQuoteResults.value = true
|
showQuoteResults.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const vars: GetOffersQueryVariables = {}
|
// Prefer geo-based offers with routes when hub + product are selected
|
||||||
if (productId.value) vars.productUuid = productId.value
|
if (hubId.value && productId.value) {
|
||||||
if (supplierId.value) vars.teamUuid = supplierId.value
|
const hubData = await execute(GetNodeDocument, { uuid: hubId.value }, 'public', 'geo')
|
||||||
if (hubId.value) vars.locationUuid = hubId.value
|
const hub = hubData?.node
|
||||||
|
if (hub?.latitude != null && hub?.longitude != null) {
|
||||||
|
const geoData = await execute(
|
||||||
|
NearestOffersDocument,
|
||||||
|
{
|
||||||
|
lat: hub.latitude,
|
||||||
|
lon: hub.longitude,
|
||||||
|
productUuid: productId.value,
|
||||||
|
hubUuid: hubId.value,
|
||||||
|
radius: 500,
|
||||||
|
limit: 12
|
||||||
|
},
|
||||||
|
'public',
|
||||||
|
'geo'
|
||||||
|
)
|
||||||
|
|
||||||
const data = await execute(GetOffersDocument, vars, 'public', 'exchange')
|
let nearest = (geoData?.nearestOffers || []).filter((o): o is QuoteOffer => o !== null)
|
||||||
offers.value = (data?.getOffers || []).filter((o): o is OfferResult => o !== null)
|
if (supplierId.value) {
|
||||||
|
nearest = nearest.filter(o => o?.supplierUuid === supplierId.value)
|
||||||
|
}
|
||||||
|
offers.value = nearest
|
||||||
|
|
||||||
// Update labels from response
|
const first = offers.value[0]
|
||||||
const first = offers.value[0]
|
if (first?.productName) {
|
||||||
if (first) {
|
setLabel('product', productId.value, first.productName)
|
||||||
if (productId.value && first.productName) {
|
}
|
||||||
setLabel('product', productId.value, first.productName)
|
} else {
|
||||||
|
offers.value = []
|
||||||
}
|
}
|
||||||
if (hubId.value && first.locationName) {
|
} else {
|
||||||
setLabel('hub', hubId.value, first.locationName)
|
const vars: GetOffersQueryVariables = {}
|
||||||
|
if (productId.value) vars.productUuid = productId.value
|
||||||
|
if (supplierId.value) vars.teamUuid = supplierId.value
|
||||||
|
if (hubId.value) vars.locationUuid = hubId.value
|
||||||
|
|
||||||
|
const data = await execute(GetOffersDocument, vars, 'public', 'exchange')
|
||||||
|
const exchangeOffers = (data?.getOffers || []).filter((o): o is NonNullable<typeof o> => o !== null)
|
||||||
|
offers.value = exchangeOffers.map((offer) => ({
|
||||||
|
uuid: offer.uuid,
|
||||||
|
productUuid: offer.productUuid,
|
||||||
|
productName: offer.productName,
|
||||||
|
teamUuid: offer.teamUuid,
|
||||||
|
quantity: offer.quantity,
|
||||||
|
unit: offer.unit,
|
||||||
|
pricePerUnit: offer.pricePerUnit,
|
||||||
|
currency: offer.currency,
|
||||||
|
locationName: offer.locationName,
|
||||||
|
locationCountry: offer.locationCountry
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Update labels from response
|
||||||
|
const first = offers.value[0]
|
||||||
|
if (first) {
|
||||||
|
if (productId.value && first.productName) {
|
||||||
|
setLabel('product', productId.value, first.productName)
|
||||||
|
}
|
||||||
|
if (hubId.value && first.locationName) {
|
||||||
|
setLabel('hub', hubId.value, first.locationName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Note: teamName not included in GetOffers query, supplier label cannot be updated from offer
|
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
offersLoading.value = false
|
offersLoading.value = false
|
||||||
|
|||||||
Reference in New Issue
Block a user