Skip to content

Commit

Permalink
refactor and more stable
Browse files Browse the repository at this point in the history
  • Loading branch information
bahram1249 committed Mar 1, 2024
1 parent b5b2f47 commit c63353f
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 235 deletions.
17 changes: 15 additions & 2 deletions apps/e-commerce/src/product/product.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,20 @@ export class ProductController {
@ApiOperation({ description: 'show product by given slug' })
@Get('/:slug')
@HttpCode(HttpStatus.OK)
async findById(@Param('slug') slug: string) {
return await this.service.findBySlug(slug);
async findBySlug(
@Query(new ValidationPipe({ transform: true })) filter: GetProductDto,
@Param('slug') slug: string,
) {
return await this.service.findBySlug(filter, slug);
}

@ApiOperation({ description: 'show product by given slug' })
@Get('/id/:id')
@HttpCode(HttpStatus.OK)
async findById(
@Query(new ValidationPipe({ transform: true })) filter: GetProductDto,
@Param('id') id: bigint,
) {
return await this.service.findById(filter, id);
}
}
3 changes: 2 additions & 1 deletion apps/e-commerce/src/product/product.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { ProductService } from './product.service';
import { ProductController } from './product.controller';
import { SequelizeModule } from '@nestjs/sequelize';
import { ECProduct } from '@rahino/database/models/ecommerce-eav/ec-product.entity';
import { ProductQueryBuilderService } from './service';

@Module({
imports: [SequelizeModule.forFeature([ECProduct])],
controllers: [ProductController],
providers: [ProductService],
providers: [ProductService, ProductQueryBuilderService],
})
export class ProductModule {}
272 changes: 40 additions & 232 deletions apps/e-commerce/src/product/product.service.ts
Original file line number Diff line number Diff line change
@@ -1,253 +1,61 @@
import { Injectable } from '@nestjs/common';
import { Injectable, NotFoundException } from '@nestjs/common';
import { GetProductDto } from './dto';
import { InjectModel } from '@nestjs/sequelize';
import { ECProduct } from '@rahino/database/models/ecommerce-eav/ec-product.entity';
import { QueryOptionsBuilder } from '@rahino/query-filter/sequelize-query-builder';
import { Op, Sequelize } from 'sequelize';
import { ECPublishStatus } from '@rahino/database/models/ecommerce-eav/ec-publish-status.entity';
import { ECInventoryStatus } from '@rahino/database/models/ecommerce-eav/ec-inventory-status.entity';
import { ECBrand } from '@rahino/database/models/ecommerce-eav/ec-brand.entity';
import { EAVEntityType } from '@rahino/database/models/eav/eav-entity-type.entity';
import { EAVEntityAttributeValue } from '@rahino/database/models/eav/eav-entity-attribute-value.entity';
import { EAVAttribute } from '@rahino/database/models/eav/eav-attribute.entity';
import { EAVAttributeValue } from '@rahino/database/models/eav/eav-attribute-value';
import { ECInventory } from '@rahino/database/models/ecommerce-eav/ec-inventory.entity';
import { ECVendor } from '@rahino/database/models/ecommerce-eav/ec-vendor.entity';
import { ECColor } from '@rahino/database/models/ecommerce-eav/ec-color.entity';
import { ECGuarantee } from '@rahino/database/models/ecommerce-eav/ec-guarantee.entity';
import { ECGuaranteeMonth } from '@rahino/database/models/ecommerce-eav/ec-guarantee-month.entity';
import { ECProvince } from '@rahino/database/models/ecommerce-eav/ec-province.entity';
import { ECInventoryPrice } from '@rahino/database/models/ecommerce-eav/ec-inventory-price.entity';
import { ECVariationPrice } from '@rahino/database/models/ecommerce-eav/ec-variation-prices';
import { Attachment } from '@rahino/database/models/core/attachment.entity';
import { PublishStatusEnum } from './enum';
import { InventoryStatusEnum } from '../inventory/enum';
import * as _ from 'lodash';
import { ProductQueryBuilderService } from './service';

@Injectable()
export class ProductService {
constructor(
@InjectModel(ECProduct)
private readonly repository: typeof ECProduct,
private readonly productQueryBuilderService: ProductQueryBuilderService,
) {}
async findBySlug(slug: string) {
throw new Error('Method not implemented.');
}
async findAll(filter: GetProductDto) {
let queryBuilder = new QueryOptionsBuilder();
queryBuilder = queryBuilder
.filter(
Sequelize.where(
Sequelize.fn('isnull', Sequelize.col('ECProduct.isDeleted'), 0),
{
[Op.eq]: 0,
},
),
)
.filter({ publishStatusId: PublishStatusEnum.publish });
// .filter({ inventoryStatusId: InventoryStatusEnum.available });

if (filter.entityTypeId) {
queryBuilder = queryBuilder.filter({ entityTypeId: filter.entityTypeId });
}
if (filter.brands.length > 0) {
queryBuilder = queryBuilder.filter({
brandId: {
[Op.in]: filter.brands,
},
});
async findBySlug(filter: GetProductDto, slug: string) {
const { resultQuery, countQuery } =
await this.productQueryBuilderService.findAllAndCountQuery(
filter,
null,
slug,
true,
);

const product = await this.repository.findOne(resultQuery);
if (!product) {
throw new NotFoundException('the item with this given slug not founded!');
}
return {
result: product,
};
}

if (filter.colors.length > 0) {
queryBuilder = queryBuilder.filter(
Sequelize.literal(`EXISTS (
SELECT 1
FROM ECInventories AS ECI
WHERE [ECProduct].id = [ECI].productId
AND [ECI].inventoryStatusId = ${PublishStatusEnum.publish}
AND [ECI].colorId IN(${filter.colors.join(',')}))`),
async findById(filter: GetProductDto, productId: bigint) {
const { resultQuery, countQuery } =
await this.productQueryBuilderService.findAllAndCountQuery(
filter,
productId,
null,
true,
);
}

const productCount = await this.repository.count(queryBuilder.build());
const product = await this.repository.findOne(resultQuery);
if (!product) {
throw new NotFoundException('the item with this given id not founded!');
}
return {
result: product,
};
}

queryBuilder = queryBuilder
.attributes([
'id',
'title',
'sku',
// 'description',
'slug',
'entityTypeId',
'colorBased',
'brandId',
'inventoryStatusId',
'publishStatusId',
'viewCount',
])
.include([
{
attributes: ['id', 'name'],
model: ECPublishStatus,
as: 'publishStatus',
},
{
attributes: ['id', 'name'],
model: ECInventoryStatus,
as: 'inventoryStatus',
},
{
attributes: ['id', 'name', 'slug'],
model: ECBrand,
as: 'brand',
},
{
attributes: ['id', 'name', 'slug'],
model: EAVEntityType,
as: 'entityType',
},
{
attributes: [
'id',
'productId',
'vendorId',
'colorId',
'guaranteeId',
'guaranteeMonthId',
'buyPrice',
'qty',
'onlyProvinceId',
'vendorAddressId',
'weight',
'inventoryStatusId',
//'description',
],
model: ECInventory,
as: 'inventories',
where: {
[Op.and]: [
Sequelize.where(
Sequelize.fn(
'isnull',
Sequelize.col('inventories.isDeleted'),
0,
),
{
[Op.eq]: 0,
},
),
{
inventoryStatusId: InventoryStatusEnum.available,
},
],
},
include: [
{
attributes: ['id', 'name'],
model: ECInventoryStatus,
as: 'inventoryStatus',
required: false,
},
{
attributes: ['id', 'name'],
model: ECVendor,
as: 'vendor',
required: false,
},
{
attributes: ['id', 'name', 'hexCode'],
model: ECColor,
as: 'color',
required: false,
},
{
attributes: ['id', 'name', 'slug'],
model: ECGuarantee,
as: 'guarantee',
required: false,
},
{
attributes: ['id', 'name'],
model: ECGuaranteeMonth,
as: 'guaranteeMonth',
required: false,
},
{
attributes: ['id', 'name'],
model: ECProvince,
as: 'onlyProvince',
required: false,
},
{
attributes: ['price'],
model: ECInventoryPrice,
as: 'firstPrice',
required: false,
include: [
{
attributes: ['id', 'name'],
model: ECVariationPrice,
as: 'variationPrice',
},
],
where: Sequelize.where(
Sequelize.fn(
'isnull',
Sequelize.col('inventories.firstPrice.isDeleted'),
0,
),
{
[Op.eq]: 0,
},
),
},
{
attributes: ['price'],
model: ECInventoryPrice,
as: 'secondaryPrice',
required: false,
include: [
{
attributes: ['id', 'name'],
model: ECVariationPrice,
as: 'variationPrice',
},
],
where: Sequelize.where(
Sequelize.fn(
'isnull',
Sequelize.col('inventories.secondaryPrice.isDeleted'),
0,
),
{
[Op.eq]: 0,
},
),
},
],
required: false,
},
{
attributes: ['id', 'fileName'],
model: Attachment,
as: 'attachments',
required: false,
},
])
.subQuery(true)
.limit(filter.limit)
.offset(filter.offset)
.order({ orderBy: 'inventoryStatusId', sortOrder: 'ASC' })
.order({ orderBy: filter.orderBy, sortOrder: filter.sortOrder })
.order([
{ model: ECInventory, as: 'inventories' },
{ model: ECVendor, as: 'vendor' },
'priorityOrder',
'asc',
]);
async findAll(filter: GetProductDto) {
const { resultQuery, countQuery } =
await this.productQueryBuilderService.findAllAndCountQuery(filter);

return {
result: await this.repository.findAll(queryBuilder.build()),
total: productCount, //count,
result: await this.repository.findAll(resultQuery),
total: await this.repository.count(countQuery), //count,
};
}
}

0 comments on commit c63353f

Please sign in to comment.