UNPKG

@chevre/domain

Version:

Chevre Domain Library for Node.js

876 lines (875 loc) 43 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AggregateOfferRepo = void 0; const createDebug = require("debug"); const factory = require("../factory"); const aggregateOffer_1 = require("./mongoose/schemas/aggregateOffer"); const debug = createDebug('chevre-domain:repo:aggregateOffer'); /** * 集計オファーリポジトリ */ class AggregateOfferRepo { constructor(connection) { this.aggregateOfferModel = connection.model(aggregateOffer_1.modelName, (0, aggregateOffer_1.createSchema)()); } // tslint:disable-next-line:cyclomatic-complexity max-func-body-length static CREATE_MATCH_STAGE(params) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50; const matchStages = []; const projectIdEq = (_b = (_a = params.project) === null || _a === void 0 ? void 0 : _a.id) === null || _b === void 0 ? void 0 : _b.$eq; if (typeof projectIdEq === 'string') { matchStages.push({ $match: { 'project.id': { $eq: projectIdEq } } }); } const parentOfferIdIn = (_d = (_c = params.parentOffer) === null || _c === void 0 ? void 0 : _c.id) === null || _d === void 0 ? void 0 : _d.$in; if (Array.isArray(parentOfferIdIn)) { matchStages.push({ $match: { _id: { $in: parentOfferIdIn } } }); } // aggregateOffer.includedInDataCatalogで検索する(2023-09-21~) const includedInDataCatalogIdIn = (_f = (_e = params.includedInDataCatalog) === null || _e === void 0 ? void 0 : _e.id) === null || _f === void 0 ? void 0 : _f.$in; if (Array.isArray(includedInDataCatalogIdIn)) { matchStages.push({ $match: { 'includedInDataCatalog.id': { $exists: true, $in: includedInDataCatalogIdIn } } }); } const idEq = (_g = params.id) === null || _g === void 0 ? void 0 : _g.$eq; if (typeof idEq === 'string') { matchStages.push({ $match: { _id: { $eq: idEq } } // _idに変更(2023-12-22~) }); } const idIn = (_h = params.id) === null || _h === void 0 ? void 0 : _h.$in; if (Array.isArray(idIn)) { matchStages.push({ $match: { _id: { $in: idIn } } // _idに変更(2023-12-22~) }); } const identifierEq = (_j = params.identifier) === null || _j === void 0 ? void 0 : _j.$eq; if (typeof identifierEq === 'string') { matchStages.push({ $match: { 'offers.identifier': { $exists: true, $eq: identifierEq } } }); } const identifierIn = (_k = params.identifier) === null || _k === void 0 ? void 0 : _k.$in; if (Array.isArray(identifierIn)) { matchStages.push({ $match: { 'offers.identifier': { $exists: true, $in: identifierIn } } }); } const identifierRegex = (_l = params.identifier) === null || _l === void 0 ? void 0 : _l.$regex; if (typeof identifierRegex === 'string' && identifierRegex.length > 0) { matchStages.push({ $match: { 'offers.identifier': { $exists: true, $regex: new RegExp(identifierRegex) } } }); } const nameRegex = (_m = params.name) === null || _m === void 0 ? void 0 : _m.$regex; if (typeof nameRegex === 'string' && nameRegex.length > 0) { const nameRegexExp = new RegExp(nameRegex); matchStages.push({ $match: { $or: [ { 'offers.name.ja': { $exists: true, $regex: nameRegexExp } }, { 'offers.name.en': { $exists: true, $regex: nameRegexExp } }, { 'offers.alternateName.ja': { $exists: true, $regex: nameRegexExp } }, { 'offers.alternateName.en': { $exists: true, $regex: nameRegexExp } } ] } }); } const itemOfferedTypeOfEq = (_p = (_o = params.itemOffered) === null || _o === void 0 ? void 0 : _o.typeOf) === null || _p === void 0 ? void 0 : _p.$eq; if (typeof itemOfferedTypeOfEq === 'string') { matchStages.push({ $match: { 'offers.itemOffered.typeOf': { $exists: true, $eq: itemOfferedTypeOfEq } } }); } const categoryCodeValueIn = (_r = (_q = params.category) === null || _q === void 0 ? void 0 : _q.codeValue) === null || _r === void 0 ? void 0 : _r.$in; if (Array.isArray(categoryCodeValueIn)) { matchStages.push({ $match: { 'offers.category.codeValue': { $exists: true, $in: categoryCodeValueIn } } }); } const eligibleMembershipTypeCodeValueEq = (_t = (_s = params.eligibleMembershipType) === null || _s === void 0 ? void 0 : _s.codeValue) === null || _t === void 0 ? void 0 : _t.$eq; if (typeof eligibleMembershipTypeCodeValueEq === 'string') { matchStages.push({ $match: { 'offers.eligibleMembershipType.codeValue': { $exists: true, $eq: eligibleMembershipTypeCodeValueEq } } }); } const eligibleMonetaryAmountCurrencyEq = (_v = (_u = params.eligibleMonetaryAmount) === null || _u === void 0 ? void 0 : _u.currency) === null || _v === void 0 ? void 0 : _v.$eq; if (typeof eligibleMonetaryAmountCurrencyEq === 'string') { matchStages.push({ $match: { 'offers.eligibleMonetaryAmount.currency': { $exists: true, $eq: eligibleMonetaryAmountCurrencyEq } } }); } const eligibleSeatingTypeCodeValueEq = (_x = (_w = params.eligibleSeatingType) === null || _w === void 0 ? void 0 : _w.codeValue) === null || _x === void 0 ? void 0 : _x.$eq; if (typeof eligibleSeatingTypeCodeValueEq === 'string') { matchStages.push({ $match: { 'offers.eligibleSeatingType.codeValue': { $exists: true, $eq: eligibleSeatingTypeCodeValueEq } } }); } const appliesToMovieTicketSize = (_z = (_y = params.priceSpecification) === null || _y === void 0 ? void 0 : _y.appliesToMovieTicket) === null || _z === void 0 ? void 0 : _z.$size; if (typeof appliesToMovieTicketSize === 'number') { matchStages.push({ $match: { 'offers.priceSpecification.appliesToMovieTicket': { $exists: true, $size: appliesToMovieTicketSize } } }); } const appliesToMovieTicketServiceTypeExist = (_2 = (_1 = (_0 = params.priceSpecification) === null || _0 === void 0 ? void 0 : _0.appliesToMovieTicket) === null || _1 === void 0 ? void 0 : _1.serviceType) === null || _2 === void 0 ? void 0 : _2.$exists; if (typeof appliesToMovieTicketServiceTypeExist === 'boolean') { matchStages.push({ $match: { 'offers.priceSpecification.appliesToMovieTicket.serviceType': { $exists: appliesToMovieTicketServiceTypeExist } } }); } const appliesToMovieTicketServiceTypeEq = (_5 = (_4 = (_3 = params.priceSpecification) === null || _3 === void 0 ? void 0 : _3.appliesToMovieTicket) === null || _4 === void 0 ? void 0 : _4.serviceType) === null || _5 === void 0 ? void 0 : _5.$eq; if (typeof appliesToMovieTicketServiceTypeEq === 'string') { matchStages.push({ $match: { 'offers.priceSpecification.appliesToMovieTicket.serviceType': { $exists: true, $eq: appliesToMovieTicketServiceTypeEq } } }); } const appliesToMovieTicketServiceOutputTypeOfEq = (_9 = (_8 = (_7 = (_6 = params.priceSpecification) === null || _6 === void 0 ? void 0 : _6.appliesToMovieTicket) === null || _7 === void 0 ? void 0 : _7.serviceOutput) === null || _8 === void 0 ? void 0 : _8.typeOf) === null || _9 === void 0 ? void 0 : _9.$eq; if (typeof appliesToMovieTicketServiceOutputTypeOfEq === 'string') { matchStages.push({ $match: { 'offers.priceSpecification.appliesToMovieTicket.serviceOutput.typeOf': { $exists: true, $eq: appliesToMovieTicketServiceOutputTypeOfEq } } }); } const appliesToMovieTicketServiceOutputTypeOfAll = (_13 = (_12 = (_11 = (_10 = params.priceSpecification) === null || _10 === void 0 ? void 0 : _10.appliesToMovieTicket) === null || _11 === void 0 ? void 0 : _11.serviceOutput) === null || _12 === void 0 ? void 0 : _12.typeOf) === null || _13 === void 0 ? void 0 : _13.$all; if (Array.isArray(appliesToMovieTicketServiceOutputTypeOfAll)) { matchStages.push({ $match: { 'offers.priceSpecification.appliesToMovieTicket.serviceOutput.typeOf': { $exists: true, $all: appliesToMovieTicketServiceOutputTypeOfAll } } }); } const appliesToMovieTicketServiceOutputTypeOfNin = (_17 = (_16 = (_15 = (_14 = params.priceSpecification) === null || _14 === void 0 ? void 0 : _14.appliesToMovieTicket) === null || _15 === void 0 ? void 0 : _15.serviceOutput) === null || _16 === void 0 ? void 0 : _16.typeOf) === null || _17 === void 0 ? void 0 : _17.$nin; if (Array.isArray(appliesToMovieTicketServiceOutputTypeOfNin)) { matchStages.push({ $match: { 'offers.priceSpecification.appliesToMovieTicket.serviceOutput.typeOf': { $nin: appliesToMovieTicketServiceOutputTypeOfNin } } }); } if (params.priceSpecification !== undefined && params.priceSpecification !== null) { const priceSpecificationPriceGte = (_18 = params.priceSpecification.price) === null || _18 === void 0 ? void 0 : _18.$gte; if (typeof priceSpecificationPriceGte === 'number') { matchStages.push({ $match: { 'offers.priceSpecification.price': { $exists: true, $gte: priceSpecificationPriceGte } } }); } const priceSpecificationPriceLte = (_19 = params.priceSpecification.price) === null || _19 === void 0 ? void 0 : _19.$lte; if (typeof priceSpecificationPriceLte === 'number') { matchStages.push({ $match: { 'offers.priceSpecification.price': { $exists: true, $lte: priceSpecificationPriceLte } } }); } const accountsReceivableGte = (_21 = (_20 = params.priceSpecification.accounting) === null || _20 === void 0 ? void 0 : _20.accountsReceivable) === null || _21 === void 0 ? void 0 : _21.$gte; if (typeof accountsReceivableGte === 'number') { matchStages.push({ $match: { 'offers.priceSpecification.accounting.accountsReceivable': { $exists: true, $gte: accountsReceivableGte } } }); } const accountsReceivableLte = (_23 = (_22 = params.priceSpecification.accounting) === null || _22 === void 0 ? void 0 : _22.accountsReceivable) === null || _23 === void 0 ? void 0 : _23.$lte; if (typeof accountsReceivableLte === 'number') { matchStages.push({ $match: { 'offers.priceSpecification.accounting.accountsReceivable': { $exists: true, $lte: accountsReceivableLte } } }); } const accountingCodeValueEq = (_26 = (_25 = (_24 = params.priceSpecification.accounting) === null || _24 === void 0 ? void 0 : _24.operatingRevenue) === null || _25 === void 0 ? void 0 : _25.codeValue) === null || _26 === void 0 ? void 0 : _26.$eq; if (typeof accountingCodeValueEq === 'string') { matchStages.push({ $match: { 'offers.priceSpecification.accounting.operatingRevenue.codeValue': { $exists: true, $eq: accountingCodeValueEq } } }); } const accountingCodeValueIn = (_29 = (_28 = (_27 = params.priceSpecification.accounting) === null || _27 === void 0 ? void 0 : _27.operatingRevenue) === null || _28 === void 0 ? void 0 : _28.codeValue) === null || _29 === void 0 ? void 0 : _29.$in; if (Array.isArray(accountingCodeValueIn)) { matchStages.push({ $match: { 'offers.priceSpecification.accounting.operatingRevenue.codeValue': { $exists: true, $in: accountingCodeValueIn } } }); } const referenceQuantityValueEq = (_31 = (_30 = params.priceSpecification.referenceQuantity) === null || _30 === void 0 ? void 0 : _30.value) === null || _31 === void 0 ? void 0 : _31.$eq; if (typeof referenceQuantityValueEq === 'number') { matchStages.push({ $match: { 'offers.priceSpecification.referenceQuantity.value': { $exists: true, $eq: referenceQuantityValueEq } } }); } } const availabilityEq = (_32 = params.availability) === null || _32 === void 0 ? void 0 : _32.$eq; if (typeof availabilityEq === 'string') { matchStages.push({ $match: { 'offers.availability': { $eq: availabilityEq } } }); } const availableAtOrFromIdEq = (_34 = (_33 = params.availableAtOrFrom) === null || _33 === void 0 ? void 0 : _33.id) === null || _34 === void 0 ? void 0 : _34.$eq; if (typeof availableAtOrFromIdEq === 'string') { matchStages.push({ $match: { 'offers.availableAtOrFrom.id': { $exists: true, $eq: availableAtOrFromIdEq } } }); } const availableAtOrFromIdIn = (_36 = (_35 = params.availableAtOrFrom) === null || _35 === void 0 ? void 0 : _35.id) === null || _36 === void 0 ? void 0 : _36.$in; if (Array.isArray(availableAtOrFromIdIn)) { matchStages.push({ $match: { 'offers.availableAtOrFrom.id': { $exists: true, $in: availableAtOrFromIdIn } } }); } const addOnItemOfferedIdEq = (_39 = (_38 = (_37 = params.addOn) === null || _37 === void 0 ? void 0 : _37.itemOffered) === null || _38 === void 0 ? void 0 : _38.id) === null || _39 === void 0 ? void 0 : _39.$eq; if (typeof addOnItemOfferedIdEq === 'string') { matchStages.push({ $match: { 'offers.addOn.itemOffered.id': { $exists: true, $eq: addOnItemOfferedIdEq } } }); } const addOnItemOfferedIdIn = (_42 = (_41 = (_40 = params.addOn) === null || _40 === void 0 ? void 0 : _40.itemOffered) === null || _41 === void 0 ? void 0 : _41.id) === null || _42 === void 0 ? void 0 : _42.$in; if (Array.isArray(addOnItemOfferedIdIn)) { matchStages.push({ $match: { 'offers.addOn.itemOffered.id': { $exists: true, $in: addOnItemOfferedIdIn } } }); } const hasMerchantReturnPolicyIdEq = (_44 = (_43 = params.hasMerchantReturnPolicy) === null || _43 === void 0 ? void 0 : _43.id) === null || _44 === void 0 ? void 0 : _44.$eq; if (typeof hasMerchantReturnPolicyIdEq === 'string') { matchStages.push({ $match: { 'offers.hasMerchantReturnPolicy.id': { $exists: true, $eq: hasMerchantReturnPolicyIdEq } } }); } const acceptedPaymentMethodIdentifierIn = (_46 = (_45 = params.acceptedPaymentMethod) === null || _45 === void 0 ? void 0 : _45.identifier) === null || _46 === void 0 ? void 0 : _46.$in; if (Array.isArray(acceptedPaymentMethodIdentifierIn)) { matchStages.push({ $match: { 'offers.acceptedPaymentMethod.identifier': { $exists: true, $in: acceptedPaymentMethodIdentifierIn } } }); } const additionalPropertyAll = (_47 = params.additionalProperty) === null || _47 === void 0 ? void 0 : _47.$all; if (Array.isArray(additionalPropertyAll)) { matchStages.push({ $match: { 'offers.additionalProperty': { $exists: true, $all: additionalPropertyAll } } }); } const additionalPropertyElemMatch = (_48 = params.additionalProperty) === null || _48 === void 0 ? void 0 : _48.$elemMatch; if (additionalPropertyElemMatch !== undefined && additionalPropertyElemMatch !== null) { matchStages.push({ $match: { 'offers.additionalProperty': { $exists: true, $elemMatch: additionalPropertyElemMatch } } }); } if (params.onlyValid === true) { const now = new Date(); matchStages.push({ $match: { $or: [ { 'offers.validFrom': { $exists: false } }, { 'offers.validFrom': { $exists: true, $lte: now } } ] } }, { $match: { $or: [ { 'offers.validThrough': { $exists: false } }, { 'offers.validThrough': { $exists: true, $gte: now } } ] } }); } // add advanceBookingRequirement.id.$eq(2025-04-08~) const advanceBookingRequirementIdEq = (_50 = (_49 = params.advanceBookingRequirement) === null || _49 === void 0 ? void 0 : _49.id) === null || _50 === void 0 ? void 0 : _50.$eq; if (typeof advanceBookingRequirementIdEq === 'string') { matchStages.push({ $match: { 'offers.advanceBookingRequirement.id': { $exists: true, $eq: advanceBookingRequirementIdEq } } }); } return matchStages; } static CREATE_AGGREGATE_OFFERS_PROJECTION(params) { let projectStage = { _id: 0, id: '$_id', typeOf: '$typeOf', project: '$project', offers: [{ $first: '$offers' }], highPrice: { $max: '$offers.priceSpecification.price' }, lowPrice: { $min: '$offers.priceSpecification.price' }, offerCount: { $size: '$offers' } }; const positiveProjectionFields = Object.keys(params) .filter((key) => params[key] !== 0); const negativeProjectionFields = Object.keys(params) .filter((key) => params[key] === 0); if (positiveProjectionFields.length > 0) { projectStage = { _id: 0, id: '$_id', typeOf: '$typeOf', project: '$project', // offers: [{ $first: '$offers' }], highPrice: { $max: '$offers.priceSpecification.price' }, lowPrice: { $min: '$offers.priceSpecification.price' }, offerCount: { $size: '$offers' } }; const offersProjection = {}; positiveProjectionFields.forEach((field) => { offersProjection[field] = { $first: `$offers.${field}` }; }); projectStage.offers = [offersProjection]; } else if (negativeProjectionFields.length > 0) { negativeProjectionFields.forEach((field) => { if (typeof projectStage[field] === 'string') { // tslint:disable-next-line:no-dynamic-delete delete projectStage[field]; } }); } return projectStage; } search(params, projection) { return __awaiter(this, void 0, void 0, function* () { var _a, _b; const matchStages = AggregateOfferRepo.CREATE_MATCH_STAGE(params); const projectStage = AggregateOfferRepo.CREATE_AGGREGATE_OFFERS_PROJECTION(Object.assign({}, projection)); const sortByPrice = (_a = params.sort) === null || _a === void 0 ? void 0 : _a['priceSpecification.price']; const sortByIdentifier = (_b = params.sort) === null || _b === void 0 ? void 0 : _b.identifier; const aggregate = this.aggregateOfferModel.aggregate([ ...matchStages, ...(typeof sortByPrice === 'number' || typeof sortByIdentifier === 'number') ? [ { $sort: Object.assign(Object.assign({}, (typeof sortByPrice === 'number') ? { 'offers.priceSpecification.price': sortByPrice } : undefined), (typeof sortByIdentifier === 'number') ? { 'offers.identifier': sortByIdentifier } : undefined) } ] : [], { $project: projectStage } ]); // tslint:disable-next-line:no-single-line-block-comment /* istanbul ignore else */ if (typeof params.limit === 'number' && params.limit > 0) { const page = (typeof params.page === 'number' && params.page > 0) ? params.page : 1; aggregate.limit(params.limit * page) .skip(params.limit * (page - 1)); } return aggregate.exec(); }); } pushIncludedInDataCatalog(params) { return __awaiter(this, void 0, void 0, function* () { if (!Array.isArray(params.id.$in) || params.id.$in.length === 0) { return; } const pushIncludedInDataCatalogIds = params.$push.includedInDataCatalog.$each.map((element) => element.id); if (pushIncludedInDataCatalogIds.length === 0) { return; } const newIncludedInDataCatalogs = pushIncludedInDataCatalogIds.map((catalogId) => { return { id: catalogId, typeOf: 'OfferCatalog' }; }); const result = yield this.aggregateOfferModel.updateMany({ 'project.id': { $eq: params.project.id }, _id: { $in: params.id.$in }, // includedInDataCatalogのユニークネスを保証する 'includedInDataCatalog.id': { $nin: pushIncludedInDataCatalogIds } }, // { $addToSet: { includedInDataCatalog: { $each: newIncludedInDataCatalogs } } } { $push: { includedInDataCatalog: { $each: newIncludedInDataCatalogs // $slice: params.$push.includedInDataCatalog.$slice } } }) .exec(); debug('result', result); }); } /** * 記載カタログからカタログを除外する */ pullIncludedInDataCatalog(params) { return __awaiter(this, void 0, void 0, function* () { var _a; const idNin = (_a = params.id) === null || _a === void 0 ? void 0 : _a.$nin; const pullingCatalogId = params.$pull.includedInDataCatalog.$elemMatch.id.$eq; yield this.aggregateOfferModel.updateMany(Object.assign({ 'project.id': { $eq: params.project.id }, 'includedInDataCatalog.id': { $exists: true, $eq: pullingCatalogId } }, (Array.isArray(idNin)) ? { _id: { $nin: idNin } } : undefined), { $pull: { includedInDataCatalog: { id: { $eq: pullingCatalogId } } } }) .exec(); }); } deleteById(params) { return __awaiter(this, void 0, void 0, function* () { yield this.aggregateOfferModel.findOneAndDelete({ _id: { $eq: params.id }, 'project.id': { $eq: params.project.id } }, { projection: { _id: 1 } }) .exec(); }); } // 単価オファー最適化作業における一時的な処理 // public async optimizeOffers() { // return this.aggregateOfferModel.updateMany( // { // $or: [ // { 'offers.id': { $exists: true } }, // { 'offers.project': { $exists: true } } // ] // }, // { // $set: {}, // $unset: { // 'offers.0.id': 1, // 'offers.0.project': 1 // } // } // ) // .exec(); // } getCursor(conditions, projection) { return this.aggregateOfferModel.find(conditions, projection) .sort({ 'offers.identifier': factory.sortType.Ascending }) .cursor(); } unsetUnnecessaryFields(params) { return __awaiter(this, void 0, void 0, function* () { return this.aggregateOfferModel.updateMany(params.filter, { $unset: params.$unset }, { timestamps: false }) .exec(); }); } save(params) { return __awaiter(this, void 0, void 0, function* () { var _a; let doc; let aggregateOfferId; // const { $unset, ...paramsWithoutUnset } = params; const paramsWithoutUnset = __rest(params, []); // let savedUnitPriceOffer: factory.unitPriceOffer.IUnitPriceOffer; if (typeof params.id !== 'string' || params.id.length === 0) { const uniqid = yield Promise.resolve().then(() => require('uniqid')); const newId = uniqid(); aggregateOfferId = newId; // サブオファー最適化(2023-12-22~) // savedUnitPriceOffer = { ...paramsWithoutUnset, id }; const { id, project } = paramsWithoutUnset, savedUnitPriceOffer = __rest(paramsWithoutUnset, ["id", "project"]); const aggregateOffer = { typeOf: factory.offerType.AggregateOffer, project: params.project, offers: [savedUnitPriceOffer] }; doc = yield this.aggregateOfferModel.create(Object.assign(Object.assign({}, aggregateOffer), { _id: newId })); } else { aggregateOfferId = params.id; // const unitPriceOffers = <Pick<factory.unitPriceOffer.IUnitPriceOffer, 'id' | 'identifier' | 'project' | 'typeOf'>[]> // await this.search( // { // limit: 1, // page: 1, // project: { id: { $eq: params.project.id } }, // id: { $eq: params.id } // }, // { identifier: 1, project: 1, typeOf: 1 } // ); // const originalUnitPriceOffer = unitPriceOffers.shift(); const aggregateOffers = yield this.search({ limit: 1, page: 1, project: { id: { $eq: params.project.id } }, id: { $eq: params.id } }); const originalUnitPriceOffer = (_a = aggregateOffers.shift()) === null || _a === void 0 ? void 0 : _a.offers.shift(); if (originalUnitPriceOffer === undefined) { throw new factory.errors.NotFound(factory.offerType.Offer); } // 上書き禁止属性を除外 const { id, identifier, project, typeOf } = paramsWithoutUnset, updateFields = __rest(paramsWithoutUnset, ["id", "identifier", "project", "typeOf"]); // サブオファー最適化(2023-12-22~) const subOffer = Object.assign(Object.assign({}, updateFields), { // id: originalUnitPriceOffer.id, identifier: originalUnitPriceOffer.identifier, // project: originalUnitPriceOffer.project, typeOf: originalUnitPriceOffer.typeOf }); doc = yield this.aggregateOfferModel.findOneAndUpdate( // { 'offers.id': params.id }, { _id: params.id }, // _idに変更(2023-12-22~) { $set: { // 'offers.$[offer]': savedUnitPriceOffer 'offers.0': subOffer // _idに変更(2023-12-22~) } }, { upsert: false, new: true // _idに変更(2023-12-22~) // arrayFilters: [ // { 'offer.id': { $eq: params.id } } // ] }) .exec(); } if (doc === null) { throw new factory.errors.NotFound(this.aggregateOfferModel.modelName); } return { id: aggregateOfferId }; }); } /** * コードをキーにして冪等置換(2023-12-13~) */ upsertByIdentifier(params) { return __awaiter(this, void 0, void 0, function* () { const uniqid = yield Promise.resolve().then(() => require('uniqid')); const insertBulkWriteOps = []; // const updateBulkWriteOps: AnyBulkWriteOperation<factory.aggregateOffer.IAggregateOffer>[] = []; const queryFilters = []; if (Array.isArray(params)) { params.forEach((p) => { // リソースのユニークネスを保証するfilter const filter = { 'project.id': { $eq: p.project.id }, 'offers.identifier': { $exists: true, $eq: p.identifier } }; queryFilters.push({ 'project.id': { $eq: p.project.id }, 'offers.identifier': { $exists: true, $eq: p.identifier } }); const newOfferId = uniqid(); // setOnInsert時のみに利用する新ID // サブオファー最適化(2023-12-22~) const { project } = p, subOffer = __rest(p, ["project"]); const aggregateOffer = { project: p.project, typeOf: factory.offerType.AggregateOffer, offers: [subOffer] }; const setOnInsert = { project: aggregateOffer.project, typeOf: aggregateOffer.typeOf, _id: newOfferId }; const updateFilter = { $setOnInsert: setOnInsert, $set: { offers: aggregateOffer.offers } }; const updateOneOnInsert = { filter, update: updateFilter, upsert: true }; insertBulkWriteOps.push({ updateOne: updateOneOnInsert }); }); } if (insertBulkWriteOps.length > 0) { const bulkWriteResult = yield this.aggregateOfferModel.bulkWrite(insertBulkWriteOps, { ordered: false }); // modifiedの場合upsertedIdsに含まれないので、idを検索する const modifiedOffers = yield this.aggregateOfferModel.find({ $or: queryFilters }, // { _id: 1, 'offers.identifier': 1 } { _id: 0, id: '$_id' }) .lean() // lean(2024-09-26~) .exec(); return { bulkWriteResult, modifiedOffers }; } }); } /** * sskts専用オファー保管 */ // tslint:disable-next-line:max-func-body-length saveManyByIdentifier4sskts(params) { return __awaiter(this, void 0, void 0, function* () { const uniqid = yield Promise.resolve().then(() => require('uniqid')); const insertBulkWriteOps = []; // const updateBulkWriteOps: AnyBulkWriteOperation[] = []; if (Array.isArray(params)) { params.forEach((p) => { const newOfferId = uniqid(); // サブオファー最適化(2023-12-22~) // const unitPriceOffer: factory.aggregateOffer.ISubOffer = { ...p.attributes, id: newOfferId }; const subOffer = p.attributes; const aggregateOffer = { project: { id: p.project.id, typeOf: factory.organizationType.Project }, typeOf: factory.offerType.AggregateOffer, offers: [subOffer] }; insertBulkWriteOps.push({ updateOne: { filter: { 'project.id': { $eq: p.project.id }, 'offers.identifier': { $exists: true, $eq: p.attributes.identifier } }, update: { $setOnInsert: { // ...aggregateOffer, project: aggregateOffer.project, typeOf: aggregateOffer.typeOf, _id: newOfferId }, $set: { offers: aggregateOffer.offers } // サブオファー最適化(2023-12-22~) }, upsert: true } }); // updateBulkWriteOps.push({ // updateOne: { // filter: { // 'project.id': { $eq: aggregateOffer.project.id }, // 'offers.identifier': { $exists: true, $eq: subOffer.identifier } // }, // update: { // // 特定の属性のみ更新する(IDを上書きできないので) // $set: { // 'offers.0.name': subOffer.name, // 'offers.0.description': subOffer.description, // 'offers.0.alternateName': subOffer.alternateName, // 'offers.0.priceSpecification': subOffer.priceSpecification, // 'offers.0.additionalProperty': subOffer.additionalProperty, // ...(Array.isArray(subOffer.eligibleMembershipType)) // ? { 'offers.0.eligibleMembershipType': subOffer.eligibleMembershipType } // : undefined, // ...(Array.isArray(subOffer.eligibleMonetaryAmount)) // ? { 'offers.0.eligibleMonetaryAmount': subOffer.eligibleMonetaryAmount } // : undefined // }, // }, // upsert: false // } // }); }); } if (insertBulkWriteOps.length > 0) { yield this.aggregateOfferModel.bulkWrite(insertBulkWriteOps, { ordered: false }); // await this.aggregateOfferModel.bulkWrite(updateBulkWriteOps, { ordered: false }); } }); } /** * プロダクトIDからアドオンを除外する */ pullAddOns(params) { return __awaiter(this, void 0, void 0, function* () { if (params.addOn.itemOffered.id.$in.length === 0) { return; } const conditions = { 'project.id': { $eq: params.project.id }, 'offers.addOn.itemOffered.id': { $exists: true, $in: params.addOn.itemOffered.id.$in } }; // const updatingOffers = <Pick<factory.unitPriceOffer.IUnitPriceOffer, 'id' | 'identifier'>[]>await this.search( // { // project: { id: { $eq: params.project.id } }, // addOn: { itemOffered: { id: { $in: params.addOn.itemOffered.id.$in } } } // }, // { identifier: 1 } // ); return this.aggregateOfferModel.updateMany(conditions, { $pull: { 'offers.$[offer].addOn': { 'itemOffered.id': { $in: params.addOn.itemOffered.id.$in } } } }, { arrayFilters: [ { 'offer.addOn.itemOffered.id': { $exists: true, $in: params.addOn.itemOffered.id.$in } } ] }) .exec(); // if (updatingOffers.length > 0) { // // no op // } // return result; }); } countIncludedInDataCatalog(params) { return __awaiter(this, void 0, void 0, function* () { const aggregate = this.aggregateOfferModel.aggregate([ { $match: { _id: { $eq: params.id.$eq } } }, { $project: { _id: 0, includedInDataCatalogCount: { $cond: { if: { $isArray: '$includedInDataCatalog' }, then: { $size: '$includedInDataCatalog' }, else: 0 } } } } ]); return aggregate.exec(); }); } maxIncludedInDataCatalogCount() { return __awaiter(this, void 0, void 0, function* () { const aggregate = this.aggregateOfferModel.aggregate([ // { // $match: { // _id: { $eq: params.id.$eq } // } // }, { $project: { _id: 0, includedInDataCatalogCount: { $cond: { if: { $isArray: '$includedInDataCatalog' }, then: { $size: '$includedInDataCatalog' }, else: 0 } } } }, { $group: { // tslint:disable-next-line:no-null-keyword _id: null, maxCount: { $max: '$includedInDataCatalogCount' } } }, { $project: { _id: 0, maxCount: '$maxCount' } } ]); return aggregate.exec(); }); } } exports.AggregateOfferRepo = AggregateOfferRepo;