1- import { Injectable } from '@nestjs/common' ;
1+ import { Injectable , NotFoundException } from '@nestjs/common' ;
22import { In } from 'typeorm' ;
33import {
4+ ID ,
45 IPagination ,
56 IWarehouseProduct ,
67 IWarehouseProductCreateInput ,
78 IWarehouseProductVariant
89} from '@gauzy/contracts' ;
9- import { TenantAwareCrudService } from './../core/crud' ;
10- import { RequestContext } from './../core/context' ;
10+ import { TenantAwareCrudService } from './../core/crud/tenant-aware-crud.service ' ;
11+ import { RequestContext } from './../core/context/request-context ' ;
1112import { WarehouseProduct , WarehouseProductVariant } from './../core/entities/internal' ;
13+ import { ProductService } from '../product/product.service' ;
1214import { TypeOrmWarehouseProductVariantRepository } from './repository/type-orm-warehouse-product-variant.repository' ;
1315import { MikroOrmWarehouseProductRepository } from './repository/mikro-orm-warehouse-product.repository ' ;
1416import { TypeOrmWarehouseRepository } from './repository/type-orm-warehouse.repository' ;
1517import { TypeOrmWarehouseProductRepository } from './repository/type-orm-warehouse-product.repository ' ;
16- import { TypeOrmProductRepository } from './../product/repository/type-orm-product.repository' ;
1718
1819@Injectable ( )
1920export class WarehouseProductService extends TenantAwareCrudService < WarehouseProduct > {
@@ -22,119 +23,178 @@ export class WarehouseProductService extends TenantAwareCrudService<WarehousePro
2223 readonly mikroOrmWarehouseProductRepository : MikroOrmWarehouseProductRepository ,
2324 private readonly typeOrmWarehouseRepository : TypeOrmWarehouseRepository ,
2425 private readonly typeOrmWarehouseProductVariantRepository : TypeOrmWarehouseProductVariantRepository ,
25- private readonly typeOrmProductRepository : TypeOrmProductRepository
26+ private readonly _productService : ProductService
2627 ) {
2728 super ( typeOrmWarehouseProductRepository , mikroOrmWarehouseProductRepository ) ;
2829 }
2930
3031 /**
32+ * Retrieves all warehouse products for a given warehouse.
3133 *
32- * @param warehouseId
33- * @returns
34+ * @param { ID } warehouseId - The ID of the warehouse to fetch products from.
35+ * @returns { Promise<IWarehouseProduct[]> } - A list of warehouse products.
3436 */
35- async getAllWarehouseProducts ( warehouseId : string ) : Promise < IWarehouseProduct [ ] > {
36- return await this . typeOrmRepository . find ( {
37- where : {
38- warehouseId ,
39- tenantId : RequestContext . currentTenantId ( )
40- } ,
37+ async getAllWarehouseProducts ( warehouseId : ID ) : Promise < IWarehouseProduct [ ] > {
38+ const tenantId = RequestContext . currentTenantId ( ) ;
39+
40+ // Fetch all warehouse products
41+ const warehouseProducts = await this . typeOrmRepository . find ( {
42+ where : { warehouseId , tenantId } ,
4143 relations : {
4244 product : true ,
43- variants : {
44- variant : true
45- }
45+ variants : { variant : true }
4646 }
4747 } ) ;
48+
49+ return warehouseProducts ;
4850 }
4951
52+ /**
53+ * Creates multiple warehouse products in bulk.
54+ *
55+ * @param {IWarehouseProductCreateInput[] } warehouseProductCreateInput - Array of warehouse product input data.
56+ * @param {ID } warehouseId - The ID of the warehouse where products will be added.
57+ * @returns {Promise<IPagination<IWarehouseProduct[]>> } - The created warehouse products with pagination metadata.
58+ *
59+ * @throws {NotFoundException } If warehouse or products are not found.
60+ *
61+ * @description
62+ * 1. Fetches the warehouse and related products based on provided input.
63+ * 2. Creates warehouse products and their variants in bulk.
64+ * 3. Saves and returns the created records.
65+ */
5066 async createWarehouseProductBulk (
5167 warehouseProductCreateInput : IWarehouseProductCreateInput [ ] ,
52- warehouseId : string
53- ) : Promise < IPagination < IWarehouseProduct [ ] > > {
54- let productIds = warehouseProductCreateInput . map ( ( pr ) => pr . productId ) ;
68+ warehouseId : ID
69+ ) : Promise < IPagination < IWarehouseProduct > > {
5570 const tenantId = RequestContext . currentTenantId ( ) ;
56- let warehouse = await this . typeOrmWarehouseRepository . findOneBy ( {
57- id : warehouseId ,
58- tenantId
71+
72+ // Extract product IDs from input
73+ const productIds = warehouseProductCreateInput . map ( ( pr ) => pr . productId ) ;
74+
75+ // Fetch warehouse
76+ const warehouse = await this . typeOrmWarehouseRepository . findOneBy ( { id : warehouseId , tenantId } ) ;
77+ if ( ! warehouse ) {
78+ throw new NotFoundException ( `Warehouse with ID ${ warehouseId } not found` ) ;
79+ }
80+
81+ // Fetch products with variants
82+ const products = await this . _productService . find ( {
83+ where : { id : In ( productIds ) , tenantId } ,
84+ relations : { variants : true }
5985 } ) ;
60- let products = await this . typeOrmProductRepository . find ( {
61- where : {
62- id : In ( productIds ) ,
63- tenantId
64- } ,
65- relations : {
66- variants : true
67- }
86+
87+ if ( ! products . length ) {
88+ throw new NotFoundException ( 'No matching products found' ) ;
89+ }
90+ // Create warehouse products in bulk
91+ const warehouseProducts = products . map ( ( product ) => {
92+ const newWarehouseProduct = new WarehouseProduct ( ) ;
93+ newWarehouseProduct . warehouse = warehouse ;
94+ newWarehouseProduct . product = product ;
95+ newWarehouseProduct . organizationId = warehouse . organizationId ;
96+ newWarehouseProduct . tenantId = tenantId ;
97+
98+ // Create warehouse product variants in bulk
99+ newWarehouseProduct . variants = product . variants . map ( ( variant ) => {
100+ const warehouseVariant = new WarehouseProductVariant ( ) ;
101+ warehouseVariant . variant = variant ;
102+ warehouseVariant . organizationId = warehouse . organizationId ;
103+ warehouseVariant . tenantId = tenantId ;
104+ return warehouseVariant ;
105+ } ) ;
106+
107+ return newWarehouseProduct ;
68108 } ) ;
69- let warehouseProductArr = await Promise . all (
70- products . map ( async ( product ) => {
71- let newWarehouseProduct = new WarehouseProduct ( ) ;
72- newWarehouseProduct . warehouse = warehouse ;
73- newWarehouseProduct . product = product ;
74- newWarehouseProduct . organizationId = warehouse . organizationId ;
75- newWarehouseProduct . tenantId = tenantId ;
76-
77- let warehouseVariants = await Promise . all (
78- product . variants . map ( async ( variant ) => {
79- let warehouseVariant = new WarehouseProductVariant ( ) ;
80- warehouseVariant . variant = variant ;
81-
82- warehouseVariant . organizationId = warehouse . organizationId ;
83- warehouseVariant . tenantId = tenantId ;
84-
85- return this . typeOrmWarehouseProductVariantRepository . save ( warehouseVariant ) ;
86- } )
87- ) ;
88-
89- newWarehouseProduct . variants = warehouseVariants ;
90- return newWarehouseProduct ;
91- } )
92- ) ;
93-
94- let result : any = await this . typeOrmRepository . save ( warehouseProductArr ) ;
95-
96- return { items : result , total : result ? result . length : 0 } ;
109+
110+ // Save warehouse product variants first
111+ await this . typeOrmWarehouseProductVariantRepository . save ( warehouseProducts . flatMap ( ( wp ) => wp . variants ) ) ;
112+
113+ // Save warehouse products
114+ const result = await this . typeOrmRepository . save ( warehouseProducts ) ;
115+
116+ return { items : result , total : result . length } ;
97117 }
98118
99- async updateWarehouseProductQuantity ( warehouseProductId : String , quantity : number ) : Promise < IWarehouseProduct > {
100- let warehouseProduct = await this . typeOrmRepository . findOneBy ( {
101- id : warehouseProductId as any
102- } ) ;
119+ /**
120+ * Updates the quantity of a warehouse product.
121+ *
122+ * @param {ID } warehouseProductId - The ID of the warehouse product to update.
123+ * @param {number } quantity - The new quantity to be set.
124+ * @returns {Promise<IWarehouseProduct> } - The updated warehouse product.
125+ *
126+ * @throws {NotFoundException } If the warehouse product is not found.
127+ *
128+ * @description
129+ * 1. Fetches the warehouse product by its ID.
130+ * 2. Updates the quantity field.
131+ * 3. Saves and returns the updated record.
132+ */
133+ async updateWarehouseProductQuantity ( warehouseProductId : ID , quantity : number ) : Promise < IWarehouseProduct > {
134+ // Fetch warehouse product
135+ const warehouseProduct = await this . typeOrmRepository . findOneBy ( { id : warehouseProductId } ) ;
136+
137+ // Handle missing warehouse product
138+ if ( ! warehouseProduct ) {
139+ throw new NotFoundException ( `Warehouse product with ID ${ warehouseProductId } not found` ) ;
140+ }
141+
142+ // Update and save warehouse product quantity
103143 warehouseProduct . quantity = quantity ;
104- return this . typeOrmRepository . save ( warehouseProduct ) ;
144+ return await this . typeOrmRepository . save ( warehouseProduct ) ;
105145 }
106146
147+ /**
148+ * Updates the quantity of a warehouse product variant and synchronizes the total quantity.
149+ *
150+ * @param {ID } warehouseProductVariantId - The ID of the warehouse product variant to update.
151+ * @param {number } quantity - The new quantity to be set.
152+ * @returns {Promise<IWarehouseProductVariant> } - The updated warehouse product variant.
153+ *
154+ * @throws {NotFoundException } If the warehouse product variant or its associated warehouse product is not found.
155+ *
156+ * @description
157+ * 1. Updates the `quantity` of the specified warehouse product variant.
158+ * 2. Fetches the associated warehouse product and updates its total quantity.
159+ * 3. Saves the updated records to the database.
160+ */
107161 async updateWarehouseProductVariantQuantity (
108- warehouseProductVariantId : string ,
162+ warehouseProductVariantId : ID ,
109163 quantity : number
110164 ) : Promise < IWarehouseProductVariant > {
111- let warehouseProductVariant = await this . typeOrmWarehouseProductVariantRepository . findOne ( {
112- where : {
113- id : warehouseProductVariantId
114- } ,
115- relations : {
116- warehouseProduct : true
117- }
165+ // Fetch the warehouse product variant along with its associated warehouse product
166+ const warehouseProductVariant = await this . typeOrmWarehouseProductVariantRepository . findOne ( {
167+ where : { id : warehouseProductVariantId } ,
168+ relations : { warehouseProduct : true }
118169 } ) ;
119- warehouseProductVariant . quantity = quantity ;
120170
121- let updatedVariant = await this . typeOrmWarehouseProductVariantRepository . save ( warehouseProductVariant ) ;
171+ if ( ! warehouseProductVariant ) {
172+ throw new NotFoundException ( 'Warehouse product variant not found' ) ;
173+ }
122174
123- let warehouseProduct = await this . typeOrmRepository . findOne ( {
124- where : {
125- id : warehouseProductVariant . warehouseProduct . id
126- } ,
127- relations : {
128- variants : true
129- }
175+ // Update variant quantity
176+ warehouseProductVariant . quantity = quantity ;
177+ const updatedVariant = await this . typeOrmWarehouseProductVariantRepository . save ( warehouseProductVariant ) ;
178+
179+ // Fetch the associated warehouse product with all its variants
180+ const warehouseProduct = await this . typeOrmRepository . findOne ( {
181+ where : { id : warehouseProductVariant . warehouseProduct ?. id } ,
182+ relations : { variants : true }
130183 } ) ;
131- let sumQuantity = warehouseProduct . variants . map ( ( v ) => + v . quantity ) . reduce ( ( prev , current ) => prev + current ) ;
132184
133- if ( warehouseProduct . quantity < sumQuantity ) {
134- warehouseProduct . quantity = + warehouseProduct . quantity + sumQuantity - warehouseProduct . quantity ;
185+ if ( ! warehouseProduct ) {
186+ throw new NotFoundException ( 'Warehouse product not found' ) ;
135187 }
136188
189+ // Calculate total quantity of all variants
190+ const sumQuantity = warehouseProduct . variants ?. reduce ( ( sum , v ) => sum + Number ( v . quantity ) , 0 ) || 0 ;
191+
192+ // Synchronize warehouse product quantity with total variant quantities
193+ warehouseProduct . quantity = sumQuantity ;
194+
195+ // Save updated warehouse product
137196 await this . typeOrmRepository . save ( warehouseProduct ) ;
197+
138198 return updatedVariant ;
139199 }
140200}
0 commit comments