@merkaly/api 0.2.5-4 → 0.2.5-6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. package/.bin/deploy.sh +9 -0
  2. package/.bin/package.sh +12 -0
  3. package/.docker/Dockerfile +21 -0
  4. package/.dockerignore +12 -0
  5. package/.github/dependabot.yml +17 -0
  6. package/.github/semantic.yml +5 -0
  7. package/.github/workflows/pull_request.yml +35 -0
  8. package/.prettierrc +5 -0
  9. package/app.ts +11 -0
  10. package/authCertificate.pem +19 -0
  11. package/nest-cli.json +8 -0
  12. package/package.json +66 -78
  13. package/src/abstracts/abstarct.repository.ts +62 -0
  14. package/src/abstracts/abstract.controller.ts +18 -0
  15. package/src/abstracts/abstract.entity.ts +22 -0
  16. package/src/abstracts/abstract.router.ts +7 -0
  17. package/src/abstracts/abstract.validator.ts +61 -0
  18. package/src/app.config.ts +59 -0
  19. package/src/app.console.ts +24 -0
  20. package/src/app.guard.ts +39 -0
  21. package/src/app.module.ts +54 -0
  22. package/src/app.strategy.ts +21 -0
  23. package/src/commands/seed.command.ts +263 -0
  24. package/src/decorators/public.decorator.ts +5 -0
  25. package/src/decorators/user.decorator.ts +30 -0
  26. package/src/exceptions/missing-identity.exception.ts +11 -0
  27. package/src/interceptors/mongoose.interceptor.ts +63 -0
  28. package/src/main.ts +27 -0
  29. package/src/middlewares/router.middleware.ts +14 -0
  30. package/src/modules/asset/asset.module.ts +19 -0
  31. package/src/modules/asset/files/file.controller.ts +22 -0
  32. package/src/modules/asset/files/file.entity.ts +24 -0
  33. package/src/modules/asset/files/file.module.ts +21 -0
  34. package/src/modules/asset/files/file.repository.ts +44 -0
  35. package/src/modules/asset/files/file.schema.ts +8 -0
  36. package/src/modules/asset/files/file.service.ts +4 -0
  37. package/src/modules/auth/auth.controller.ts +57 -0
  38. package/src/modules/auth/auth.module.ts +20 -0
  39. package/src/modules/auth/organizations/organization.controller.ts +20 -0
  40. package/src/modules/auth/organizations/organization.entity.ts +22 -0
  41. package/src/modules/auth/organizations/organization.module.ts +21 -0
  42. package/src/modules/auth/organizations/organization.repository.ts +16 -0
  43. package/src/modules/auth/organizations/organization.schema.ts +8 -0
  44. package/src/modules/auth/users/user.controller.ts +23 -0
  45. package/src/modules/auth/users/user.entity.ts +25 -0
  46. package/src/modules/auth/users/user.module.ts +20 -0
  47. package/src/modules/auth/users/user.repository.ts +79 -0
  48. package/src/modules/auth/users/user.schema.ts +8 -0
  49. package/src/modules/auth/users/user.validator.ts +32 -0
  50. package/src/modules/command.module.ts +15 -0
  51. package/src/modules/global.module.ts +46 -0
  52. package/src/modules/inventory/brands/brand.controller.ts +44 -0
  53. package/src/modules/inventory/brands/brand.entity.ts +20 -0
  54. package/src/modules/inventory/brands/brand.module.ts +20 -0
  55. package/src/modules/inventory/brands/brand.repository.ts +40 -0
  56. package/src/modules/inventory/brands/brand.schema.ts +8 -0
  57. package/src/modules/inventory/brands/brand.validator.ts +31 -0
  58. package/src/modules/inventory/categories/category.controller.ts +42 -0
  59. package/src/modules/inventory/categories/category.entity.ts +15 -0
  60. package/src/modules/inventory/categories/category.module.ts +19 -0
  61. package/src/modules/inventory/categories/category.repository.ts +34 -0
  62. package/src/modules/inventory/categories/category.schema.ts +8 -0
  63. package/src/modules/inventory/categories/category.validator.ts +20 -0
  64. package/src/modules/inventory/complements/complement.controller.ts +41 -0
  65. package/src/modules/inventory/complements/complement.entity.ts +15 -0
  66. package/src/modules/inventory/complements/complement.module.ts +19 -0
  67. package/src/modules/inventory/complements/complement.repository.ts +37 -0
  68. package/src/modules/inventory/complements/complement.schema.ts +8 -0
  69. package/src/modules/inventory/complements/complement.validator.ts +28 -0
  70. package/src/modules/inventory/inventory.module.ts +23 -0
  71. package/src/modules/inventory/products/documents/attribute.document.ts +14 -0
  72. package/src/modules/inventory/products/documents/dimension.document.ts +16 -0
  73. package/src/modules/inventory/products/product.controller.ts +62 -0
  74. package/src/modules/inventory/products/product.entity.ts +46 -0
  75. package/src/modules/inventory/products/product.module.ts +19 -0
  76. package/src/modules/inventory/products/product.repository.ts +64 -0
  77. package/src/modules/inventory/products/product.schema.ts +19 -0
  78. package/src/modules/inventory/products/product.validator.ts +132 -0
  79. package/src/modules/inventory/products/validators/attributes.validator.ts +15 -0
  80. package/src/modules/inventory/products/validators/dimension.validator.ts +19 -0
  81. package/src/modules/sale/customers/customer.controller.ts +41 -0
  82. package/src/modules/sale/customers/customer.entity.ts +19 -0
  83. package/src/modules/sale/customers/customer.module.ts +18 -0
  84. package/src/modules/sale/customers/customer.repository.ts +30 -0
  85. package/src/modules/sale/customers/customer.schema.ts +8 -0
  86. package/src/modules/sale/customers/customer.validator.ts +43 -0
  87. package/src/modules/sale/orders/documents/address.document.ts +22 -0
  88. package/src/modules/sale/orders/documents/status.document.ts +17 -0
  89. package/src/modules/sale/orders/entities/item.entity.ts +24 -0
  90. package/src/modules/sale/orders/enums/order.status.ts +6 -0
  91. package/src/modules/sale/orders/order.controller.ts +65 -0
  92. package/src/modules/sale/orders/order.entity.ts +46 -0
  93. package/src/modules/sale/orders/order.module.ts +22 -0
  94. package/src/modules/sale/orders/order.repository.ts +122 -0
  95. package/src/modules/sale/orders/order.schema.ts +36 -0
  96. package/src/modules/sale/orders/order.validator.ts +44 -0
  97. package/src/modules/sale/orders/validators/address.validator.ts +50 -0
  98. package/src/modules/sale/orders/validators/billing.validator.ts +11 -0
  99. package/src/modules/sale/orders/validators/item.validator.ts +14 -0
  100. package/src/modules/sale/orders/validators/payment.validator.ts +44 -0
  101. package/src/modules/sale/orders/validators/shipping.validator.ts +14 -0
  102. package/src/modules/sale/payments/entities/status.entity.ts +17 -0
  103. package/src/modules/sale/payments/enums/billing.type.ts +6 -0
  104. package/src/modules/sale/payments/enums/payment.status.ts +7 -0
  105. package/src/modules/sale/payments/enums/shipping.type.ts +4 -0
  106. package/src/modules/sale/payments/payment.controller.ts +45 -0
  107. package/src/modules/sale/payments/payment.entity.ts +25 -0
  108. package/src/modules/sale/payments/payment.module.ts +20 -0
  109. package/src/modules/sale/payments/payment.repository.ts +57 -0
  110. package/src/modules/sale/payments/payment.schema.ts +14 -0
  111. package/src/modules/sale/payments/payment.validator.ts +32 -0
  112. package/src/modules/sale/sale.module.ts +20 -0
  113. package/src/services/auth0.service.ts +49 -0
  114. package/src/services/mongo.service.ts +52 -0
  115. package/test/auth/auth.spec.ts +20 -0
  116. package/test/main.ts +12 -0
  117. package/tsconfig.build.json +4 -0
  118. package/tsconfig.json +21 -0
  119. package/tsconfig.package.json +22 -0
  120. package/.output/abstract/abstract.entity.d.ts +0 -9
  121. package/.output/abstract/abstract.exception.d.ts +0 -11
  122. package/.output/abstract/abstract.exception.js +0 -53
  123. package/.output/abstract/abstract.fixture.d.ts +0 -4
  124. package/.output/abstract/abstract.fixture.js +0 -11
  125. package/.output/abstract/abstract.validator.d.ts +0 -20
  126. package/.output/abstract/abstract.validator.js +0 -105
  127. package/.output/exceptions/missing-identity.exception.d.ts +0 -5
  128. package/.output/exceptions/missing-identity.exception.js +0 -30
  129. package/.output/exceptions/store-not-implemented.exception.d.ts +0 -5
  130. package/.output/exceptions/store-not-implemented.exception.js +0 -31
  131. package/.output/exceptions/store-not-recognized.exception.d.ts +0 -5
  132. package/.output/exceptions/store-not-recognized.exception.js +0 -30
  133. package/.output/modules/asset/files/file.entity.d.ts +0 -10
  134. package/.output/modules/auth/auth.types.d.ts +0 -3
  135. package/.output/modules/auth/auth.types.js +0 -7
  136. package/.output/modules/auth/users/user.validator.d.ts +0 -10
  137. package/.output/modules/auth/users/user.validator.js +0 -50
  138. package/.output/modules/config/organization/organization.entity.d.ts +0 -21
  139. package/.output/modules/config/organization/organization.types.d.ts +0 -23
  140. package/.output/modules/config/organization/organization.types.js +0 -107
  141. package/.output/modules/config/organization/organization.validator.d.ts +0 -18
  142. package/.output/modules/config/organization/organization.validator.js +0 -88
  143. package/.output/modules/insight/validators/order.validator.d.ts +0 -4
  144. package/.output/modules/insight/validators/order.validator.js +0 -27
  145. package/.output/modules/inventory/brands/brand.entity.d.ts +0 -9
  146. package/.output/modules/inventory/brands/brand.exception.d.ts +0 -5
  147. package/.output/modules/inventory/brands/brand.exception.js +0 -40
  148. package/.output/modules/inventory/brands/brand.validator.d.ts +0 -11
  149. package/.output/modules/inventory/brands/brand.validator.js +0 -75
  150. package/.output/modules/inventory/categories/category.entity.d.ts +0 -12
  151. package/.output/modules/inventory/categories/category.exception.d.ts +0 -5
  152. package/.output/modules/inventory/categories/category.exception.js +0 -40
  153. package/.output/modules/inventory/categories/category.fixture.d.ts +0 -5
  154. package/.output/modules/inventory/categories/category.fixture.js +0 -38
  155. package/.output/modules/inventory/categories/category.validator.d.ts +0 -13
  156. package/.output/modules/inventory/categories/category.validator.js +0 -88
  157. package/.output/modules/inventory/products/entities/code.entity.d.ts +0 -5
  158. package/.output/modules/inventory/products/entities/dimension.entity.d.ts +0 -6
  159. package/.output/modules/inventory/products/entities/seo.entity.d.ts +0 -5
  160. package/.output/modules/inventory/products/entities/variant.entity.d.ts +0 -10
  161. package/.output/modules/inventory/products/product.entity.d.ts +0 -26
  162. package/.output/modules/inventory/products/product.exception.d.ts +0 -5
  163. package/.output/modules/inventory/products/product.exception.js +0 -40
  164. package/.output/modules/inventory/products/product.fixture.d.ts +0 -5
  165. package/.output/modules/inventory/products/product.fixture.js +0 -39
  166. package/.output/modules/inventory/products/product.validator.d.ts +0 -38
  167. package/.output/modules/inventory/products/product.validator.js +0 -235
  168. package/.output/modules/inventory/products/schemas/variant.schema.d.ts +0 -27
  169. package/.output/modules/inventory/products/schemas/variant.schema.js +0 -6
  170. package/.output/modules/inventory/products/validators/code.validator.d.ts +0 -5
  171. package/.output/modules/inventory/products/validators/code.validator.js +0 -37
  172. package/.output/modules/inventory/products/validators/dimension.validator.d.ts +0 -6
  173. package/.output/modules/inventory/products/validators/dimension.validator.js +0 -43
  174. package/.output/modules/inventory/products/validators/seo.validator.d.ts +0 -5
  175. package/.output/modules/inventory/products/validators/seo.validator.js +0 -34
  176. package/.output/modules/inventory/products/validators/variant.validator.d.ts +0 -9
  177. package/.output/modules/inventory/products/validators/variant.validator.js +0 -39
  178. package/.output/modules/inventory/properties/property.entity.d.ts +0 -8
  179. package/.output/modules/inventory/properties/property.exception.d.ts +0 -5
  180. package/.output/modules/inventory/properties/property.exception.js +0 -40
  181. package/.output/modules/inventory/properties/property.types.d.ts +0 -6
  182. package/.output/modules/inventory/properties/property.types.js +0 -10
  183. package/.output/modules/inventory/properties/property.validator.d.ts +0 -12
  184. package/.output/modules/inventory/properties/property.validator.js +0 -79
  185. package/.output/modules/layout/pages/page.entity.d.ts +0 -8
  186. package/.output/modules/layout/pages/page.fixture.d.ts +0 -5
  187. package/.output/modules/layout/pages/page.fixture.js +0 -36
  188. package/.output/modules/layout/pages/page.types.d.ts +0 -20
  189. package/.output/modules/layout/pages/page.types.js +0 -2
  190. package/.output/modules/layout/pages/page.validator.d.ts +0 -8
  191. package/.output/modules/layout/pages/page.validator.js +0 -61
  192. package/.output/modules/sale/customers/customer.entity.d.ts +0 -12
  193. package/.output/modules/sale/customers/customer.exception.d.ts +0 -5
  194. package/.output/modules/sale/customers/customer.exception.js +0 -40
  195. package/.output/modules/sale/customers/customer.validator.d.ts +0 -18
  196. package/.output/modules/sale/customers/customer.validator.js +0 -107
  197. package/.output/modules/sale/orders/billing/billing.entity.d.ts +0 -10
  198. package/.output/modules/sale/orders/billing/billing.types.d.ts +0 -9
  199. package/.output/modules/sale/orders/billing/billing.types.js +0 -14
  200. package/.output/modules/sale/orders/billing/billing.validator.d.ts +0 -9
  201. package/.output/modules/sale/orders/billing/billing.validator.js +0 -42
  202. package/.output/modules/sale/orders/billing/entities/address.entity.d.ts +0 -10
  203. package/.output/modules/sale/orders/billing/entities/customer.entity.d.ts +0 -5
  204. package/.output/modules/sale/orders/billing/entities/status.entity.d.ts +0 -6
  205. package/.output/modules/sale/orders/billing/validators/address.validator.d.ts +0 -10
  206. package/.output/modules/sale/orders/billing/validators/address.validator.js +0 -56
  207. package/.output/modules/sale/orders/billing/validators/customer.validator.d.ts +0 -5
  208. package/.output/modules/sale/orders/billing/validators/customer.validator.js +0 -36
  209. package/.output/modules/sale/orders/customer/customer.entity.d.ts +0 -5
  210. package/.output/modules/sale/orders/customer/customer.validator.d.ts +0 -5
  211. package/.output/modules/sale/orders/customer/customer.validator.js +0 -36
  212. package/.output/modules/sale/orders/item/item.entity.d.ts +0 -9
  213. package/.output/modules/sale/orders/item/item.schema.d.ts +0 -27
  214. package/.output/modules/sale/orders/item/item.schema.js +0 -9
  215. package/.output/modules/sale/orders/item/item.validator.d.ts +0 -4
  216. package/.output/modules/sale/orders/item/item.validator.js +0 -29
  217. package/.output/modules/sale/orders/order.entity.d.ts +0 -21
  218. package/.output/modules/sale/orders/order.exception.d.ts +0 -13
  219. package/.output/modules/sale/orders/order.exception.js +0 -46
  220. package/.output/modules/sale/orders/order.validator.d.ts +0 -28
  221. package/.output/modules/sale/orders/order.validator.js +0 -140
  222. package/.output/modules/sale/orders/shipping/entities/address.entity.d.ts +0 -10
  223. package/.output/modules/sale/orders/shipping/entities/customer.entity.d.ts +0 -5
  224. package/.output/modules/sale/orders/shipping/entities/status.entity.d.ts +0 -6
  225. package/.output/modules/sale/orders/shipping/shipping.entity.d.ts +0 -11
  226. package/.output/modules/sale/orders/shipping/shipping.types.d.ts +0 -11
  227. package/.output/modules/sale/orders/shipping/shipping.types.js +0 -16
  228. package/.output/modules/sale/orders/shipping/shipping.validator.d.ts +0 -10
  229. package/.output/modules/sale/orders/shipping/shipping.validator.js +0 -48
  230. package/.output/modules/sale/orders/shipping/validators/address.validator.d.ts +0 -10
  231. package/.output/modules/sale/orders/shipping/validators/address.validator.js +0 -56
  232. package/.output/modules/sale/orders/shipping/validators/customer.validator.d.ts +0 -5
  233. package/.output/modules/sale/orders/shipping/validators/customer.validator.js +0 -36
  234. package/.output/modules/sale/orders/status/status.entity.d.ts +0 -6
  235. package/.output/modules/sale/orders/status/status.validator.d.ts +0 -8
  236. package/.output/modules/sale/orders/status/status.validator.js +0 -12
  237. package/.output/services/logger.service.d.ts +0 -11
  238. package/.output/services/logger.service.js +0 -50
  239. package/.output/types.d.ts +0 -18
  240. package/.output/types.js +0 -2
  241. package/LICENSE +0 -674
