@vendure/core
Version:
A modern, headless ecommerce framework
200 lines • 10.7 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProductOptionGroupService = void 0;
const common_1 = require("@nestjs/common");
const generated_types_1 = require("@vendure/common/lib/generated-types");
const typeorm_1 = require("typeorm");
const instrument_decorator_1 = require("../../common/instrument-decorator");
const utils_1 = require("../../common/utils");
const vendure_logger_1 = require("../../config/logger/vendure-logger");
const transactional_connection_1 = require("../../connection/transactional-connection");
const product_option_group_translation_entity_1 = require("../../entity/product-option-group/product-option-group-translation.entity");
const product_option_group_entity_1 = require("../../entity/product-option-group/product-option-group.entity");
const product_variant_entity_1 = require("../../entity/product-variant/product-variant.entity");
const product_entity_1 = require("../../entity/product/product.entity");
const event_bus_1 = require("../../event-bus");
const product_option_group_event_1 = require("../../event-bus/events/product-option-group-event");
const custom_field_relation_service_1 = require("../helpers/custom-field-relation/custom-field-relation.service");
const translatable_saver_1 = require("../helpers/translatable-saver/translatable-saver");
const translator_service_1 = require("../helpers/translator/translator.service");
const product_option_service_1 = require("./product-option.service");
/**
* @description
* Contains methods relating to {@link ProductOptionGroup} entities.
*
* @docsCategory services
*/
let ProductOptionGroupService = class ProductOptionGroupService {
constructor(connection, translatableSaver, customFieldRelationService, productOptionService, eventBus, translator) {
this.connection = connection;
this.translatableSaver = translatableSaver;
this.customFieldRelationService = customFieldRelationService;
this.productOptionService = productOptionService;
this.eventBus = eventBus;
this.translator = translator;
}
findAll(ctx, filterTerm, relations) {
const findOptions = {
relations: relations !== null && relations !== void 0 ? relations : ['options'],
where: {
deletedAt: (0, typeorm_1.IsNull)(),
},
};
if (filterTerm) {
findOptions.where = Object.assign({ code: (0, typeorm_1.Like)(`%${filterTerm}%`) }, findOptions.where);
}
return this.connection
.getRepository(ctx, product_option_group_entity_1.ProductOptionGroup)
.find(findOptions)
.then(groups => groups.map(group => this.translator.translate(group, ctx, ['options'])));
}
findOne(ctx, id, relations, findOneOptions) {
return this.connection
.getRepository(ctx, product_option_group_entity_1.ProductOptionGroup)
.findOne({
where: {
id,
deletedAt: !(findOneOptions === null || findOneOptions === void 0 ? void 0 : findOneOptions.includeSoftDeleted) ? (0, typeorm_1.IsNull)() : undefined,
},
relations: relations !== null && relations !== void 0 ? relations : ['options'],
})
.then(group => { var _a; return (_a = (group && this.translator.translate(group, ctx, ['options']))) !== null && _a !== void 0 ? _a : undefined; });
}
getOptionGroupsByProductId(ctx, id) {
return this.connection
.getRepository(ctx, product_option_group_entity_1.ProductOptionGroup)
.find({
relations: ['options'],
where: {
product: { id },
deletedAt: (0, typeorm_1.IsNull)(),
},
order: {
id: 'ASC',
},
})
.then(groups => groups.map(group => this.translator.translate(group, ctx, ['options'])));
}
async create(ctx, input) {
const group = await this.translatableSaver.create({
ctx,
input,
entityType: product_option_group_entity_1.ProductOptionGroup,
translationType: product_option_group_translation_entity_1.ProductOptionGroupTranslation,
});
const groupWithRelations = await this.customFieldRelationService.updateRelations(ctx, product_option_group_entity_1.ProductOptionGroup, input, group);
await this.eventBus.publish(new product_option_group_event_1.ProductOptionGroupEvent(ctx, groupWithRelations, 'created', input));
return (0, utils_1.assertFound)(this.findOne(ctx, group.id));
}
async update(ctx, input) {
const group = await this.translatableSaver.update({
ctx,
input,
entityType: product_option_group_entity_1.ProductOptionGroup,
translationType: product_option_group_translation_entity_1.ProductOptionGroupTranslation,
});
await this.customFieldRelationService.updateRelations(ctx, product_option_group_entity_1.ProductOptionGroup, input, group);
await this.eventBus.publish(new product_option_group_event_1.ProductOptionGroupEvent(ctx, group, 'updated', input));
return (0, utils_1.assertFound)(this.findOne(ctx, group.id));
}
/**
* @description
* Deletes the ProductOptionGroup and any associated ProductOptions. If the ProductOptionGroup
* is still referenced by a soft-deleted Product, then a soft-delete will be used to preserve
* referential integrity. Otherwise a hard-delete will be performed.
*/
async deleteGroupAndOptionsFromProduct(ctx, id, productId) {
const optionGroup = await this.connection.getEntityOrThrow(ctx, product_option_group_entity_1.ProductOptionGroup, id, {
relationLoadStrategy: 'query',
loadEagerRelations: false,
relations: ['options', 'product'],
});
const deletedOptionGroup = new product_option_group_entity_1.ProductOptionGroup(optionGroup);
const inUseByActiveProducts = await this.isInUseByOtherProducts(ctx, optionGroup, productId);
if (0 < inUseByActiveProducts) {
return {
result: generated_types_1.DeletionResult.NOT_DELETED,
message: ctx.translate('message.product-option-group-used', {
code: optionGroup.code,
count: inUseByActiveProducts,
}),
};
}
const optionsToDelete = optionGroup.options && optionGroup.options.filter(group => !group.deletedAt);
for (const option of optionsToDelete) {
const { result, message } = await this.productOptionService.delete(ctx, option.id);
if (result === generated_types_1.DeletionResult.NOT_DELETED) {
await this.connection.rollBackTransaction(ctx);
return { result, message };
}
}
const hasOptionsWhichAreInUse = await this.groupOptionsAreInUse(ctx, optionGroup);
if (0 < hasOptionsWhichAreInUse) {
// soft delete
optionGroup.deletedAt = new Date();
await this.connection.getRepository(ctx, product_option_group_entity_1.ProductOptionGroup).save(optionGroup, { reload: false });
}
else {
// hard delete
const product = await this.connection.getRepository(ctx, product_entity_1.Product).findOne({
relationLoadStrategy: 'query',
loadEagerRelations: false,
where: { id: productId },
relations: ['optionGroups'],
});
if (product) {
product.optionGroups = product.optionGroups.filter(og => !(0, utils_1.idsAreEqual)(og.id, id));
await this.connection.getRepository(ctx, product_entity_1.Product).save(product, { reload: false });
}
try {
await this.connection.getRepository(ctx, product_option_group_entity_1.ProductOptionGroup).remove(optionGroup);
}
catch (e) {
vendure_logger_1.Logger.error(e.message, undefined, e.stack);
}
}
await this.eventBus.publish(new product_option_group_event_1.ProductOptionGroupEvent(ctx, deletedOptionGroup, 'deleted', id));
return {
result: generated_types_1.DeletionResult.DELETED,
};
}
async isInUseByOtherProducts(ctx, productOptionGroup, targetProductId) {
return this.connection
.getRepository(ctx, product_entity_1.Product)
.createQueryBuilder('product')
.leftJoin('product.optionGroups', 'optionGroup')
.where('product.deletedAt IS NULL')
.andWhere('optionGroup.id = :id', { id: productOptionGroup.id })
.andWhere('product.id != :productId', { productId: targetProductId })
.getCount();
}
async groupOptionsAreInUse(ctx, productOptionGroup) {
return this.connection
.getRepository(ctx, product_variant_entity_1.ProductVariant)
.createQueryBuilder('variant')
.leftJoin('variant.options', 'option')
.where('option.groupId = :groupId', { groupId: productOptionGroup.id })
.getCount();
}
};
exports.ProductOptionGroupService = ProductOptionGroupService;
exports.ProductOptionGroupService = ProductOptionGroupService = __decorate([
(0, common_1.Injectable)(),
(0, instrument_decorator_1.Instrument)(),
__metadata("design:paramtypes", [transactional_connection_1.TransactionalConnection,
translatable_saver_1.TranslatableSaver,
custom_field_relation_service_1.CustomFieldRelationService,
product_option_service_1.ProductOptionService,
event_bus_1.EventBus,
translator_service_1.TranslatorService])
], ProductOptionGroupService);
//# sourceMappingURL=product-option-group.service.js.map