import { inject, injectable } from "inversify"; import PartnerActivity, { IPartnerActivity, IPartnerActivityResource, IPartnerActivityAttributes, partnerActivityType, IPartnerActivityPrice } from "./"; import { IJsonApiResource } from "../../interfaces"; import Mapper from "../../mapper"; import * as TYPES from "../../types"; import { isTourOrActivity } from "./partnerActivityType"; import imgix from "../../utils/imgix"; import formattedPrice from "../../utils/formattedPrice"; @injectable() export class PartnerActivityMapper extends Mapper { @inject(TYPES.Bookmark) model: IPartnerActivity; toModel(resource: IPartnerActivityResource, included: IJsonApiResource[] = []): IPartnerActivity { const model = new PartnerActivity(); const attrs = resource.attributes; model.accommodation = attrs.accommodation; model.canonicalCategory = attrs.canonical_category; model.categories = attrs.categories; model.departureInfo = attrs.departure_info; model.descriptions.longDescription = attrs.descriptions.long_description; model.descriptions.shortDescription = attrs.descriptions.short_description; model.difficulty.description = attrs.difficulty.description; model.difficulty.grade = attrs.difficulty.grade; model.difficulty.scale = attrs.difficulty.scale; model.durationInfo = attrs.duration_info; model.duration = attrs.duration; model.exclusions = attrs.exclusions; model.externalId = attrs.external_id; model.groupSize.averageSize = attrs.group_size.average_size; model.groupSize.description = attrs.group_size.description; model.groupSize.maximumSize = attrs.group_size.maximum_size; model.groupSize.minimumSize = attrs.group_size.minimum_size; model.highlights = attrs.highlights; model.id = resource.id; model.inclusions = attrs.inclusions; model.itinerary = attrs.itinerary; model.meals = attrs.meals; model.media = { images: attrs.media.images && attrs.media.images.length > 0 ? attrs.media.images.map((image) => imgix(image, attrs.provider)) : attrs.media.images, videos: attrs.media.videos, }; model.name = attrs.name; const priceToModelPrice = (price: any = {}) => ({ amount: price.amount, currency: price.currency, formattedAmount: formattedPrice(price.formatted_amount), }); if (attrs.pricing.discounted_price) { model.pricing.discountedPrice = priceToModelPrice(attrs.pricing.discounted_price); } if (attrs.pricing.regular_price) { model.pricing.regularPrice = priceToModelPrice(attrs.pricing.regular_price); } if (attrs.prices && Array.isArray(attrs.prices.regular_prices)) { model.prices.regularPrices = attrs.prices.regular_prices.map(priceToModelPrice); } if (attrs.prices && Array.isArray(attrs.prices.discounted_prices)) { model.prices.discountedPrices = attrs.prices.discounted_prices.map(priceToModelPrice); } model.provider = attrs.provider; model.rating = attrs.rating; model.returnInfo = attrs.return_info; model.reviewCount = attrs.review_count; model.staffExperts = attrs.staff_experts; model.transport = attrs.transport; const places = (resource.relationships["places"].data); if (places && places.length) { model.containingPlaceId = places[0].id; } model.map = resource.links.map; model.images = resource.links.image ? [{ url: imgix(resource.links.image, attrs.provider), attribution: [{ name: "", organization: attrs.provider, }], caption: "", height: 0, orientation: "landscape", path: resource.links.image.substr(resource.links.image.lastIndexOf(".com/") + 4, resource.links.image.length), tags: [], width: 0, }] : []; model.booking = resource.links.booking; model.activityType = isTourOrActivity(attrs.duration); return model; } toResource(model: IPartnerActivity): IPartnerActivityResource { const modelPriceToResourcePrice = (price) => ({ amount: price.amount, currency: price.currency, formatted_amount: price.formattedAmount, }); const resource = { id: model.id, type: partnerActivityType, attributes: { accommodation: model.accommodation, canonical_category: model.canonicalCategory, categories: model.categories, departure_info: model.departureInfo, descriptions: { long_description: model.descriptions.longDescription, short_description: model.descriptions.shortDescription, }, difficulty: { description: model.difficulty.description, grade: model.difficulty.grade, scale: model.difficulty.scale, }, duration: { duration: model.duration.duration, unit: model.duration.unit, }, duration_info: model.durationInfo, exclusions: model.exclusions, external_id: model.externalId, group_size: { average_size: model.groupSize.averageSize, description: model.groupSize.description, maximum_size: model.groupSize.maximumSize, minimum_size: model.groupSize.minimumSize, }, highlights: model.highlights, id: model.id, inclusions: model.inclusions, itinerary: model.itinerary, meals: model.meals, media: model.media, name: model.name, prices: { discounted_prices: model.prices.discountedPrices.map(modelPriceToResourcePrice), regular_prices: model.prices.regularPrices.map(modelPriceToResourcePrice), }, pricing: { discounted_price: { amount: model.pricing.discountedPrice.amount, currency: model.pricing.discountedPrice.currency, formatted_amount: model.pricing.discountedPrice.formattedAmount, }, regular_price: { amount: model.pricing.regularPrice.amount, currency: model.pricing.regularPrice.currency, formatted_amount: model.pricing.regularPrice.formattedAmount, }, }, provider: model.provider, rating: model.rating, return_info: model.returnInfo, review_count: model.reviewCount, staff_experts: model.staffExperts, transport: model.transport, }, }; return resource; } } export default PartnerActivityMapper;