@@ -0,0 +1,41 @@
1
+ import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Inject, Param, Patch, Post, Query } from '@nestjs/common';
2
+ import { ApiTags } from '@nestjs/swagger';
3
+ import { AbstractController } from '../../../abstracts/abstract.controller';
4
+ import { FindValidator, IdMongoValidator, ReadValidator } from '../../../abstracts/abstract.validator';
5
+ import { CustomerEntity } from './customer.entity';
6
+ import { CustomerRepository } from './customer.repository';
7
+ import { CreateCustomerValidator, UpdateCustomerValidator } from './customer.validator';
8
+
9
+ @Controller()
10
+ @ApiTags('sale')
11
+ export class CustomerController extends AbstractController {
12
+ @Inject()
13
+ protected readonly $repository: CustomerRepository;
14
+
15
+ @Get('/')
16
+ public async find(@Query() validator: FindValidator<CustomerEntity>) {
17
+ return this.$repository.find(validator);
18
+ }
19
+
20
+ @Get('/:id')
21
+ public read(@Param() { id }: IdMongoValidator, @Query() validator?: ReadValidator) {
22
+ return this.$repository.read(id, validator);
23
+ }
24
+
25
+ @Post('/')
26
+ @HttpCode(HttpStatus.CREATED)
27
+ public async create(@Body() validator: CreateCustomerValidator) {
28
+ return this.$repository.create(validator);
29
+ }
30
+
31
+ @Patch('/:id')
32
+ public async update(@Param() { id }: IdMongoValidator, @Body() validator: UpdateCustomerValidator) {
33
+ return this.$repository.update(id, validator);
34
+ }
35
+
36
+ @Delete('/:id')
37
+ @HttpCode(HttpStatus.NO_CONTENT)
38
+ public delete(@Param() { id }: IdMongoValidator) {
39
+ return this.$repository.delete(id);
40
+ }
41
+ }
@@ -0,0 +1,19 @@
1
+ import { Prop, Schema as Collection } from '@nestjs/mongoose';
2
+ import { Schema } from 'mongoose';
3
+ import { $collection, AbstractEntity } from '../../../abstracts/abstract.entity';
4
+ import { AddressValidator } from '../orders/validators/address.validator';
5
+
6
+ @Collection($collection)
7
+ export class CustomerEntity extends AbstractEntity {
8
+ @Prop({ type: Schema.Types.String, required: true })
9
+ public name: string;
10
+
11
+ @Prop({ type: Schema.Types.String, unique: true, required: true })
12
+ public email: string;
13
+
14
+ @Prop({ type: Schema.Types.String, default: null })
15
+ public phone: string;
16
+
17
+ @Prop({ type: Schema.Types.Array, default: [] })
18
+ public addresses: AddressValidator[] = [];
19
+ }
@@ -0,0 +1,18 @@
1
+ import { Module, ModuleMetadata } from '@nestjs/common';
2
+ import { AbstractRouter } from '../../../abstracts/abstract.router';
3
+ import { CustomerController } from './customer.controller';
4
+ import { CustomerRepository } from './customer.repository';
5
+
6
+ export const metadata: ModuleMetadata = {
7
+ controllers: [CustomerController],
8
+ exports: [CustomerRepository],
9
+ imports: [],
10
+ providers: [CustomerRepository],
11
+ };
12
+
13
+ @Module(metadata)
14
+ export class CustomerModule extends AbstractRouter {
15
+ public static readonly path = '/customers';
16
+
17
+ public static readonly module = CustomerModule;
18
+ }
@@ -0,0 +1,30 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { InjectModel } from '@nestjs/mongoose';
3
+ import { Model } from 'mongoose';
4
+ import { AbstractRepository } from '../../../abstracts/abstarct.repository';
5
+ import { CustomerEntity } from './customer.entity';
6
+ import { CustomerSchema } from './customer.schema';
7
+ import { CreateCustomerValidator, UpdateCustomerValidator } from './customer.validator';
8
+
9
+ @Injectable()
10
+ export class CustomerRepository extends AbstractRepository<CustomerEntity> {
11
+ @InjectModel(CustomerSchema.name)
12
+ public readonly $model: Model<CustomerEntity>;
13
+
14
+ public async create(validator: CreateCustomerValidator) {
15
+ const customer = new this.$model();
16
+
17
+ customer.name = validator.name;
18
+ customer.email = validator.email;
19
+ customer.phone = validator.phone;
20
+ customer.addresses = validator.addresses;
21
+
22
+ await customer.save();
23
+
24
+ return customer;
25
+ }
26
+
27
+ public async update(id: string, validator: UpdateCustomerValidator): Promise<CustomerEntity> {
28
+ return super.read(id);
29
+ }
30
+ }
@@ -0,0 +1,8 @@
1
+ import { SchemaFactory } from '@nestjs/mongoose';
2
+ import { CustomerEntity } from './customer.entity';
3
+
4
+ export namespace CustomerSchema {
5
+ export const name = 'sale_customers';
6
+
7
+ export const schema = SchemaFactory.createForClass(CustomerEntity);
8
+ }
@@ -0,0 +1,43 @@
1
+ import { Transform, Type } from 'class-transformer';
2
+ import { IsArray, IsEmail, IsOptional, IsPhoneNumber, IsString, ValidateNested } from 'class-validator';
3
+ import { AbstractValidator } from '../../../abstracts/abstract.validator';
4
+ import { AddressValidator } from '../orders/validators/address.validator';
5
+
6
+ export class CreateCustomerValidator extends AbstractValidator {
7
+ @IsString()
8
+ public name: string;
9
+
10
+ @IsEmail()
11
+ @Transform(({ value }) => String(value).toLowerCase())
12
+ public email: string;
13
+
14
+ @IsString()
15
+ @IsOptional()
16
+ public phone?: string;
17
+
18
+ @IsArray()
19
+ @Type(() => AddressValidator)
20
+ @ValidateNested()
21
+ public addresses?: AddressValidator[] = [];
22
+ }
23
+
24
+ export class UpdateCustomerValidator {
25
+ @IsString()
26
+ @IsOptional()
27
+ public name?: string;
28
+
29
+ @IsEmail()
30
+ @Transform(({ value }) => String(value).toLowerCase())
31
+ @IsOptional()
32
+ public email?: string;
33
+
34
+ @IsPhoneNumber()
35
+ @IsOptional()
36
+ public phone?: string;
37
+
38
+ @IsArray()
39
+ @Type(() => AddressValidator)
40
+ @ValidateNested()
41
+ @IsOptional()
42
+ public addresses?: AddressValidator[];
43
+ }
@@ -0,0 +1,22 @@
1
+ import { Prop } from '@nestjs/mongoose';
2
+ import { Schema } from 'mongoose';
3
+
4
+ export class AddressDocument {
5
+ @Prop({ required: true, type: Schema.Types.String })
6
+ public line1: string;
7
+
8
+ @Prop({ type: Schema.Types.String })
9
+ public line2: string;
10
+
11
+ @Prop({ required: true, type: Schema.Types.String })
12
+ public state: string;
13
+
14
+ @Prop({ required: true, type: Schema.Types.String })
15
+ public city: string;
16
+
17
+ @Prop({ type: Schema.Types.String })
18
+ public country: string;
19
+
20
+ @Prop({ required: true, type: Schema.Types.String })
21
+ public code: string;
22
+ }
@@ -0,0 +1,17 @@
1
+ import { Prop } from '@nestjs/mongoose';
2
+ import { Schema } from 'mongoose';
3
+ import { MaybeEntity } from '../../../../abstracts/abstract.entity';
4
+ import { UserEntity } from '../../../auth/users/user.entity';
5
+ import { UserSchema } from '../../../auth/users/user.schema';
6
+ import { OrderStatus } from '../enums/order.status';
7
+
8
+ export class StatusDocument {
9
+ @Prop({ default: OrderStatus.CREATED, enum: OrderStatus, required: true, type: Schema.Types.String })
10
+ public name: OrderStatus;
11
+
12
+ @Prop({ ref: UserSchema.name, required: true, type: Schema.Types.ObjectId })
13
+ public user: MaybeEntity<UserEntity>;
14
+
15
+ @Prop({ default: () => new Date(), type: Schema.Types.Date })
16
+ public date = new Date();
17
+ }
@@ -0,0 +1,24 @@
1
+ import { Prop, SchemaFactory } from '@nestjs/mongoose';
2
+ import { Schema as Collection } from '@nestjs/mongoose/dist/decorators/schema.decorator';
3
+ import { Schema } from 'mongoose';
4
+ import type { MaybeEntity } from '../../../../abstracts/abstract.entity';
5
+ import { $collection } from '../../../../abstracts/abstract.entity';
6
+ import { ProductEntity } from '../../../inventory/products/product.entity';
7
+ import { ProductSchema } from '../../../inventory/products/product.schema';
8
+
9
+ @Collection($collection)
10
+ export class ItemEntity {
11
+ @Prop({ ref: ProductSchema.name, type: Schema.Types.ObjectId })
12
+ public product: MaybeEntity<ProductEntity>;
13
+
14
+ @Prop({ default: 0, type: Schema.Types.Number })
15
+ public price?: number;
16
+
17
+ @Prop({ type: Schema.Types.Number })
18
+ public quantity: number;
19
+
20
+ @Prop({ type: Schema.Types.String })
21
+ public description: string;
22
+ }
23
+
24
+ export const ItemSchema = SchemaFactory.createForClass(ItemEntity);
@@ -0,0 +1,6 @@
1
+ export enum OrderStatus {
2
+ CREATED = 'CREATED',
3
+ ACCEPTED = 'ACCEPTED',
4
+ COMPLETED = 'COMPLETED',
5
+ CANCELED = 'CANCELED',
6
+ }
@@ -0,0 +1,65 @@
1
+ import { Body, Controller, Delete, Get, Inject, Param, Patch, Post, Query } from '@nestjs/common';
2
+ import { ApiTags } from '@nestjs/swagger';
3
+ import { AbstractController } from '../../../abstracts/abstract.controller';
4
+ import { FindValidator, IdMongoValidator, ReadValidator } from '../../../abstracts/abstract.validator';
5
+ import { GetUser } from '../../../decorators/user.decorator';
6
+ import { UserRepository } from '../../auth/users/user.repository';
7
+ import { OrderEntity } from './order.entity';
8
+ import { OrderRepository } from './order.repository';
9
+ import { CreateOrderValidator, UpdateOrderStatusValidator, UpdateOrderValidator } from './order.validator';
10
+
11
+ @Controller('/')
12
+ @ApiTags('sales')
13
+ export class OrderController extends AbstractController {
14
+ @Inject()
15
+ protected readonly $repository: OrderRepository;
16
+
17
+ @Inject()
18
+ protected readonly $userRepository: UserRepository;
19
+
20
+ @Get('/')
21
+ public find(@Query() validator: FindValidator<OrderEntity>) {
22
+ return this.$repository.find(validator);
23
+ }
24
+
25
+ @Post('/')
26
+ public async create(@Body() validator: CreateOrderValidator, @GetUser('sub') sub: string) {
27
+ // const user = await this.$userRepository.readByAuth0(sub)
28
+ const user = undefined;
29
+
30
+ return this.$repository.create(validator, user);
31
+ }
32
+
33
+ @Get('/me')
34
+ public async byCurrentUser(@Query() validator: FindValidator<OrderEntity>, @GetUser('sub') sub: string) {
35
+ const user = await this.$userRepository.readByAuth0(sub);
36
+
37
+ return this.$repository.findByUser(validator, user);
38
+ }
39
+
40
+ @Get('/:id')
41
+ public read(@Param() { id }: IdMongoValidator, @Query() validator?: ReadValidator) {
42
+ return this.$repository.read(id, validator);
43
+ }
44
+
45
+ @Patch('/:id')
46
+ public update(@Param('id') id: string, @Body() validator: UpdateOrderValidator) {
47
+ return this.$repository.update(id, validator);
48
+ }
49
+
50
+ @Delete('/:id')
51
+ public delete(@Param() { id }: IdMongoValidator) {
52
+ return this.$repository.delete(id);
53
+ }
54
+
55
+ @Patch('/:id/status/:type')
56
+ public async updateStatus(
57
+ @Param() { id, type }: UpdateOrderStatusValidator,
58
+ @Body() validator: UpdateOrderValidator,
59
+ @GetUser('sub') sub: string,
60
+ ) {
61
+ const user = await this.$userRepository.readByAuth0(sub);
62
+
63
+ return this.$repository.updateStatus(id, type, user);
64
+ }
65
+ }
@@ -0,0 +1,46 @@
1
+ import { Prop, Schema as Collection } from '@nestjs/mongoose';
2
+ import { Schema } from 'mongoose';
3
+ import type { MaybeEntity } from '../../../abstracts/abstract.entity';
4
+ import { $collection, AbstractEntity } from '../../../abstracts/abstract.entity';
5
+ import { UserEntity } from '../../auth/users/user.entity';
6
+ import { UserSchema } from '../../auth/users/user.schema';
7
+ import { CustomerEntity } from '../customers/customer.entity';
8
+ import { CustomerSchema } from '../customers/customer.schema';
9
+ import { PaymentEntity } from '../payments/payment.entity';
10
+ import { PaymentSchema } from '../payments/payment.schema';
11
+ import { AddressDocument } from './documents/address.document';
12
+ import { StatusDocument } from './documents/status.document';
13
+ import { ItemEntity, ItemSchema } from './entities/item.entity';
14
+
15
+ @Collection($collection)
16
+ export class OrderEntity extends AbstractEntity {
17
+ @Prop({ default: () => 1, type: Schema.Types.Number })
18
+ public number = 1;
19
+
20
+ @Prop({ default: () => [], type: [ItemSchema] })
21
+ public items: ItemEntity[] = [];
22
+
23
+ @Prop({ default: () => [], type: Schema.Types.Array })
24
+ public status: StatusDocument[] = [];
25
+
26
+ @Prop({ ref: PaymentSchema.name, required: true, type: Schema.Types.ObjectId })
27
+ public payment: MaybeEntity<PaymentEntity>;
28
+
29
+ @Prop({ ref: CustomerSchema.name, required: true, type: Schema.Types.ObjectId })
30
+ public customer: MaybeEntity<CustomerEntity>;
31
+
32
+ @Prop({ ref: UserSchema.name, required: true, type: Schema.Types.ObjectId })
33
+ public user: MaybeEntity<UserEntity>;
34
+
35
+ @Prop({ default: () => new AddressDocument(), required: true, type: Schema.Types.Mixed })
36
+ public address = new AddressDocument();
37
+
38
+ @Prop({ type: Schema.Types.String })
39
+ public description: string;
40
+
41
+ public readonly total: number;
42
+
43
+ public readonly fullNumber: string;
44
+
45
+ public readonly lastStatus: StatusDocument;
46
+ }
@@ -0,0 +1,22 @@
1
+ import { Module, ModuleMetadata } from '@nestjs/common';
2
+ import { UserRepository } from '../../auth/users/user.repository';
3
+ import { ProductRepository } from '../../inventory/products/product.repository';
4
+ import { PaymentRepository } from '../payments/payment.repository';
5
+ import { OrderController } from './order.controller';
6
+ import { OrderRepository } from './order.repository';
7
+
8
+ export const metadata: ModuleMetadata = {
9
+ controllers: [OrderController],
10
+ exports: [OrderRepository],
11
+ imports: [],
12
+ providers: [OrderRepository, ProductRepository, PaymentRepository, UserRepository],
13
+ };
14
+
15
+ @Module(metadata)
16
+ export class OrderModule {
17
+ public static readonly path = '/orders';
18
+
19
+ public static readonly module = OrderModule;
20
+
21
+ public static readonly children = metadata.imports;
22
+ }
@@ -0,0 +1,122 @@
1
+ import { Inject, Injectable, Logger, OnModuleInit } from '@nestjs/common';
2
+ import { InjectModel } from '@nestjs/mongoose';
3
+ import { Model } from 'mongoose';
4
+ import { AbstractRepository } from '../../../abstracts/abstarct.repository';
5
+ import { FindValidator } from '../../../abstracts/abstract.validator';
6
+ import { UserEntity } from '../../auth/users/user.entity';
7
+ import { UserRepository } from '../../auth/users/user.repository';
8
+ import { ProductRepository } from '../../inventory/products/product.repository';
9
+ import { PaymentRepository } from '../payments/payment.repository';
10
+ import { CreatePaymentValidator } from '../payments/payment.validator';
11
+ import { StatusDocument } from './documents/status.document';
12
+ import { ItemEntity } from './entities/item.entity';
13
+ import { OrderStatus } from './enums/order.status';
14
+ import { OrderEntity } from './order.entity';
15
+ import { OrderSchema } from './order.schema';
16
+ import { CreateOrderValidator, UpdateOrderValidator } from './order.validator';
17
+
18
+ export let autoIncrement = 1;
19
+
20
+ @Injectable()
21
+ export class OrderRepository extends AbstractRepository<OrderEntity> implements OnModuleInit {
22
+ @InjectModel(OrderSchema.name)
23
+ protected readonly $model: Model<OrderEntity>;
24
+
25
+ @Inject()
26
+ protected readonly $products: ProductRepository;
27
+
28
+ @Inject()
29
+ protected readonly $payments: PaymentRepository;
30
+
31
+ @Inject()
32
+ protected readonly $users: UserRepository;
33
+
34
+ public async onModuleInit() {
35
+ const lastOne = await this.$model.findOne<OrderEntity>(undefined, undefined, {
36
+ sort: { number: 'descending' },
37
+ });
38
+
39
+ if (!lastOne) {
40
+ return;
41
+ }
42
+
43
+ return (autoIncrement = lastOne.number);
44
+ }
45
+
46
+ public findByUser(validator: FindValidator<OrderEntity>, user: UserEntity) {
47
+ validator.filters.user = user._id;
48
+
49
+ return super.find(validator);
50
+ }
51
+
52
+ public async create(validator: CreateOrderValidator, user?: UserEntity) {
53
+ const order = new this.$model();
54
+
55
+ order.number = ++autoIncrement;
56
+ order.user = user;
57
+ order.address = validator.shipping.address;
58
+ order.description = validator.description;
59
+
60
+ const status = new StatusDocument();
61
+ status.date = new Date();
62
+ status.name = OrderStatus.CREATED;
63
+ status.user = order.user._id as any;
64
+
65
+ order.status.push(status);
66
+
67
+ for await (const itemValidator of validator.items) {
68
+ const item = new ItemEntity();
69
+
70
+ try {
71
+ const product = await this.$products.read(itemValidator.product);
72
+
73
+ item.description = itemValidator.description;
74
+ item.quantity = itemValidator.quantity;
75
+ item.product = product._id as any;
76
+ item.price = product.price;
77
+ } catch (reason: unknown) {
78
+ Logger.warn(`When creating order occurs: [${reason}] `);
79
+ continue;
80
+ }
81
+
82
+ order.items.push(item);
83
+ }
84
+
85
+ const payment = new CreatePaymentValidator();
86
+
87
+ payment.order = order._id;
88
+ payment.total = order.total;
89
+ payment.type = validator.billing.type;
90
+ payment.user = user._id;
91
+ payment.payload = validator.billing.payload;
92
+
93
+ order.payment = await this.$payments.create(payment, order);
94
+
95
+ await order.save();
96
+
97
+ return order;
98
+ }
99
+
100
+ public async update(id: string, validator: UpdateOrderValidator) {
101
+ const order = await this.read(id);
102
+
103
+ await order.save();
104
+
105
+ return order;
106
+ }
107
+
108
+ public async updateStatus(id: string, type: OrderStatus, user: UserEntity) {
109
+ const order = await this.read(id);
110
+
111
+ const status = new StatusDocument();
112
+ status.date = new Date();
113
+ status.name = type;
114
+ status.user = user;
115
+
116
+ order.status.push(status);
117
+
118
+ await order.save();
119
+
120
+ return order;
121
+ }
122
+ }
@@ -0,0 +1,36 @@
1
+ import { SchemaFactory } from '@nestjs/mongoose';
2
+ import { OrderEntity } from './order.entity';
3
+
4
+ export namespace OrderSchema {
5
+ export const name = 'sale_orders';
6
+
7
+ export const schema = SchemaFactory.createForClass(OrderEntity);
8
+
9
+ schema.virtual('total').get(function () {
10
+ return this.items.reduce((amount, current) => {
11
+ const price = current.price || 0;
12
+ const quantity = current.quantity || 1;
13
+
14
+ return amount + price * quantity;
15
+ }, 0);
16
+ });
17
+
18
+ schema.virtual('fullNumber').get(function () {
19
+ const createdAt = new Date(this.createdAt);
20
+
21
+ const year = `Y${createdAt.getFullYear().toString().slice(2)}`;
22
+ const month = `M${(createdAt.getMonth() + 1).toString().padStart(2, '0')}`;
23
+ const day = `D${createdAt.getDate().toString().padStart(2, '0')}`;
24
+
25
+ const date = `${year}${month}${day}`;
26
+ const number = this.number.toString().padStart(4, '0');
27
+
28
+ return `${date}-${number}`.toUpperCase();
29
+ });
30
+
31
+ schema.virtual('lastStatus').get(function () {
32
+ const [first] = this.status.reverse();
33
+
34
+ return first;
35
+ });
36
+ }
@@ -0,0 +1,44 @@
1
+ import { Type } from 'class-transformer';
2
+ import {
3
+ ArrayNotEmpty,
4
+ IsArray,
5
+ IsEnum,
6
+ IsNotEmptyObject,
7
+ IsOptional,
8
+ IsString,
9
+ ValidateNested,
10
+ } from 'class-validator';
11
+ import { IdMongoValidator } from '../../../abstracts/abstract.validator';
12
+ import { OrderStatus } from './enums/order.status';
13
+ import { BillingValidator } from './validators/billing.validator';
14
+ import { CreateItemValidator } from './validators/item.validator';
15
+ import { ShippingValidator } from './validators/shipping.validator';
16
+
17
+ export class CreateOrderValidator {
18
+ @IsArray()
19
+ @ArrayNotEmpty()
20
+ @Type(() => CreateItemValidator)
21
+ @ValidateNested()
22
+ public items: CreateItemValidator[] = [];
23
+
24
+ @Type(() => BillingValidator)
25
+ @ValidateNested()
26
+ @IsNotEmptyObject()
27
+ public billing = new BillingValidator();
28
+
29
+ @Type(() => ShippingValidator)
30
+ @ValidateNested()
31
+ @IsNotEmptyObject()
32
+ public shipping = new ShippingValidator();
33
+
34
+ @IsString()
35
+ @IsOptional()
36
+ public description = String();
37
+ }
38
+
39
+ export class UpdateOrderValidator extends CreateOrderValidator {}
40
+
41
+ export class UpdateOrderStatusValidator extends IdMongoValidator {
42
+ @IsEnum(OrderStatus)
43
+ public type: OrderStatus;
44
+ }
@@ -0,0 +1,50 @@
1
+ import { IsISO31661Alpha2, IsOptional, IsString, Matches } from 'class-validator';
2
+
3
+ export class CreateAddressValidator {
4
+ @IsString()
5
+ public street: string;
6
+
7
+ @IsString()
8
+ @IsOptional()
9
+ public complement: string;
10
+
11
+ @IsString()
12
+ public city: string;
13
+
14
+ @IsString()
15
+ public state: string;
16
+
17
+ @IsString()
18
+ public number: string;
19
+
20
+ @IsString()
21
+ @IsOptional()
22
+ public neighborhood: string;
23
+
24
+ @IsString()
25
+ @Matches(/[a-zA-Z0-9_-]{8}/, { message: 'zipCode must be valid' })
26
+ public zipCode: string;
27
+ }
28
+
29
+ export class AddressValidator {
30
+ @IsString()
31
+ public line1: string;
32
+
33
+ @IsString()
34
+ @IsOptional()
35
+ public line2: string;
36
+
37
+ @IsString()
38
+ public city: string;
39
+
40
+ @IsString()
41
+ public state: string;
42
+
43
+ @IsString()
44
+ @IsISO31661Alpha2()
45
+ public country: string;
46
+
47
+ @IsString()
48
+ @Matches(/[a-zA-Z0-9_-]{8}/, { message: 'zipCode must be valid' })
49
+ public code: string;
50
+ }
@@ -0,0 +1,11 @@
1
+ import { BillingType } from '../../payments/enums/billing.type';
2
+ import { AddressValidator } from './address.validator';
3
+ import { PaymentValidator } from './payment.validator';
4
+
5
+ export class BillingValidator {
6
+ public type: BillingType;
7
+
8
+ public payload = new PaymentValidator();
9
+
10
+ public address = new AddressValidator();
11
+ }
@@ -0,0 +1,14 @@
1
+ import { IsInt, IsMongoId, IsOptional, IsPositive, IsString } from 'class-validator';
2
+
3
+ export class CreateItemValidator {
4
+ @IsMongoId()
5
+ public product: string;
6
+
7
+ @IsPositive()
8
+ @IsInt()
9
+ public quantity: number;
10
+
11
+ @IsString()
12
+ @IsOptional()
13
+ public description?: string;
14
+ }