@bisondesk/core-sdk 1.0.596 → 1.0.598
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/apis/country-delivery.d.ts +3 -0
- package/lib/apis/country-delivery.d.ts.map +1 -0
- package/lib/apis/{country-pricing.js → country-delivery.js} +3 -3
- package/lib/apis/country-delivery.js.map +1 -0
- package/lib/constants.d.ts +0 -1
- package/lib/constants.d.ts.map +1 -1
- package/lib/constants.js +0 -1
- package/lib/constants.js.map +1 -1
- package/lib/types/country-delivery.d.ts +18 -0
- package/lib/types/country-delivery.d.ts.map +1 -0
- package/lib/types/country-delivery.js +2 -0
- package/lib/types/country-delivery.js.map +1 -0
- package/lib/types/exchange-rates.d.ts +6 -0
- package/lib/types/exchange-rates.d.ts.map +1 -0
- package/lib/types/exchange-rates.js +2 -0
- package/lib/types/exchange-rates.js.map +1 -0
- package/lib/types/marketing.d.ts +1 -0
- package/lib/types/marketing.d.ts.map +1 -1
- package/lib/types/marketing.js.map +1 -1
- package/lib/types/quote-settings.d.ts +4 -0
- package/lib/types/quote-settings.d.ts.map +1 -1
- package/lib/types/quote-settings.js.map +1 -1
- package/lib/types/vehicles.d.ts +11 -7
- package/lib/types/vehicles.d.ts.map +1 -1
- package/lib/types/vehicles.js.map +1 -1
- package/lib/utils/exchange-rates.d.ts +3 -0
- package/lib/utils/exchange-rates.d.ts.map +1 -0
- package/lib/utils/exchange-rates.js +15 -0
- package/lib/utils/exchange-rates.js.map +1 -0
- package/lib/utils/exchange-rates.test.d.ts +2 -0
- package/lib/utils/exchange-rates.test.d.ts.map +1 -0
- package/lib/utils/exchange-rates.test.js +23 -0
- package/lib/utils/exchange-rates.test.js.map +1 -0
- package/package.json +3 -3
- package/src/apis/{country-pricing.ts → country-delivery.ts} +5 -3
- package/src/constants.ts +0 -1
- package/src/types/country-delivery.ts +42 -0
- package/src/types/exchange-rates.ts +10 -0
- package/src/types/marketing.ts +12 -0
- package/src/types/quote-settings.ts +4 -0
- package/src/types/vehicles.ts +45 -4
- package/src/utils/exchange-rates.test.ts +29 -0
- package/src/utils/exchange-rates.ts +32 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/apis/country-pricing.d.ts +0 -3
- package/lib/apis/country-pricing.d.ts.map +0 -1
- package/lib/apis/country-pricing.js.map +0 -1
- package/lib/types/country-pricing.d.ts +0 -16
- package/lib/types/country-pricing.d.ts.map +0 -1
- package/lib/types/country-pricing.js +0 -2
- package/lib/types/country-pricing.js.map +0 -1
- package/lib/utils/country-pricing.d.ts +0 -5
- package/lib/utils/country-pricing.d.ts.map +0 -1
- package/lib/utils/country-pricing.js +0 -17
- package/lib/utils/country-pricing.js.map +0 -1
- package/lib/utils/country-pricing.test.d.ts +0 -2
- package/lib/utils/country-pricing.test.d.ts.map +0 -1
- package/lib/utils/country-pricing.test.js +0 -65
- package/lib/utils/country-pricing.test.js.map +0 -1
- package/src/types/activities.js +0 -13
- package/src/types/activities.js.map +0 -1
- package/src/types/comparables.js +0 -2
- package/src/types/comparables.js.map +0 -1
- package/src/types/country-pricing.ts +0 -25
- package/src/types/crm.js +0 -58
- package/src/types/crm.js.map +0 -1
- package/src/types/dashboard.js +0 -2
- package/src/types/dashboard.js.map +0 -1
- package/src/types/definitions.js +0 -2
- package/src/types/definitions.js.map +0 -1
- package/src/types/fields.js +0 -2
- package/src/types/fields.js.map +0 -1
- package/src/types/insights.js +0 -2
- package/src/types/insights.js.map +0 -1
- package/src/types/interests.js +0 -6
- package/src/types/interests.js.map +0 -1
- package/src/types/internal-events.js +0 -18
- package/src/types/internal-events.js.map +0 -1
- package/src/types/internet-opportunities.js +0 -2
- package/src/types/internet-opportunities.js.map +0 -1
- package/src/types/internet-vehicles.js +0 -2
- package/src/types/internet-vehicles.js.map +0 -1
- package/src/types/leasing-administration.js +0 -2
- package/src/types/leasing-administration.js.map +0 -1
- package/src/types/leasing-debtors.js +0 -2
- package/src/types/leasing-debtors.js.map +0 -1
- package/src/types/leasing-search.js +0 -2
- package/src/types/leasing-search.js.map +0 -1
- package/src/types/leasing-settings.js +0 -7
- package/src/types/leasing-settings.js.map +0 -1
- package/src/types/leasing.js +0 -38
- package/src/types/leasing.js.map +0 -1
- package/src/types/marketing.js +0 -35
- package/src/types/marketing.js.map +0 -1
- package/src/types/offers.js +0 -56
- package/src/types/opportunities.js +0 -107
- package/src/types/opportunities.js.map +0 -1
- package/src/types/payments.js +0 -7
- package/src/types/picklists.js +0 -2
- package/src/types/picklists.js.map +0 -1
- package/src/types/quotes.js +0 -42
- package/src/types/recently-viewed.js +0 -2
- package/src/types/recently-viewed.js.map +0 -1
- package/src/types/reservations.js +0 -5
- package/src/types/reservations.js.map +0 -1
- package/src/types/roi-ratings.js +0 -5
- package/src/types/roi-ratings.js.map +0 -1
- package/src/types/saved-filters.js +0 -9
- package/src/types/saved-filters.js.map +0 -1
- package/src/types/search.js +0 -2
- package/src/types/search.js.map +0 -1
- package/src/types/settings.js +0 -2
- package/src/types/settings.js.map +0 -1
- package/src/types/templates.js +0 -2
- package/src/types/templates.js.map +0 -1
- package/src/types/tenants.js +0 -21
- package/src/types/tenants.js.map +0 -1
- package/src/types/user-performance.js +0 -7
- package/src/types/user-performance.js.map +0 -1
- package/src/types/utils.js +0 -2
- package/src/types/validation.js +0 -2
- package/src/types/validation.js.map +0 -1
- package/src/types/vehicle-sales.js +0 -6
- package/src/types/vehicle-sales.js.map +0 -1
- package/src/types/vehicles.js +0 -98
- package/src/types/vehicles.js.map +0 -1
- package/src/utils/country-pricing.test.ts +0 -82
- package/src/utils/country-pricing.ts +0 -44
- package/src/utils/leasing.js +0 -6
- package/src/utils/leasing.js.map +0 -1
- package/src/utils/opportunities.js +0 -48
- package/src/utils/opportunities.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vehicles.js","sourceRoot":"/","sources":["types/vehicles.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AttachmentValue,\n Document,\n LocationValue,\n MultiLangValue,\n PaginatedRequest,\n SearchPermissions,\n ShareEmailRequest,\n ShareWhatsappRequest,\n} from '@bisondesk/commons-sdk/types';\nimport { ReferenceData } from '@bisondesk/commons-sdk/utils';\nimport { BaseEvent } from './internal-events.js';\nimport { VehicleSaleLogisticsStatus } from './opportunities.js';\nimport { OpportunityReservation } from './reservations.js';\nimport { ComplexFilter, Filter } from './search.js';\nimport { Transport } from './transports.js';\nimport { DataRecord } from './utils.js';\nimport { VehicleBusinessOverviewXL } from './vehicle-performance.js';\nimport { VehicleSaleInfo } from './vehicle-sales.js';\n\nexport enum VehicleRoles {\n SALE = 'SALE',\n OWN_USE = 'OWN_USE',\n RENTAL = 'RENTAL',\n BUILD = 'BUILD',\n UNKNOWN = 'UNKNOWN',\n BANK_FINANCE = 'BANK_FINANCE',\n}\n\nexport enum VehicleFuelType {\n Petrol = 'PETROL',\n Diesel = 'DIESEL',\n LPG = 'LPG',\n LPG_G3 = 'LPG_G3',\n Electric = 'ELECTRIC',\n CNG = 'CNG',\n Hydrogen = 'HYDROGEN',\n BioEthanol = 'BIO_ETHANOL',\n BioDiesel = 'BIO_DIESEL',\n E85 = 'E85',\n HCNG = 'HCNG',\n LPG_Petrol = 'LPG_PETROL',\n LPG_Diesel = 'LPG_DIESEL',\n LPG_G3_Petrol = 'LPG_G3_PETROL',\n LPG_G3_Diesel = 'LPG_G3_DIESEL',\n Electric_Diesel = 'ELECTRIC_DIESEL',\n Electric_Petrol = 'ELECTRIC_PETROL',\n Hybrid = 'HYBRID',\n Other = 'OTHER',\n}\n\nexport enum VehicleTachoTypes {\n Analog = 'ANALOG',\n Digital = 'DIGITAL',\n SmartTacho1 = 'SMART_TACHO_1',\n SmartTacho2 = 'SMART_TACHO_2',\n}\n\ntype BaseVehicleEvent = BaseEvent & {\n id: string;\n actionAt: string;\n userId: string;\n tenantId: string;\n};\n\ntype VehicleSuperstructure = {\n carCapacity?: number;\n compartmentCount?: number;\n counter?: boolean;\n crane?: {\n make?: string;\n model?: string;\n position?: 'Behind the cabin' | 'Rear';\n present?: boolean;\n year?: number;\n };\n dimensions?: {\n height?: number;\n length?: number;\n width?: number;\n extended?: string; // L1, L2, ...\n heightened?: string; // H1, H2, ...\n };\n baseVehicle?: SuperstructureBaseVehicle;\n extendable?: boolean;\n highPressurePump?: boolean;\n loadingPlatformHeight?: number;\n pump?: boolean;\n slidingRoof?: boolean;\n tailgate?: {\n capacity?: number;\n make?: string;\n model?: string;\n present?: boolean;\n type?: 'slider_lift' | 'cantilever' | 'column_lift';\n };\n tank?: {\n capacity: number; //litters\n volume?: number; //m3\n };\n temperatureControl?: {\n engineType?: 'diesel' | 'electric' | 'diesel+electric' | 'engine';\n make?: string;\n runningHours?: {\n diesel?: number;\n electric?: number;\n };\n };\n tipper?: {\n tipsBack?: boolean;\n tipsLeft?: boolean;\n tipsRight?: boolean;\n };\n};\n\nexport type NewVehicleRequest = {\n branch: string;\n count: number;\n specs: VehicleExternalInfo;\n description: {\n remarks?: string;\n technicalRemarks?: string;\n };\n salesConditions?: {\n marginScheme?: boolean;\n manufacturerWarranty?: {\n remarks?: string;\n available?: boolean;\n };\n };\n logistics: {\n parking?: string;\n deliveryType?: VehiclePurchaseDeliveryType;\n pickupAddress?: LocationValue;\n status: VehiclePurchaseLogisticsStatus;\n };\n prices: {\n minimum?: string;\n premium?: string;\n internet?: string;\n };\n media: {\n internalPictures: AttachmentValue[];\n pictures: AttachmentValue[];\n videos: AttachmentValue[];\n docs: Document[];\n engineeringDocs: Document[];\n };\n vinList?: string;\n deal: {\n offerId?: string;\n stockNumber?: string;\n contactId: string;\n orgId: string;\n purchasedBy: string;\n purchaseAssistedBy?: string;\n readyToDeliver?: boolean;\n dealStatus: VehiclePurchaseDealStatus;\n costs: {\n purchase: string;\n purchaseVatPercentage: string;\n commission?: string;\n externalTransport?: string;\n internalTransport?: string;\n externalGarage?: string;\n internalGarage?: string;\n other?: string;\n bonus?: string;\n };\n logistics: {\n availableDate?: string;\n vehicleRole: VehicleRoles;\n };\n };\n};\n\nexport type VehicleCreateEvent = BaseVehicleEvent & {\n action: 'create';\n vehicle: Vehicle;\n previousVehicle?: undefined;\n};\n\nexport type VehicleUpdateEvent = BaseVehicleEvent & {\n action: 'update';\n vehicle: Vehicle;\n previousVehicle: Vehicle;\n};\n\nexport type VehicleDeleteEvent = BaseVehicleEvent & {\n action: 'delete';\n vehicle?: undefined;\n previousVehicle: Vehicle;\n};\n\nexport type VehicleEvent = VehicleCreateEvent | VehicleUpdateEvent | VehicleDeleteEvent;\n\ntype BaseVehiclePurchaseEvent = {\n actionAt: string;\n userId: string;\n tenantId: string;\n branchId: string;\n vehicleId: string;\n};\n\nexport type VehiclePurchaseCreateEvent = BaseVehiclePurchaseEvent & {\n action: 'create';\n data: VehiclePurchase;\n previousData?: undefined;\n};\n\nexport type VehiclePurchaseUpdateEvent = BaseVehiclePurchaseEvent & {\n action: 'update';\n data: VehiclePurchase;\n previousData: VehiclePurchase;\n};\n\nexport type VehiclePurchaseEvent = BaseEvent &\n (VehiclePurchaseCreateEvent | VehiclePurchaseUpdateEvent);\n\nexport type UpdateVehiclesPricesEvent = {\n id: string;\n actionAt: string;\n userId: string;\n tenantId: string;\n priceList: AttachmentValue;\n};\n\nexport type PublicVehicle = Pick<Vehicle, 'external' | 'id'>;\n\nexport type PublicSearchVehicle = {\n vehicle: PublicVehicle;\n};\n\nexport enum SearchVehicleSaleDealStatus {\n NotSold = 'NOT_SOLD',\n Reserved = 'RESERVED',\n Sold = 'SOLD',\n}\n\nexport type SearchVehicle = {\n custom: {\n features: string[];\n sold: boolean;\n isReserved: boolean;\n hasPayments: boolean;\n listedOnWebsite: boolean;\n publishedOnWebsiteAt?: string;\n originalBranchId: string;\n };\n customSortableFields: {\n priceChangedAt?: string;\n checkedInAt?: string;\n saleAgreementAt?: string;\n };\n purchase?: {\n supplierStockNumber?: string;\n readyToDeliver: boolean;\n dealStatus?: VehiclePurchaseDealStatus;\n logisticsStatus?: VehiclePurchaseLogisticsStatus;\n purchasedBy?: string;\n parkingName?: string;\n organizationId: string;\n organizationExternalId?: number;\n fullPaymentSentAt?: string;\n marketingStartedAt?: string;\n arrivedAt?: string;\n };\n reservation?: Pick<OpportunityReservation, 'expiresAt' | 'opportunityId' | 'createdBy'>;\n transports: Transport[];\n vehicle: Vehicle;\n sale: {\n opportunityId?: string;\n externalSaleId?: string;\n soldAt?: string;\n soldBy?: string;\n sellers?: string[]; // opportunity account manager [+ assistant]\n dealStatus: SearchVehicleSaleDealStatus;\n logisticStatus?: VehicleSaleLogisticsStatus;\n };\n};\n\nexport type InputSearchVehicle = SearchVehicle & {\n permissions?: SearchPermissions;\n};\n\nexport type VehicleSearchMeta = ReferenceData & {\n matchingOffers?: {\n count: number;\n filters: {\n conditions: Array<Filter | ComplexFilter>;\n fullText?: string;\n };\n };\n};\n\nexport type PriceChangeEvent = BaseEvent & {\n tenantId: string;\n userId: string;\n vehicleId: string;\n input: {\n previousPrices: VehiclePricingHistoryInput;\n currentPrices: VehiclePricingHistoryInput;\n };\n};\n\nexport type VehiclePricingHistory = {\n pricing: VehiclePricingHistoryInput;\n createdAt: string;\n createdBy: string;\n};\n\nexport type VehiclePricingHistoryInput = VehiclePricing & { internet?: string };\n\nexport type VehiclePricing = {\n premium?: string;\n minimum?: string;\n currency?: string;\n};\n\nexport type RelatedVehicle = {\n vehicleId: string;\n description: string;\n stockNumber: string;\n};\n\nexport type VehicleInternalInfo = {\n createdAt: string;\n description: {\n title: string;\n remarks?: string;\n technicalRemarks?: string;\n };\n identification: {\n administrativeNumber?: string;\n stockNumber: string;\n branch: string;\n\n offerId?: string;\n licensePlateHistory?: {\n licensePlate: string;\n changedAt: string;\n }[];\n\n /**\n * This ID is used to link different vehicle objects that represent the same real world asset.\n * Ideally the chassis number could be used, but in some cases it is not available yet.\n */\n metaId: string;\n };\n documents: Document[];\n pictures: AttachmentValue[];\n engineeringDocs: Document[];\n pricing: VehiclePricing;\n role: VehicleRoles;\n status: VehicleStatus;\n updatedAt: string;\n /* use this property to store additional terms that you want the vehicle to be found with when doing a full text search */\n keywords?: string[];\n relatedVehicles: RelatedVehicle[];\n};\n\nexport type VehicleOriginalInfo = {\n /** IMMEDIATE source tenant (the predecessor in a sync chain). */\n tenantId: string;\n tenantChain?: string[];\n identification: {\n id: string;\n branchId: string;\n stockNumber: string;\n metaId?: string;\n country: string;\n };\n salesConditions: {\n leasing?: boolean;\n price?: string;\n currency?: string;\n marginScheme?: boolean;\n manufacturerWarranty?: {\n remarks?: string;\n available?: boolean;\n };\n };\n /**\n * Deepest-origin tenant/branch in a multi-hop sync chain. Carries forward\n * verbatim across hops so consumers can answer \"where did this vehicle\n * actually originate?\" without walking the chain.\n */\n owner: {\n tenantId: string;\n branchId: string;\n country: string;\n };\n};\n\nexport type VehicleAxlesInfo = {\n details?: VehicleAxle[];\n configuration?: string;\n count?: number;\n poweredAxlesCount?: number;\n wheelbase?: number;\n suspension?: 'Air' | 'Air/Steel' | 'Steel';\n loadCapacity?: number;\n};\n\nexport type SuperstructureBaseVehicle = {\n category: string;\n make: string;\n model?: string;\n type?: string;\n axlesConfiguration?: string;\n emissionsClass?: string;\n transmissionType?: 'Automatic' | 'Manual' | 'Semi-Automatic';\n vin?: string;\n currentRegistration?: {\n country?: string;\n };\n suspension?: 'Air' | 'Air/Steel' | 'Steel';\n constructionYear?: number;\n firstRegistration?: string;\n odometerKm?: number;\n powerHp?: number;\n bodystyle?: string;\n accessories: VehicleExternalInfo['accessories'];\n superstructure?: Pick<VehicleSuperstructure, 'crane' | 'tailgate'>;\n};\n\n// mostly inspired by the Hexon data model\nexport type VehicleExternalInfo = {\n body?: {\n cabin?: {\n type: 'Day' | 'Sleep / Small' | 'Sleep / Medium' | 'Sleep / Large';\n model?: string;\n };\n colour?: string;\n dimensions?: {\n height?: number;\n length?: number;\n width?: number;\n };\n doorCount?: number;\n interior?: {\n bedCount?: number;\n seatCount?: number;\n };\n internalDimensions?: {\n //for Trailers/Semi-trailers of type reefers, box, curtainsides\n height?: number;\n length?: number;\n width?: number;\n };\n kingpin?: {\n //for Trailers/Semi-trailers\n size?: number; // in inches\n capacity?: number; // in kg\n };\n fifthWheelHeight?: number; //for new trailers in mm\n };\n mainPicture?: AttachmentValue;\n pictures?: AttachmentValue[];\n videos?: AttachmentValue[];\n condition?: {\n damaged?: boolean;\n odometer?: {\n km?: number;\n };\n used?: boolean;\n };\n general: {\n bodystyle?: string;\n category: string;\n make?: string;\n model?: string;\n modelName?: string;\n type?: string;\n typeName?: string;\n tacho?: VehicleTachoTypes;\n color?: {\n mainColorHex?: string; //Hex color code\n chassisColorReferenceCode?: string; //Maker reference code. For now, mainly relevant for new trailers\n upperStructureColorReferenceCode?: string; //Maker reference code. For now, mainly relevant for new trailers\n };\n };\n history?: {\n advertisingYear?: number;\n constructionYear?: number;\n currentRegistration?: {\n country?: string;\n technicalInspectionEndDate?: string;\n carpassUrl?: string;\n carpassAvailable?: boolean;\n };\n firstRegistration?: string;\n cocPvg?: string;\n };\n identification: {\n licensePlate?: string;\n stockNumber?: string;\n vin?: string;\n buildStockNumber?: string;\n engineNumber?: string;\n };\n trailers?: {\n cooler?: {\n hasCooler?: boolean;\n make?: string;\n };\n };\n powertrain?: {\n axles?: VehicleAxlesInfo;\n emissions?: {\n class?: string;\n subclass?: string;\n };\n engine?: {\n cylinderCount?: number;\n energy?: { type?: VehicleFuelType };\n power?: {\n hp?: number;\n };\n displacement?: number;\n };\n transmission?: {\n gearCount?: number;\n make?: string;\n model?: string;\n type?: 'Automatic' | 'Manual' | 'Semi-Automatic';\n };\n };\n salesConditions: {\n leasing?: boolean;\n price?: string | undefined;\n currency?: string | undefined;\n marginScheme?: boolean;\n manufacturerWarranty?: {\n remarks?: string;\n available?: boolean;\n };\n } & (\n | { deliveryCost: number; deliveryLocation: string }\n | { deliveryCost?: never; deliveryLocation?: never }\n );\n superstructure?: VehicleSuperstructure;\n weights?: {\n gvw?: number;\n massEmpty?: number;\n };\n accessories: {\n abs?: boolean;\n jumbo?: boolean;\n adr?: boolean;\n airco?: boolean;\n alloyWheels?: boolean;\n aluminiumFuelTank?: boolean;\n cdPlayer?: boolean;\n coil?: boolean;\n doubleStock?: boolean;\n centralLocking?: boolean;\n centralLubrication?: boolean;\n cruiseControl?: boolean;\n electricDoorMirrors?: boolean;\n electricWindows?: boolean;\n engineBrake?: boolean;\n forklift?: boolean;\n navigationSystem?: boolean;\n hydraulicTipperKit?: boolean;\n lowDeck?: boolean;\n lowNoise?: boolean;\n mega?: boolean;\n parkingHeater?: boolean;\n particleFilter?: boolean;\n powerTakeOff?: boolean;\n refrigerator?: boolean;\n retarderIntarder?: boolean;\n reversingCamera?: boolean;\n roofSpoiler?: boolean;\n sideSkirts?: boolean;\n spareKey?: boolean;\n spareWheel?: boolean;\n speedLimiter?: boolean;\n spoilers?: boolean;\n spotlights?: boolean;\n stabilityControl?: boolean;\n standardAirco?: boolean;\n television?: boolean;\n toolbox?: boolean;\n trailerCoupling?: boolean;\n twinFuelTank?: boolean;\n visor?: boolean;\n xenonLights?: boolean;\n };\n publicLink?: string;\n};\n\ntype BaseVehicle<I = VehicleInternalInfo, E = VehicleExternalInfo> = {\n internal: I;\n external: E;\n original?: VehicleOriginalInfo;\n};\n\nexport type NewVehicle<I = VehicleInternalInfo, E = VehicleExternalInfo> = BaseVehicle<I, E> & {\n id?: undefined;\n};\n\nexport type Vehicle<I = VehicleInternalInfo, E = VehicleExternalInfo> = BaseVehicle<I, E> & {\n id: string;\n};\n\nexport type VehicleBffMetadata = {\n openOpportunities: number;\n};\n\nexport type VehicleBff = {\n vehicle: DataRecord<Vehicle, VehicleBffMetadata>;\n sale?: VehicleSaleInfo;\n purchase?: VehiclePurchase;\n overview?: VehicleBusinessOverviewXL;\n marketing?: {\n titles?: MultiLangValue;\n listed: boolean;\n sharable: boolean;\n publishedOnWebsiteAt?: string;\n numPlatformsPublished: number;\n };\n};\n\nexport type VehiclesByChassisNumberRequest = {\n tenantIds: string[];\n chassisNumber: string;\n};\n\nexport type VehiclesByMetaIdRequest = {\n tenantIds: string[];\n metaId: string;\n};\n\nexport type VehicleAxle = {\n make?: string;\n alloyWheels?: boolean;\n brakes?: 'Disc' | 'Drum';\n differentialLock?: boolean;\n liftAxle?: boolean;\n maxLoad?: number;\n nr: number;\n position?: string;\n powered?: boolean;\n reduction?: string;\n steering?: boolean;\n suspension?: 'Steel' | 'Air' | 'Hydraulic';\n twinWheels?: boolean;\n tyreSize?: string;\n tyreConditionType?: 'mm' | '%';\n\n tyreConditionMmLeftInside?: number;\n tyreConditionMmLeftOutside?: number;\n tyreConditionMmRightInside?: number;\n tyreConditionMmRightOutside?: number;\n\n tyreConditionPercLeftInside?: number;\n tyreConditionPercLeftOutside?: number;\n tyreConditionPercRightInside?: number;\n tyreConditionPercRightOutside?: number;\n\n steeringType?: 'fixed' | 'self_steering' | 'hydraulic';\n};\n\nexport enum VehiclePurchaseDealStatus {\n Marketing = 'MARKETING',\n PurchaseEvaluation = 'PURCHASE_EVALUATION', // used for vehicle consignation\n PurchaseAgreed = 'PURCHASE_AGREED',\n FirstPaymentAllowed = 'FIRST_PAYMENT_ALLOWED',\n FirstPaymentSent = 'FIRST_PAYMENT_SENT',\n FullPaymentAllowed = 'FULL_PAYMENT_ALLOWED',\n FullPaymentSent = 'FULL_PAYMENT_SENT',\n}\n\nexport enum VehiclePurchaseLogisticsStatus {\n AtOrigin = 'AT_ORIGIN',\n Arrived = 'ARRIVED',\n CheckedIn = 'CHECKED_IN',\n NotApplicable = 'NOT_APPLICABLE',\n}\n\nexport enum VehiclePurchaseDeliveryType {\n PickUp = 'PICK_UP',\n DropOff = 'DROP_OFF',\n}\n\nexport type VehicleStatus = {\n deleted?: boolean;\n deletedReason?: string;\n};\n\nexport type VehiclePriceList = {\n uploadedAt: string;\n uploadedBy: string;\n priceList: AttachmentValue;\n id: string;\n};\n\nexport type UpdateVehiclesPricesRequest = {\n priceList: AttachmentValue;\n};\n\nexport type VehiclePriceListLine = {\n reference: string;\n internet?: string;\n premium?: string;\n minimum?: string;\n};\n\nexport type VehiclePriceUpdateError = {\n data: VehiclePriceListLine;\n line: number;\n error: {\n fieldId: keyof VehiclePriceListLine;\n msg: string;\n };\n};\n\nexport type VehiclePriceUpdateResponse =\n | {\n success: true;\n }\n | {\n success: false;\n errors: VehiclePriceUpdateError[];\n };\n\nexport type VehiclePurchase = {\n organizationId: string;\n contactId: string;\n supplierStockNumber?: string;\n purchasedBy: string;\n purchaseAssistedBy?: string;\n\n log: {\n // computed automatically by the backend\n marketingStartedAt?: string;\n marketingStartedBy?: string;\n\n evaluationStartedAt?: string;\n evaluationStartedBy?: string;\n\n purchaseAgreedAt?: string;\n purchaseAgreedBy?: string;\n\n firstPaymentAllowedAt?: string;\n firstPaymentAllowedBy?: string;\n firstPaymentSentAt?: string;\n firstPaymentSentBy?: string;\n\n fullPaymentAllowedAt?: string;\n fullPaymentAllowedBy?: string;\n fullPaymentSentAt?: string;\n fullPaymentSentBy?: string;\n\n arrivedAt?: string;\n arrivedBy?: string;\n\n checkedInAt?: string;\n checkedInBy?: string;\n };\n\n deal: {\n status: VehiclePurchaseDealStatus; // partially set by the user, if there are payments then it is set automatically by the backend\n readyToDeliver?: boolean;\n\n purchaseVatRate?: string;\n purchase?: string; // exclusive VAT\n\n bonus?: string; // sometimes manufacturers pay us a bonus when we reach a target\n\n // estimated costs, real costs come from actual invoices\n commission?: string;\n externalTransport?: string;\n internalTransport?: string;\n externalGarage?: string;\n internalGarage?: string;\n other?: string;\n\n totalCosts?: string; // exclusive VAT\n };\n\n logistics: {\n parkingName?: string;\n status: VehiclePurchaseLogisticsStatus; // manually set by the user\n deliveryType?: VehiclePurchaseDeliveryType;\n pickupAddress?: LocationValue;\n availableWeek?: string; // ISOWEEK, e.g. 2016-W02\n };\n};\n\nexport type PurchaseRecordMeta = ReferenceData & {\n allowedLogisticsTransitions?: VehiclePurchaseLogisticsStatus[];\n};\n\nexport type SaveVehiclePurchaseOpts = {\n skipTransportValidation?: boolean;\n};\n\nexport enum VehicleActions {\n EditAdminDocs = 'edit_admin_docs',\n EditEngineeringDocs = 'edit_engineering_docs',\n EditMarketing = 'edit_marketing',\n EditMedia = 'edit_media',\n EditPictures = 'edit_pictures',\n EditPrices = 'edit_prices',\n EditPurchaseDeal = 'edit_purchase_deal',\n EditPurchaseLogistics = 'edit_purchase_logistics',\n EditSpecs = 'edit_specs',\n EditVideos = 'edit_videos',\n ViewLeads = 'view_leads',\n ViewBusinessOverview = 'view_business_overview',\n ViewSimilarOnline = 'view_similar_online',\n ViewPurchase = 'view_purchase',\n ViewPriceHistory = 'view_price_history',\n DeleteVehicle = 'delete_vehicle',\n}\n\nexport enum PurchaseActions {\n ViewDeal = 'view_deal',\n ViewSupplierOrganization = 'view_supplier_organization',\n ViewContact = 'view_contact',\n ViewLegalAddress = 'view_legal_address',\n ViewPickupAddress = 'view_pickup_address',\n ViewEstimatedCosts = 'view_estimated_costs',\n ViewFinanceDocuments = 'view_finance_documents',\n AddPayment = 'add_payment',\n EditPayment = 'edit_payment',\n MarkPaymentDone = 'mark_payment_done',\n AddRemarks = 'add_remarks',\n}\n\nexport enum VehicleBusinessOverviewActions {\n View = 'view_business_overview',\n}\n\nexport type VehicleShareEmailRequest = ShareEmailRequest & {\n pictures: AttachmentValue[];\n};\n\nexport type VehicleShareData = {\n title: string;\n mainPicture?: string;\n pictures: {\n picture: string;\n }[];\n message: string;\n specs: {\n name: string;\n value: string;\n }[];\n features: {\n name: string;\n }[];\n stockNumber: string;\n price?: string;\n description?: string;\n publicLink?: string;\n};\n\nexport type MarketingEmailData = {\n message: string;\n vehicles: VehicleShareData[];\n vehiclePairs: { first: VehicleShareData; second?: VehicleShareData }[];\n lastVehicle?: VehicleShareData;\n unsubscribeUrl?: string;\n};\n\nexport type VehicleReservationCreateEvent = BaseVehicleEvent & {\n action: 'create';\n reservation: OpportunityReservation;\n previousReservation?: undefined;\n};\n\nexport type VehicleReservationUpdateEvent = BaseVehicleEvent & {\n action: 'update';\n reservation: OpportunityReservation;\n previousReservation: OpportunityReservation;\n};\n\nexport type VehicleReservationDeleteEvent = BaseVehicleEvent & {\n action: 'delete';\n reservation?: undefined;\n previousReservation: OpportunityReservation;\n};\n\nexport type VehicleReservationEvent =\n | VehicleReservationCreateEvent\n | VehicleReservationUpdateEvent\n | VehicleReservationDeleteEvent;\n\nexport type ShareVehicleViaWahtsappRequest = {\n data: ShareWhatsappRequest;\n vehicleId: string;\n};\n\ntype RecordChange = {\n modifiedAt: string;\n modifiedBy: string;\n};\n\nexport type VehicleChange = RecordChange & {\n vehicle: Vehicle;\n};\n\nexport type PurchaseChange = RecordChange & {\n purchase: VehiclePurchase;\n};\n\nexport type RecordChangeRequest = PaginatedRequest & {\n fieldPath?: string;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"vehicles.js","sourceRoot":"/","sources":["types/vehicles.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AttachmentValue,\n Document,\n LocationValue,\n MultiLangValue,\n PaginatedRequest,\n SearchPermissions,\n ShareEmailRequest,\n ShareWhatsappRequest,\n} from '@bisondesk/commons-sdk/types';\nimport { ReferenceData } from '@bisondesk/commons-sdk/utils';\nimport { BaseEvent } from './internal-events.js';\nimport { VehicleSaleLogisticsStatus } from './opportunities.js';\nimport { OpportunityReservation } from './reservations.js';\nimport { ComplexFilter, Filter } from './search.js';\nimport { Transport } from './transports.js';\nimport { DataRecord } from './utils.js';\nimport { VehicleBusinessOverviewXL } from './vehicle-performance.js';\nimport { VehicleSaleInfo } from './vehicle-sales.js';\n\nexport enum VehicleRoles {\n SALE = 'SALE',\n OWN_USE = 'OWN_USE',\n RENTAL = 'RENTAL',\n BUILD = 'BUILD',\n UNKNOWN = 'UNKNOWN',\n BANK_FINANCE = 'BANK_FINANCE',\n}\n\nexport enum VehicleFuelType {\n Petrol = 'PETROL',\n Diesel = 'DIESEL',\n LPG = 'LPG',\n LPG_G3 = 'LPG_G3',\n Electric = 'ELECTRIC',\n CNG = 'CNG',\n Hydrogen = 'HYDROGEN',\n BioEthanol = 'BIO_ETHANOL',\n BioDiesel = 'BIO_DIESEL',\n E85 = 'E85',\n HCNG = 'HCNG',\n LPG_Petrol = 'LPG_PETROL',\n LPG_Diesel = 'LPG_DIESEL',\n LPG_G3_Petrol = 'LPG_G3_PETROL',\n LPG_G3_Diesel = 'LPG_G3_DIESEL',\n Electric_Diesel = 'ELECTRIC_DIESEL',\n Electric_Petrol = 'ELECTRIC_PETROL',\n Hybrid = 'HYBRID',\n Other = 'OTHER',\n}\n\nexport enum VehicleTachoTypes {\n Analog = 'ANALOG',\n Digital = 'DIGITAL',\n SmartTacho1 = 'SMART_TACHO_1',\n SmartTacho2 = 'SMART_TACHO_2',\n}\n\ntype BaseVehicleEvent = BaseEvent & {\n id: string;\n actionAt: string;\n userId: string;\n tenantId: string;\n};\n\ntype VehicleSuperstructure = {\n carCapacity?: number;\n compartmentCount?: number;\n counter?: boolean;\n crane?: {\n make?: string;\n model?: string;\n position?: 'Behind the cabin' | 'Rear';\n present?: boolean;\n year?: number;\n };\n dimensions?: {\n height?: number;\n length?: number;\n width?: number;\n extended?: string; // L1, L2, ...\n heightened?: string; // H1, H2, ...\n };\n baseVehicle?: SuperstructureBaseVehicle;\n extendable?: boolean;\n highPressurePump?: boolean;\n loadingPlatformHeight?: number;\n pump?: boolean;\n slidingRoof?: boolean;\n tailgate?: {\n capacity?: number;\n make?: string;\n model?: string;\n present?: boolean;\n type?: 'slider_lift' | 'cantilever' | 'column_lift';\n };\n tank?: {\n capacity: number; //litters\n volume?: number; //m3\n };\n temperatureControl?: {\n engineType?: 'diesel' | 'electric' | 'diesel+electric' | 'engine';\n make?: string;\n runningHours?: {\n diesel?: number;\n electric?: number;\n };\n };\n tipper?: {\n tipsBack?: boolean;\n tipsLeft?: boolean;\n tipsRight?: boolean;\n };\n};\n\nexport type NewVehicleRequest = {\n branch: string;\n count: number;\n specs: VehicleExternalInfo;\n description: {\n remarks?: string;\n technicalRemarks?: string;\n };\n salesConditions?: {\n marginScheme?: boolean;\n manufacturerWarranty?: {\n remarks?: string;\n available?: boolean;\n };\n };\n logistics: {\n parking?: string;\n deliveryType?: VehiclePurchaseDeliveryType;\n pickupAddress?: LocationValue;\n status: VehiclePurchaseLogisticsStatus;\n };\n prices: {\n minimum?: string;\n premium?: string;\n internet?: string;\n };\n media: {\n internalPictures: AttachmentValue[];\n pictures: AttachmentValue[];\n videos: AttachmentValue[];\n docs: Document[];\n engineeringDocs: Document[];\n };\n vinList?: string;\n deal: {\n offerId?: string;\n stockNumber?: string;\n contactId: string;\n orgId: string;\n purchasedBy: string;\n purchaseAssistedBy?: string;\n readyToDeliver?: boolean;\n dealStatus: VehiclePurchaseDealStatus;\n costs: {\n purchase: string;\n purchaseVatPercentage: string;\n commission?: string;\n externalTransport?: string;\n internalTransport?: string;\n externalGarage?: string;\n internalGarage?: string;\n other?: string;\n bonus?: string;\n };\n logistics: {\n availableDate?: string;\n vehicleRole: VehicleRoles;\n };\n };\n};\n\nexport type VehicleCreateEvent = BaseVehicleEvent & {\n action: 'create';\n vehicle: Vehicle;\n previousVehicle?: undefined;\n};\n\nexport type VehicleUpdateEvent = BaseVehicleEvent & {\n action: 'update';\n vehicle: Vehicle;\n previousVehicle: Vehicle;\n};\n\nexport type VehicleDeleteEvent = BaseVehicleEvent & {\n action: 'delete';\n vehicle?: undefined;\n previousVehicle: Vehicle;\n};\n\nexport type VehicleEvent = VehicleCreateEvent | VehicleUpdateEvent | VehicleDeleteEvent;\n\ntype BaseVehiclePurchaseEvent = {\n actionAt: string;\n userId: string;\n tenantId: string;\n branchId: string;\n vehicleId: string;\n};\n\nexport type VehiclePurchaseCreateEvent = BaseVehiclePurchaseEvent & {\n action: 'create';\n data: VehiclePurchase;\n previousData?: undefined;\n};\n\nexport type VehiclePurchaseUpdateEvent = BaseVehiclePurchaseEvent & {\n action: 'update';\n data: VehiclePurchase;\n previousData: VehiclePurchase;\n};\n\nexport type VehiclePurchaseEvent = BaseEvent &\n (VehiclePurchaseCreateEvent | VehiclePurchaseUpdateEvent);\n\nexport type UpdateVehiclesPricesEvent = {\n id: string;\n actionAt: string;\n userId: string;\n tenantId: string;\n priceList: AttachmentValue;\n};\n\nexport type PublicVehicle = Pick<Vehicle, 'external' | 'id'>;\n\nexport type PublicSearchVehicle = {\n vehicle: PublicVehicle;\n};\n\nexport enum SearchVehicleSaleDealStatus {\n NotSold = 'NOT_SOLD',\n Reserved = 'RESERVED',\n Sold = 'SOLD',\n}\n\nexport type SearchVehicle = {\n custom: {\n features: string[];\n sold: boolean;\n isReserved: boolean;\n hasPayments: boolean;\n listedOnWebsite: boolean;\n publishedOnWebsiteAt?: string;\n originalBranchId: string;\n };\n customSortableFields: {\n priceChangedAt?: string;\n checkedInAt?: string;\n saleAgreementAt?: string;\n };\n purchase?: {\n supplierStockNumber?: string;\n readyToDeliver: boolean;\n dealStatus?: VehiclePurchaseDealStatus;\n logisticsStatus?: VehiclePurchaseLogisticsStatus;\n purchasedBy?: string;\n parkingName?: string;\n organizationId: string;\n organizationExternalId?: number;\n fullPaymentSentAt?: string;\n marketingStartedAt?: string;\n arrivedAt?: string;\n };\n reservation?: Pick<OpportunityReservation, 'expiresAt' | 'opportunityId' | 'createdBy'>;\n transports: Transport[];\n vehicle: Vehicle;\n sale: {\n opportunityId?: string;\n externalSaleId?: string;\n soldAt?: string;\n soldBy?: string;\n sellers?: string[]; // opportunity account manager [+ assistant]\n dealStatus: SearchVehicleSaleDealStatus;\n logisticStatus?: VehicleSaleLogisticsStatus;\n };\n};\n\nexport type InputSearchVehicle = SearchVehicle & {\n permissions?: SearchPermissions;\n};\n\nexport type VehicleSearchMeta = ReferenceData & {\n matchingOffers?: {\n count: number;\n filters: {\n conditions: Array<Filter | ComplexFilter>;\n fullText?: string;\n };\n };\n};\n\nexport type PriceChangeEvent = BaseEvent & {\n tenantId: string;\n userId: string;\n vehicleId: string;\n input: {\n previousPrices: VehiclePricingHistoryInput;\n currentPrices: VehiclePricingHistoryInput;\n };\n};\n\nexport type VehiclePricingHistory = {\n pricing: VehiclePricingHistoryInput;\n createdAt: string;\n createdBy: string;\n};\n\nexport type VehiclePricingHistoryInput = VehiclePricing & { internet?: string };\n\nexport type VehiclePricing = {\n premium?: string;\n minimum?: string;\n currency?: string;\n};\n\nexport type RelatedVehicle = {\n vehicleId: string;\n description: string;\n stockNumber: string;\n};\n\nexport type VehicleInternalInfo = {\n createdAt: string;\n description: {\n title: string;\n remarks?: string;\n technicalRemarks?: string;\n };\n identification: {\n administrativeNumber?: string;\n stockNumber: string;\n branch: string;\n\n offerId?: string;\n licensePlateHistory?: {\n licensePlate: string;\n changedAt: string;\n }[];\n\n /**\n * This ID is used to link different vehicle objects that represent the same real world asset.\n * Ideally the chassis number could be used, but in some cases it is not available yet.\n */\n metaId: string;\n };\n documents: Document[];\n pictures: AttachmentValue[];\n engineeringDocs: Document[];\n pricing: VehiclePricing;\n role: VehicleRoles;\n status: VehicleStatus;\n updatedAt: string;\n /* use this property to store additional terms that you want the vehicle to be found with when doing a full text search */\n keywords?: string[];\n relatedVehicles: RelatedVehicle[];\n};\n\nexport type VehicleOriginalInfo = {\n /** IMMEDIATE source tenant (the predecessor in a sync chain). */\n tenantId: string;\n tenantChain?: string[];\n identification: {\n id: string;\n branchId: string;\n stockNumber: string;\n metaId?: string;\n country: string;\n };\n salesConditions: {\n leasing?: boolean;\n price?: string;\n currency?: string;\n marginScheme?: boolean;\n manufacturerWarranty?: {\n remarks?: string;\n available?: boolean;\n };\n /**\n * The immediate source's sellability at the last sync hop: true when the source was not\n * sellable — not in `SALE` role, had an active reservation or external sale, or was itself\n * unavailable. Derived (never set by a human) and refreshed on every cross-tenant update so\n * it cascades down the whole chain.\n */\n unavailable?: boolean;\n };\n /**\n * Deepest-origin tenant/branch in a multi-hop sync chain. Carries forward\n * verbatim across hops so consumers can answer \"where did this vehicle\n * actually originate?\" without walking the chain.\n */\n owner: {\n tenantId: string;\n branchId: string;\n country: string;\n };\n};\n\nexport type VehicleAxlesInfo = {\n details?: VehicleAxle[];\n configuration?: string;\n count?: number;\n poweredAxlesCount?: number;\n wheelbase?: number;\n suspension?: 'Air' | 'Air/Steel' | 'Steel';\n loadCapacity?: number;\n};\n\nexport type SuperstructureBaseVehicle = {\n category: string;\n make: string;\n model?: string;\n type?: string;\n axlesConfiguration?: string;\n emissionsClass?: string;\n transmissionType?: 'Automatic' | 'Manual' | 'Semi-Automatic';\n vin?: string;\n currentRegistration?: {\n country?: string;\n };\n suspension?: 'Air' | 'Air/Steel' | 'Steel';\n constructionYear?: number;\n firstRegistration?: string;\n odometerKm?: number;\n powerHp?: number;\n bodystyle?: string;\n accessories: VehicleExternalInfo['accessories'];\n superstructure?: Pick<VehicleSuperstructure, 'crane' | 'tailgate'>;\n};\n\n// mostly inspired by the Hexon data model\nexport type VehicleExternalInfo = {\n body?: {\n cabin?: {\n type: 'Day' | 'Sleep / Small' | 'Sleep / Medium' | 'Sleep / Large';\n model?: string;\n };\n colour?: string;\n dimensions?: {\n height?: number;\n length?: number;\n width?: number;\n };\n doorCount?: number;\n interior?: {\n bedCount?: number;\n seatCount?: number;\n };\n internalDimensions?: {\n //for Trailers/Semi-trailers of type reefers, box, curtainsides\n height?: number;\n length?: number;\n width?: number;\n };\n kingpin?: {\n //for Trailers/Semi-trailers\n size?: number; // in inches\n capacity?: number; // in kg\n };\n fifthWheelHeight?: number; //for new trailers in mm\n };\n mainPicture?: AttachmentValue;\n pictures?: AttachmentValue[];\n videos?: AttachmentValue[];\n condition?: {\n damaged?: boolean;\n odometer?: {\n km?: number;\n };\n used?: boolean;\n };\n general: {\n bodystyle?: string;\n category: string;\n make?: string;\n model?: string;\n modelName?: string;\n type?: string;\n typeName?: string;\n tacho?: VehicleTachoTypes;\n color?: {\n mainColorHex?: string; //Hex color code\n chassisColorReferenceCode?: string; //Maker reference code. For now, mainly relevant for new trailers\n upperStructureColorReferenceCode?: string; //Maker reference code. For now, mainly relevant for new trailers\n };\n };\n history?: {\n advertisingYear?: number;\n constructionYear?: number;\n currentRegistration?: {\n country?: string;\n technicalInspectionEndDate?: string;\n carpassUrl?: string;\n carpassAvailable?: boolean;\n };\n firstRegistration?: string;\n cocPvg?: string;\n };\n identification: {\n licensePlate?: string;\n stockNumber?: string;\n vin?: string;\n buildStockNumber?: string;\n engineNumber?: string;\n };\n trailers?: {\n cooler?: {\n hasCooler?: boolean;\n make?: string;\n };\n };\n powertrain?: {\n axles?: VehicleAxlesInfo;\n emissions?: {\n class?: string;\n subclass?: string;\n };\n engine?: {\n cylinderCount?: number;\n energy?: { type?: VehicleFuelType };\n power?: {\n hp?: number;\n };\n displacement?: number;\n };\n transmission?: {\n gearCount?: number;\n make?: string;\n model?: string;\n type?: 'Automatic' | 'Manual' | 'Semi-Automatic';\n };\n };\n salesConditions: {\n leasing?: boolean;\n price?: string | undefined;\n currency?: string | undefined;\n /**\n * Read-only field maintained by `fillReadOnlyFields` on every vehicle save:\n * the value of `price` immediately before the most recent price change. Stays\n * unchanged when `price` does not change between saves. Same currency as\n * `price`. Useful for storefront \"was/now\" price-drop labels and for the AI\n * assistant's negotiation context.\n */\n previousPrice?: string;\n marginScheme?: boolean;\n manufacturerWarranty?: {\n remarks?: string;\n available?: boolean;\n };\n /**\n * Per-country snapshot computed by the owning tenant's `fillReadOnlyFields`.\n * Every field on this snapshot is public — `vehicle.external` rides through\n * to the storefront via cross-tenant sync, so internal-only values (e.g. the\n * owner's freight cost) must not appear here. Cross-tenant sync derives the\n * internal `externalTransport` figure directly from the owner's country-\n * delivery rule at sync time.\n *\n * Each entry exposes:\n * - `price` — bare currency conversion for the rule's country.\n * - `previousPrice` — bare conversion of `salesConditions.previousPrice`\n * when set.\n * - `deliveryPrice` — customer-facing delivery fee (when the rule covers\n * the vehicle's category). Storefront consumers sum\n * `price + (deliveryPrice ?? 0)` at the display layer.\n * - `deliveryLocation` — human-readable label, present whenever the rule\n * declared a location for this country.\n *\n * Only the original owner recomputes on save; cross-tenant copies preserve\n * the array.\n */\n localizedPricing?: Array<{\n countryCode: string;\n currency: string;\n price: number;\n previousPrice?: number;\n deliveryPrice?: number;\n deliveryLocation?: string;\n }>;\n };\n superstructure?: VehicleSuperstructure;\n weights?: {\n gvw?: number;\n massEmpty?: number;\n };\n accessories: {\n abs?: boolean;\n jumbo?: boolean;\n adr?: boolean;\n airco?: boolean;\n alloyWheels?: boolean;\n aluminiumFuelTank?: boolean;\n cdPlayer?: boolean;\n coil?: boolean;\n doubleStock?: boolean;\n centralLocking?: boolean;\n centralLubrication?: boolean;\n cruiseControl?: boolean;\n electricDoorMirrors?: boolean;\n electricWindows?: boolean;\n engineBrake?: boolean;\n forklift?: boolean;\n navigationSystem?: boolean;\n hydraulicTipperKit?: boolean;\n lowDeck?: boolean;\n lowNoise?: boolean;\n mega?: boolean;\n parkingHeater?: boolean;\n particleFilter?: boolean;\n powerTakeOff?: boolean;\n refrigerator?: boolean;\n retarderIntarder?: boolean;\n reversingCamera?: boolean;\n roofSpoiler?: boolean;\n sideSkirts?: boolean;\n spareKey?: boolean;\n spareWheel?: boolean;\n speedLimiter?: boolean;\n spoilers?: boolean;\n spotlights?: boolean;\n stabilityControl?: boolean;\n standardAirco?: boolean;\n television?: boolean;\n toolbox?: boolean;\n trailerCoupling?: boolean;\n twinFuelTank?: boolean;\n visor?: boolean;\n xenonLights?: boolean;\n };\n publicLink?: string;\n};\n\ntype BaseVehicle<I = VehicleInternalInfo, E = VehicleExternalInfo> = {\n internal: I;\n external: E;\n original?: VehicleOriginalInfo;\n};\n\nexport type NewVehicle<I = VehicleInternalInfo, E = VehicleExternalInfo> = BaseVehicle<I, E> & {\n id?: undefined;\n};\n\nexport type Vehicle<I = VehicleInternalInfo, E = VehicleExternalInfo> = BaseVehicle<I, E> & {\n id: string;\n};\n\nexport type VehicleBffMetadata = {\n openOpportunities: number;\n};\n\nexport type VehicleBff = {\n vehicle: DataRecord<Vehicle, VehicleBffMetadata>;\n sale?: VehicleSaleInfo;\n purchase?: VehiclePurchase;\n overview?: VehicleBusinessOverviewXL;\n marketing?: {\n titles?: MultiLangValue;\n listed: boolean;\n sharable: boolean;\n publishedOnWebsiteAt?: string;\n numPlatformsPublished: number;\n };\n};\n\nexport type VehiclesByChassisNumberRequest = {\n tenantIds: string[];\n chassisNumber: string;\n};\n\nexport type VehiclesByMetaIdRequest = {\n tenantIds: string[];\n metaId: string;\n};\n\nexport type VehicleAxle = {\n make?: string;\n alloyWheels?: boolean;\n brakes?: 'Disc' | 'Drum';\n differentialLock?: boolean;\n liftAxle?: boolean;\n maxLoad?: number;\n nr: number;\n position?: string;\n powered?: boolean;\n reduction?: string;\n steering?: boolean;\n suspension?: 'Steel' | 'Air' | 'Hydraulic';\n twinWheels?: boolean;\n tyreSize?: string;\n tyreConditionType?: 'mm' | '%';\n\n tyreConditionMmLeftInside?: number;\n tyreConditionMmLeftOutside?: number;\n tyreConditionMmRightInside?: number;\n tyreConditionMmRightOutside?: number;\n\n tyreConditionPercLeftInside?: number;\n tyreConditionPercLeftOutside?: number;\n tyreConditionPercRightInside?: number;\n tyreConditionPercRightOutside?: number;\n\n steeringType?: 'fixed' | 'self_steering' | 'hydraulic';\n};\n\nexport enum VehiclePurchaseDealStatus {\n Marketing = 'MARKETING',\n PurchaseEvaluation = 'PURCHASE_EVALUATION', // used for vehicle consignation\n PurchaseAgreed = 'PURCHASE_AGREED',\n FirstPaymentAllowed = 'FIRST_PAYMENT_ALLOWED',\n FirstPaymentSent = 'FIRST_PAYMENT_SENT',\n FullPaymentAllowed = 'FULL_PAYMENT_ALLOWED',\n FullPaymentSent = 'FULL_PAYMENT_SENT',\n}\n\nexport enum VehiclePurchaseLogisticsStatus {\n AtOrigin = 'AT_ORIGIN',\n Arrived = 'ARRIVED',\n CheckedIn = 'CHECKED_IN',\n NotApplicable = 'NOT_APPLICABLE',\n}\n\nexport enum VehiclePurchaseDeliveryType {\n PickUp = 'PICK_UP',\n DropOff = 'DROP_OFF',\n}\n\nexport type VehicleStatus = {\n deleted?: boolean;\n deletedReason?: string;\n};\n\nexport type VehiclePriceList = {\n uploadedAt: string;\n uploadedBy: string;\n priceList: AttachmentValue;\n id: string;\n};\n\nexport type UpdateVehiclesPricesRequest = {\n priceList: AttachmentValue;\n};\n\nexport type VehiclePriceListLine = {\n reference: string;\n internet?: string;\n premium?: string;\n minimum?: string;\n};\n\nexport type VehiclePriceUpdateError = {\n data: VehiclePriceListLine;\n line: number;\n error: {\n fieldId: keyof VehiclePriceListLine;\n msg: string;\n };\n};\n\nexport type VehiclePriceUpdateResponse =\n | {\n success: true;\n }\n | {\n success: false;\n errors: VehiclePriceUpdateError[];\n };\n\nexport type VehiclePurchase = {\n organizationId: string;\n contactId: string;\n supplierStockNumber?: string;\n purchasedBy: string;\n purchaseAssistedBy?: string;\n\n log: {\n // computed automatically by the backend\n marketingStartedAt?: string;\n marketingStartedBy?: string;\n\n evaluationStartedAt?: string;\n evaluationStartedBy?: string;\n\n purchaseAgreedAt?: string;\n purchaseAgreedBy?: string;\n\n firstPaymentAllowedAt?: string;\n firstPaymentAllowedBy?: string;\n firstPaymentSentAt?: string;\n firstPaymentSentBy?: string;\n\n fullPaymentAllowedAt?: string;\n fullPaymentAllowedBy?: string;\n fullPaymentSentAt?: string;\n fullPaymentSentBy?: string;\n\n arrivedAt?: string;\n arrivedBy?: string;\n\n checkedInAt?: string;\n checkedInBy?: string;\n };\n\n deal: {\n status: VehiclePurchaseDealStatus; // partially set by the user, if there are payments then it is set automatically by the backend\n readyToDeliver?: boolean;\n\n purchaseVatRate?: string;\n purchase?: string; // exclusive VAT\n\n bonus?: string; // sometimes manufacturers pay us a bonus when we reach a target\n\n // estimated costs, real costs come from actual invoices\n commission?: string;\n externalTransport?: string;\n internalTransport?: string;\n externalGarage?: string;\n internalGarage?: string;\n other?: string;\n\n totalCosts?: string; // exclusive VAT\n };\n\n logistics: {\n parkingName?: string;\n status: VehiclePurchaseLogisticsStatus; // manually set by the user\n deliveryType?: VehiclePurchaseDeliveryType;\n pickupAddress?: LocationValue;\n availableWeek?: string; // ISOWEEK, e.g. 2016-W02\n };\n};\n\nexport type PurchaseRecordMeta = ReferenceData & {\n allowedLogisticsTransitions?: VehiclePurchaseLogisticsStatus[];\n};\n\nexport type SaveVehiclePurchaseOpts = {\n skipTransportValidation?: boolean;\n};\n\nexport enum VehicleActions {\n EditAdminDocs = 'edit_admin_docs',\n EditEngineeringDocs = 'edit_engineering_docs',\n EditMarketing = 'edit_marketing',\n EditMedia = 'edit_media',\n EditPictures = 'edit_pictures',\n EditPrices = 'edit_prices',\n EditPurchaseDeal = 'edit_purchase_deal',\n EditPurchaseLogistics = 'edit_purchase_logistics',\n EditSpecs = 'edit_specs',\n EditVideos = 'edit_videos',\n ViewLeads = 'view_leads',\n ViewBusinessOverview = 'view_business_overview',\n ViewSimilarOnline = 'view_similar_online',\n ViewPurchase = 'view_purchase',\n ViewPriceHistory = 'view_price_history',\n DeleteVehicle = 'delete_vehicle',\n}\n\nexport enum PurchaseActions {\n ViewDeal = 'view_deal',\n ViewSupplierOrganization = 'view_supplier_organization',\n ViewContact = 'view_contact',\n ViewLegalAddress = 'view_legal_address',\n ViewPickupAddress = 'view_pickup_address',\n ViewEstimatedCosts = 'view_estimated_costs',\n ViewFinanceDocuments = 'view_finance_documents',\n AddPayment = 'add_payment',\n EditPayment = 'edit_payment',\n MarkPaymentDone = 'mark_payment_done',\n AddRemarks = 'add_remarks',\n}\n\nexport enum VehicleBusinessOverviewActions {\n View = 'view_business_overview',\n}\n\nexport type VehicleShareEmailRequest = ShareEmailRequest & {\n pictures: AttachmentValue[];\n};\n\nexport type VehicleShareData = {\n title: string;\n mainPicture?: string;\n pictures: {\n picture: string;\n }[];\n message: string;\n specs: {\n name: string;\n value: string;\n }[];\n features: {\n name: string;\n }[];\n stockNumber: string;\n price?: string;\n description?: string;\n publicLink?: string;\n};\n\nexport type MarketingEmailData = {\n message: string;\n vehicles: VehicleShareData[];\n vehiclePairs: { first: VehicleShareData; second?: VehicleShareData }[];\n lastVehicle?: VehicleShareData;\n unsubscribeUrl?: string;\n};\n\nexport type VehicleReservationCreateEvent = BaseVehicleEvent & {\n action: 'create';\n reservation: OpportunityReservation;\n previousReservation?: undefined;\n};\n\nexport type VehicleReservationUpdateEvent = BaseVehicleEvent & {\n action: 'update';\n reservation: OpportunityReservation;\n previousReservation: OpportunityReservation;\n};\n\nexport type VehicleReservationDeleteEvent = BaseVehicleEvent & {\n action: 'delete';\n reservation?: undefined;\n previousReservation: OpportunityReservation;\n};\n\nexport type VehicleReservationEvent =\n | VehicleReservationCreateEvent\n | VehicleReservationUpdateEvent\n | VehicleReservationDeleteEvent;\n\nexport type ShareVehicleViaWahtsappRequest = {\n data: ShareWhatsappRequest;\n vehicleId: string;\n};\n\ntype RecordChange = {\n modifiedAt: string;\n modifiedBy: string;\n};\n\nexport type VehicleChange = RecordChange & {\n vehicle: Vehicle;\n};\n\nexport type PurchaseChange = RecordChange & {\n purchase: VehiclePurchase;\n};\n\nexport type RecordChangeRequest = PaginatedRequest & {\n fieldPath?: string;\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exchange-rates.d.ts","sourceRoot":"/","sources":["utils/exchange-rates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAU1D,eAAO,MAAM,eAAe,GAC1B,QAAQ,MAAM,EACd,cAAc,MAAM,EACpB,YAAY,MAAM,EAClB,OAAO,YAAY,EAAE,KACpB,MAAM,GAAG,SAgBX,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const convertCurrency = (amount, fromCurrency, toCurrency, rates) => {
|
|
2
|
+
if (fromCurrency === toCurrency) {
|
|
3
|
+
return Math.ceil(amount);
|
|
4
|
+
}
|
|
5
|
+
const direct = rates.find((r) => r.fromCurrency === fromCurrency && r.toCurrency === toCurrency);
|
|
6
|
+
if (direct != null) {
|
|
7
|
+
return Math.ceil(amount * direct.rate);
|
|
8
|
+
}
|
|
9
|
+
const inverse = rates.find((r) => r.fromCurrency === toCurrency && r.toCurrency === fromCurrency);
|
|
10
|
+
if (inverse != null && inverse.rate > 0) {
|
|
11
|
+
return Math.ceil(amount / inverse.rate);
|
|
12
|
+
}
|
|
13
|
+
return undefined;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=exchange-rates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exchange-rates.js","sourceRoot":"/","sources":["utils/exchange-rates.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,MAAc,EACd,YAAoB,EACpB,UAAkB,EAClB,KAAqB,EACD,EAAE;IACtB,IAAI,YAAY,KAAK,UAAU,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IAED,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,YAAY,IAAI,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;IACjG,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,UAAU,IAAI,CAAC,CAAC,UAAU,KAAK,YAAY,CAAC,CAAC;IAClG,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC","sourcesContent":["import { ExchangeRate } from '../types/exchange-rates.js';\n\n/**\n * Convert `amount` from `fromCurrency` to `toCurrency` using a direction-agnostic\n * rate lookup. If a rate exists in either direction it is applied (inverted when\n * needed). Returns `undefined` if no matching pair is configured.\n *\n * `Math.ceil` is applied on the result so the seller is never undersold by a\n * partial unit of rounding.\n */\nexport const convertCurrency = (\n amount: number,\n fromCurrency: string,\n toCurrency: string,\n rates: ExchangeRate[],\n): number | undefined => {\n if (fromCurrency === toCurrency) {\n return Math.ceil(amount);\n }\n\n const direct = rates.find((r) => r.fromCurrency === fromCurrency && r.toCurrency === toCurrency);\n if (direct != null) {\n return Math.ceil(amount * direct.rate);\n }\n\n const inverse = rates.find((r) => r.fromCurrency === toCurrency && r.toCurrency === fromCurrency);\n if (inverse != null && inverse.rate > 0) {\n return Math.ceil(amount / inverse.rate);\n }\n\n return undefined;\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exchange-rates.test.d.ts","sourceRoot":"/","sources":["utils/exchange-rates.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { convertCurrency } from './exchange-rates.js';
|
|
2
|
+
const rates = [
|
|
3
|
+
{ fromCurrency: 'EUR', toCurrency: 'USD', rate: 1.2 },
|
|
4
|
+
{ fromCurrency: 'EUR', toCurrency: 'XOF', rate: 655.96 },
|
|
5
|
+
];
|
|
6
|
+
describe('convertCurrency', () => {
|
|
7
|
+
test('passthrough when from and to are equal', () => {
|
|
8
|
+
expect(convertCurrency(10000, 'EUR', 'EUR', rates)).toBe(10000);
|
|
9
|
+
});
|
|
10
|
+
test('uses the direct rate', () => {
|
|
11
|
+
expect(convertCurrency(10000, 'EUR', 'USD', rates)).toBe(12000);
|
|
12
|
+
});
|
|
13
|
+
test('uses the inverse rate when only the reverse is configured', () => {
|
|
14
|
+
expect(convertCurrency(12000, 'USD', 'EUR', rates)).toBe(Math.ceil(12000 / 1.2));
|
|
15
|
+
});
|
|
16
|
+
test('returns undefined when no pair matches', () => {
|
|
17
|
+
expect(convertCurrency(10000, 'BRL', 'USD', rates)).toBeUndefined();
|
|
18
|
+
});
|
|
19
|
+
test('uses Math.ceil to avoid underselling on partial units', () => {
|
|
20
|
+
expect(convertCurrency(999.5, 'EUR', 'USD', rates)).toBe(Math.ceil(999.5 * 1.2));
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=exchange-rates.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exchange-rates.test.js","sourceRoot":"/","sources":["utils/exchange-rates.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,KAAK,GAAmB;IAC5B,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE;IACrD,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE;CACzD,CAAC;AAEF,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,IAAI,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAClD,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAChC,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACrE,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC;IACnF,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAClD,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,uDAAuD,EAAE,GAAG,EAAE;QACjE,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC;IACnF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { ExchangeRate } from '../types/exchange-rates.js';\nimport { convertCurrency } from './exchange-rates.js';\n\nconst rates: ExchangeRate[] = [\n { fromCurrency: 'EUR', toCurrency: 'USD', rate: 1.2 },\n { fromCurrency: 'EUR', toCurrency: 'XOF', rate: 655.96 },\n];\n\ndescribe('convertCurrency', () => {\n test('passthrough when from and to are equal', () => {\n expect(convertCurrency(10000, 'EUR', 'EUR', rates)).toBe(10000);\n });\n\n test('uses the direct rate', () => {\n expect(convertCurrency(10000, 'EUR', 'USD', rates)).toBe(12000);\n });\n\n test('uses the inverse rate when only the reverse is configured', () => {\n expect(convertCurrency(12000, 'USD', 'EUR', rates)).toBe(Math.ceil(12000 / 1.2));\n });\n\n test('returns undefined when no pair matches', () => {\n expect(convertCurrency(10000, 'BRL', 'USD', rates)).toBeUndefined();\n });\n\n test('uses Math.ceil to avoid underselling on partial units', () => {\n expect(convertCurrency(999.5, 'EUR', 'USD', rates)).toBe(Math.ceil(999.5 * 1.2));\n });\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bisondesk/core-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.598",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "TheTruckCompany",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@date-fns/utc": "
|
|
9
|
-
"date-fns": "
|
|
8
|
+
"@date-fns/utc": "2.1.1",
|
|
9
|
+
"date-fns": "4.1.0",
|
|
10
10
|
"decimal.js": "10.4.3",
|
|
11
11
|
"immer": "10.0.3",
|
|
12
12
|
"joi": "17.13.3",
|
|
@@ -2,11 +2,13 @@ import { TENANT_ID_ADMIN_HEADER } from '@bisondesk/commons-sdk/constants';
|
|
|
2
2
|
import { XError } from '@bisondesk/commons-sdk/errors';
|
|
3
3
|
import { getAdminAuth } from '@bisondesk/commons-sdk/fetch';
|
|
4
4
|
import fetch, { Response } from 'node-fetch';
|
|
5
|
-
import {
|
|
5
|
+
import { CountryDeliveryRule } from '../types/country-delivery.js';
|
|
6
6
|
|
|
7
|
-
export const
|
|
7
|
+
export const listCountryDeliveryRules = async (
|
|
8
|
+
tenantId: string,
|
|
9
|
+
): Promise<CountryDeliveryRule[]> => {
|
|
8
10
|
const auth = await getAdminAuth();
|
|
9
|
-
const url = `${process.env.CORE_API_ORIGIN}/api/settings/country-
|
|
11
|
+
const url = `${process.env.CORE_API_ORIGIN}/api/settings/country-delivery`;
|
|
10
12
|
const response: Response = await fetch(url, {
|
|
11
13
|
headers: {
|
|
12
14
|
Authorization: auth,
|
package/src/constants.ts
CHANGED
|
@@ -42,7 +42,6 @@ export const SELLER_VAT_PERCENTAGE_PICKLIST_ID = 'sellerVatPercentages';
|
|
|
42
42
|
export const STEERING_TYPE_PICKLIST_ID = 'steering_type';
|
|
43
43
|
export const CRANE_MAKE_PICKLIST_ID = 'craneMakes';
|
|
44
44
|
export const ENGINEERING_DOCS_PICKLIST_ID = 'engineeringDocs';
|
|
45
|
-
export const SHIPPING_COMPANIES_PICKLIST_ID = 'shippingCompanies';
|
|
46
45
|
export const SLB_PARTNERS_PICKLIST_ID = 'slb_partners';
|
|
47
46
|
export const PURCHASE_LOGISTICS_STATUS_PICKLIST_ID = 'purchaseLogisticsStatus';
|
|
48
47
|
export const PURCHASE_DEAL_STATUS_PICKLIST_ID = 'purchaseDealStatus';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Categories } from '../constants.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Per-category freight figures. The two figures are paired by design — for any
|
|
5
|
+
* category covered by the rule, both must be set:
|
|
6
|
+
*
|
|
7
|
+
* - `cost` — internal freight cost. Feeds `externalTransport` on the cross-tenant
|
|
8
|
+
* purchase deal of the receiving tenant. Not customer-facing.
|
|
9
|
+
* - `price` — customer-facing delivery price. Surfaced on the storefront via
|
|
10
|
+
* `salesConditions.localizedPricing[i].deliveryPrice`. May exceed `cost` —
|
|
11
|
+
* the difference is the operator's margin on transport.
|
|
12
|
+
*/
|
|
13
|
+
export type CategoryDelivery = {
|
|
14
|
+
cost: number;
|
|
15
|
+
price: number;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type DeliveryFields =
|
|
19
|
+
| {
|
|
20
|
+
/**
|
|
21
|
+
* Paired `{ cost, price }` per vehicle category. Categories not present in
|
|
22
|
+
* the map have no freight quote in this rule.
|
|
23
|
+
*/
|
|
24
|
+
deliveryByCategory?: Partial<Record<Categories, CategoryDelivery>>;
|
|
25
|
+
/** Human-readable, e.g., "Iquique (Chile)". */
|
|
26
|
+
deliveryLocation: string;
|
|
27
|
+
}
|
|
28
|
+
| {
|
|
29
|
+
deliveryByCategory?: never;
|
|
30
|
+
deliveryLocation?: never;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Per-destination delivery rule. The owning tenant declares, for each destination country,
|
|
35
|
+
* which currency that country's pricing is quoted in, the per-category paired
|
|
36
|
+
* `{ cost, price }` freight figures, and a human-readable delivery location label.
|
|
37
|
+
* Currency conversion no longer lives here — see the shared `public.exchange_rates` table.
|
|
38
|
+
*/
|
|
39
|
+
export type CountryDeliveryRule = {
|
|
40
|
+
countryCode: string; // lower-cased ISO 3166-1 alpha-2 (e.g., "cl")
|
|
41
|
+
currency: string; // ISO 4217 (e.g., "USD")
|
|
42
|
+
} & DeliveryFields;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One row in the shared `public.exchange_rates` table. Direction-agnostic: an
|
|
3
|
+
* `EUR → USD` row at rate `1.2` also defines the reverse `USD → EUR` at
|
|
4
|
+
* `1 / 1.2 ≈ 0.833`. Operators only need to store one direction per pair.
|
|
5
|
+
*/
|
|
6
|
+
export type ExchangeRate = {
|
|
7
|
+
fromCurrency: string; // ISO 4217 (e.g., "EUR")
|
|
8
|
+
toCurrency: string; // ISO 4217 (e.g., "USD")
|
|
9
|
+
rate: number; // positive, amount in `toCurrency` per 1 unit of `fromCurrency`
|
|
10
|
+
};
|
package/src/types/marketing.ts
CHANGED
|
@@ -21,6 +21,18 @@ export type VehicleMarketingTargetTenant = {
|
|
|
21
21
|
tenantId: string;
|
|
22
22
|
branchId?: string;
|
|
23
23
|
allowWebsiteList?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* `true` when the entry was added by a human ticking the checkbox in the marketing form.
|
|
26
|
+
* Human-added entries are user-pinned: they persist until the user unchecks them, and
|
|
27
|
+
* they anchor the target copy alive (the copy is downgraded to UNKNOWN role rather than
|
|
28
|
+
* deleted when the filter no longer matches).
|
|
29
|
+
*
|
|
30
|
+
* Undefined or `false` means the entry was created by cross-tenant sync because the
|
|
31
|
+
* source vehicle matched the target's filter. Such entries are safe to remove
|
|
32
|
+
* automatically when the filter no longer matches and nothing else anchors the target
|
|
33
|
+
* copy. This is the default for legacy entries that predate this flag.
|
|
34
|
+
*/
|
|
35
|
+
humanAdded?: boolean;
|
|
24
36
|
};
|
|
25
37
|
|
|
26
38
|
export type VehicleMarketing = {
|
|
@@ -14,6 +14,10 @@ export type BeSpecificQuoteParams = {
|
|
|
14
14
|
other: BaseQuoteSettings['other'] & {
|
|
15
15
|
leasingStartupFeePercentage: string;
|
|
16
16
|
};
|
|
17
|
+
validationLimits?: {
|
|
18
|
+
minimumInterestRate?: string;
|
|
19
|
+
minimumDepositPercentage?: string;
|
|
20
|
+
};
|
|
17
21
|
insurance: {
|
|
18
22
|
allRisksCost: string;
|
|
19
23
|
allRisksTax: string;
|
package/src/types/vehicles.ts
CHANGED
|
@@ -379,6 +379,13 @@ export type VehicleOriginalInfo = {
|
|
|
379
379
|
remarks?: string;
|
|
380
380
|
available?: boolean;
|
|
381
381
|
};
|
|
382
|
+
/**
|
|
383
|
+
* The immediate source's sellability at the last sync hop: true when the source was not
|
|
384
|
+
* sellable — not in `SALE` role, had an active reservation or external sale, or was itself
|
|
385
|
+
* unavailable. Derived (never set by a human) and refreshed on every cross-tenant update so
|
|
386
|
+
* it cascades down the whole chain.
|
|
387
|
+
*/
|
|
388
|
+
unavailable?: boolean;
|
|
382
389
|
};
|
|
383
390
|
/**
|
|
384
391
|
* Deepest-origin tenant/branch in a multi-hop sync chain. Carries forward
|
|
@@ -530,15 +537,49 @@ export type VehicleExternalInfo = {
|
|
|
530
537
|
leasing?: boolean;
|
|
531
538
|
price?: string | undefined;
|
|
532
539
|
currency?: string | undefined;
|
|
540
|
+
/**
|
|
541
|
+
* Read-only field maintained by `fillReadOnlyFields` on every vehicle save:
|
|
542
|
+
* the value of `price` immediately before the most recent price change. Stays
|
|
543
|
+
* unchanged when `price` does not change between saves. Same currency as
|
|
544
|
+
* `price`. Useful for storefront "was/now" price-drop labels and for the AI
|
|
545
|
+
* assistant's negotiation context.
|
|
546
|
+
*/
|
|
547
|
+
previousPrice?: string;
|
|
533
548
|
marginScheme?: boolean;
|
|
534
549
|
manufacturerWarranty?: {
|
|
535
550
|
remarks?: string;
|
|
536
551
|
available?: boolean;
|
|
537
552
|
};
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
553
|
+
/**
|
|
554
|
+
* Per-country snapshot computed by the owning tenant's `fillReadOnlyFields`.
|
|
555
|
+
* Every field on this snapshot is public — `vehicle.external` rides through
|
|
556
|
+
* to the storefront via cross-tenant sync, so internal-only values (e.g. the
|
|
557
|
+
* owner's freight cost) must not appear here. Cross-tenant sync derives the
|
|
558
|
+
* internal `externalTransport` figure directly from the owner's country-
|
|
559
|
+
* delivery rule at sync time.
|
|
560
|
+
*
|
|
561
|
+
* Each entry exposes:
|
|
562
|
+
* - `price` — bare currency conversion for the rule's country.
|
|
563
|
+
* - `previousPrice` — bare conversion of `salesConditions.previousPrice`
|
|
564
|
+
* when set.
|
|
565
|
+
* - `deliveryPrice` — customer-facing delivery fee (when the rule covers
|
|
566
|
+
* the vehicle's category). Storefront consumers sum
|
|
567
|
+
* `price + (deliveryPrice ?? 0)` at the display layer.
|
|
568
|
+
* - `deliveryLocation` — human-readable label, present whenever the rule
|
|
569
|
+
* declared a location for this country.
|
|
570
|
+
*
|
|
571
|
+
* Only the original owner recomputes on save; cross-tenant copies preserve
|
|
572
|
+
* the array.
|
|
573
|
+
*/
|
|
574
|
+
localizedPricing?: Array<{
|
|
575
|
+
countryCode: string;
|
|
576
|
+
currency: string;
|
|
577
|
+
price: number;
|
|
578
|
+
previousPrice?: number;
|
|
579
|
+
deliveryPrice?: number;
|
|
580
|
+
deliveryLocation?: string;
|
|
581
|
+
}>;
|
|
582
|
+
};
|
|
542
583
|
superstructure?: VehicleSuperstructure;
|
|
543
584
|
weights?: {
|
|
544
585
|
gvw?: number;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ExchangeRate } from '../types/exchange-rates.js';
|
|
2
|
+
import { convertCurrency } from './exchange-rates.js';
|
|
3
|
+
|
|
4
|
+
const rates: ExchangeRate[] = [
|
|
5
|
+
{ fromCurrency: 'EUR', toCurrency: 'USD', rate: 1.2 },
|
|
6
|
+
{ fromCurrency: 'EUR', toCurrency: 'XOF', rate: 655.96 },
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
describe('convertCurrency', () => {
|
|
10
|
+
test('passthrough when from and to are equal', () => {
|
|
11
|
+
expect(convertCurrency(10000, 'EUR', 'EUR', rates)).toBe(10000);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('uses the direct rate', () => {
|
|
15
|
+
expect(convertCurrency(10000, 'EUR', 'USD', rates)).toBe(12000);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('uses the inverse rate when only the reverse is configured', () => {
|
|
19
|
+
expect(convertCurrency(12000, 'USD', 'EUR', rates)).toBe(Math.ceil(12000 / 1.2));
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('returns undefined when no pair matches', () => {
|
|
23
|
+
expect(convertCurrency(10000, 'BRL', 'USD', rates)).toBeUndefined();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('uses Math.ceil to avoid underselling on partial units', () => {
|
|
27
|
+
expect(convertCurrency(999.5, 'EUR', 'USD', rates)).toBe(Math.ceil(999.5 * 1.2));
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ExchangeRate } from '../types/exchange-rates.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Convert `amount` from `fromCurrency` to `toCurrency` using a direction-agnostic
|
|
5
|
+
* rate lookup. If a rate exists in either direction it is applied (inverted when
|
|
6
|
+
* needed). Returns `undefined` if no matching pair is configured.
|
|
7
|
+
*
|
|
8
|
+
* `Math.ceil` is applied on the result so the seller is never undersold by a
|
|
9
|
+
* partial unit of rounding.
|
|
10
|
+
*/
|
|
11
|
+
export const convertCurrency = (
|
|
12
|
+
amount: number,
|
|
13
|
+
fromCurrency: string,
|
|
14
|
+
toCurrency: string,
|
|
15
|
+
rates: ExchangeRate[],
|
|
16
|
+
): number | undefined => {
|
|
17
|
+
if (fromCurrency === toCurrency) {
|
|
18
|
+
return Math.ceil(amount);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const direct = rates.find((r) => r.fromCurrency === fromCurrency && r.toCurrency === toCurrency);
|
|
22
|
+
if (direct != null) {
|
|
23
|
+
return Math.ceil(amount * direct.rate);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const inverse = rates.find((r) => r.fromCurrency === toCurrency && r.toCurrency === fromCurrency);
|
|
27
|
+
if (inverse != null && inverse.rate > 0) {
|
|
28
|
+
return Math.ceil(amount / inverse.rate);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return undefined;
|
|
32
|
+
};
|