@@ -703,22 +703,13 @@
|
|||||||
"nullable": true,
|
"nullable": true,
|
||||||
"length": 6,
|
"length": 6,
|
||||||
"mappedType": "datetime"
|
"mappedType": "datetime"
|
||||||
},
|
|
||||||
"fileds": {
|
|
||||||
"name": "fileds",
|
|
||||||
"type": "jsonb",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": true,
|
|
||||||
"mappedType": "json"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"name": "prints",
|
"name": "order_prints",
|
||||||
"schema": "public",
|
"schema": "public",
|
||||||
"indexes": [
|
"indexes": [
|
||||||
{
|
{
|
||||||
"keyName": "prints_pkey",
|
"keyName": "order_prints_pkey",
|
||||||
"columnNames": [
|
"columnNames": [
|
||||||
"id"
|
"id"
|
||||||
],
|
],
|
||||||
@@ -732,6 +723,122 @@
|
|||||||
"foreignKeys": {},
|
"foreignKeys": {},
|
||||||
"nativeEnums": {}
|
"nativeEnums": {}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "char(26)",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 26,
|
||||||
|
"mappedType": "character"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"name": "created_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 6,
|
||||||
|
"default": "now()",
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"deleted_at": {
|
||||||
|
"name": "deleted_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"length": 6,
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"order_print_id": {
|
||||||
|
"name": "order_print_id",
|
||||||
|
"type": "char(26)",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 26,
|
||||||
|
"mappedType": "character"
|
||||||
|
},
|
||||||
|
"field_id": {
|
||||||
|
"name": "field_id",
|
||||||
|
"type": "char(26)",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 26,
|
||||||
|
"mappedType": "character"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"name": "value",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "order_print_values",
|
||||||
|
"schema": "public",
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"keyName": "order_print_values_order_print_id_index",
|
||||||
|
"columnNames": [
|
||||||
|
"order_print_id"
|
||||||
|
],
|
||||||
|
"composite": false,
|
||||||
|
"constraint": false,
|
||||||
|
"primary": false,
|
||||||
|
"unique": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "order_print_values_pkey",
|
||||||
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"composite": false,
|
||||||
|
"constraint": true,
|
||||||
|
"primary": true,
|
||||||
|
"unique": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checks": [],
|
||||||
|
"foreignKeys": {
|
||||||
|
"order_print_values_order_print_id_foreign": {
|
||||||
|
"constraintName": "order_print_values_order_print_id_foreign",
|
||||||
|
"columnNames": [
|
||||||
|
"order_print_id"
|
||||||
|
],
|
||||||
|
"localTableName": "public.order_print_values",
|
||||||
|
"referencedColumnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"referencedTableName": "public.order_prints",
|
||||||
|
"updateRule": "cascade"
|
||||||
|
},
|
||||||
|
"order_print_values_field_id_foreign": {
|
||||||
|
"constraintName": "order_print_values_field_id_foreign",
|
||||||
|
"columnNames": [
|
||||||
|
"field_id"
|
||||||
|
],
|
||||||
|
"localTableName": "public.order_print_values",
|
||||||
|
"referencedColumnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"referencedTableName": "public.field",
|
||||||
|
"updateRule": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nativeEnums": {}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
@@ -784,6 +891,11 @@
|
|||||||
"delete_invoice",
|
"delete_invoice",
|
||||||
"view_orders",
|
"view_orders",
|
||||||
"view_assigned_orders",
|
"view_assigned_orders",
|
||||||
|
"change_order_status_from_any_to_any",
|
||||||
|
"change_order_status_to_cancelled",
|
||||||
|
"change_order_status_in_progress",
|
||||||
|
"change_order_status_from_in_progress_to_finished",
|
||||||
|
"change_order_status_from_finished_to_invoiced",
|
||||||
"create_order",
|
"create_order",
|
||||||
"update_order",
|
"update_order",
|
||||||
"assign_designer",
|
"assign_designer",
|
||||||
@@ -796,8 +908,8 @@
|
|||||||
"manage_roles",
|
"manage_roles",
|
||||||
"manage_payments",
|
"manage_payments",
|
||||||
"manage_settings",
|
"manage_settings",
|
||||||
"create_print",
|
"create_print_form",
|
||||||
"view_print",
|
"view_print_form",
|
||||||
"manage_learnings",
|
"manage_learnings",
|
||||||
"manage_criticisms",
|
"manage_criticisms",
|
||||||
"manage_announcements",
|
"manage_announcements",
|
||||||
@@ -971,15 +1083,6 @@
|
|||||||
"length": 255,
|
"length": 255,
|
||||||
"mappedType": "string"
|
"mappedType": "string"
|
||||||
},
|
},
|
||||||
"quantities": {
|
|
||||||
"name": "quantities",
|
|
||||||
"type": "jsonb",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": false,
|
|
||||||
"mappedType": "json"
|
|
||||||
},
|
|
||||||
"link_url": {
|
"link_url": {
|
||||||
"name": "link_url",
|
"name": "link_url",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
@@ -1836,20 +1939,6 @@
|
|||||||
"primary": false,
|
"primary": false,
|
||||||
"nullable": false,
|
"nullable": false,
|
||||||
"mappedType": "integer"
|
"mappedType": "integer"
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
"name": "status",
|
|
||||||
"type": "text",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": false,
|
|
||||||
"default": "'pending'",
|
|
||||||
"enumItems": [
|
|
||||||
"pending",
|
|
||||||
"invoiced"
|
|
||||||
],
|
|
||||||
"mappedType": "enum"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"name": "requests",
|
"name": "requests",
|
||||||
@@ -2400,6 +2489,21 @@
|
|||||||
"nullable": false,
|
"nullable": false,
|
||||||
"mappedType": "integer"
|
"mappedType": "integer"
|
||||||
},
|
},
|
||||||
|
"confirm_status": {
|
||||||
|
"name": "confirm_status",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"default": "'pending'",
|
||||||
|
"enumItems": [
|
||||||
|
"pending",
|
||||||
|
"partially_confirmed",
|
||||||
|
"confirmed"
|
||||||
|
],
|
||||||
|
"mappedType": "enum"
|
||||||
|
},
|
||||||
"enable_tax": {
|
"enable_tax": {
|
||||||
"name": "enable_tax",
|
"name": "enable_tax",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@@ -2496,19 +2600,6 @@
|
|||||||
],
|
],
|
||||||
"referencedTableName": "public.users",
|
"referencedTableName": "public.users",
|
||||||
"updateRule": "cascade"
|
"updateRule": "cascade"
|
||||||
},
|
|
||||||
"invoices_request_id_foreign": {
|
|
||||||
"constraintName": "invoices_request_id_foreign",
|
|
||||||
"columnNames": [
|
|
||||||
"request_id"
|
|
||||||
],
|
|
||||||
"localTableName": "public.invoices",
|
|
||||||
"referencedColumnNames": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"referencedTableName": "public.requests",
|
|
||||||
"deleteRule": "set null",
|
|
||||||
"updateRule": "cascade"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nativeEnums": {}
|
"nativeEnums": {}
|
||||||
@@ -3026,16 +3117,6 @@
|
|||||||
"length": 26,
|
"length": 26,
|
||||||
"mappedType": "character"
|
"mappedType": "character"
|
||||||
},
|
},
|
||||||
"designer_id": {
|
|
||||||
"name": "designer_id",
|
|
||||||
"type": "char(26)",
|
|
||||||
"unsigned": false,
|
|
||||||
"autoincrement": false,
|
|
||||||
"primary": false,
|
|
||||||
"nullable": true,
|
|
||||||
"length": 26,
|
|
||||||
"mappedType": "character"
|
|
||||||
},
|
|
||||||
"creator_id": {
|
"creator_id": {
|
||||||
"name": "creator_id",
|
"name": "creator_id",
|
||||||
"type": "char(26)",
|
"type": "char(26)",
|
||||||
@@ -3065,8 +3146,6 @@
|
|||||||
"default": "'created'",
|
"default": "'created'",
|
||||||
"enumItems": [
|
"enumItems": [
|
||||||
"created",
|
"created",
|
||||||
"invoiced",
|
|
||||||
"waiting_to_confirm_invoice",
|
|
||||||
"design_initiated",
|
"design_initiated",
|
||||||
"design_finished",
|
"design_finished",
|
||||||
"design_revision",
|
"design_revision",
|
||||||
@@ -3078,7 +3157,8 @@
|
|||||||
"after_print_boxing",
|
"after_print_boxing",
|
||||||
"after_print_cartoning",
|
"after_print_cartoning",
|
||||||
"finished",
|
"finished",
|
||||||
"canceled"
|
"canceled",
|
||||||
|
"invoiced"
|
||||||
],
|
],
|
||||||
"mappedType": "enum"
|
"mappedType": "enum"
|
||||||
},
|
},
|
||||||
@@ -3134,16 +3214,6 @@
|
|||||||
"primary": false,
|
"primary": false,
|
||||||
"unique": false
|
"unique": false
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"keyName": "orders_designer_id_index",
|
|
||||||
"columnNames": [
|
|
||||||
"designer_id"
|
|
||||||
],
|
|
||||||
"composite": false,
|
|
||||||
"constraint": false,
|
|
||||||
"primary": false,
|
|
||||||
"unique": false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"keyName": "orders_user_id_index",
|
"keyName": "orders_user_id_index",
|
||||||
"columnNames": [
|
"columnNames": [
|
||||||
@@ -3202,7 +3272,7 @@
|
|||||||
"referencedColumnNames": [
|
"referencedColumnNames": [
|
||||||
"id"
|
"id"
|
||||||
],
|
],
|
||||||
"referencedTableName": "public.prints",
|
"referencedTableName": "public.order_prints",
|
||||||
"deleteRule": "set null",
|
"deleteRule": "set null",
|
||||||
"updateRule": "cascade"
|
"updateRule": "cascade"
|
||||||
},
|
},
|
||||||
@@ -3230,19 +3300,6 @@
|
|||||||
"referencedTableName": "public.users",
|
"referencedTableName": "public.users",
|
||||||
"updateRule": "cascade"
|
"updateRule": "cascade"
|
||||||
},
|
},
|
||||||
"orders_designer_id_foreign": {
|
|
||||||
"constraintName": "orders_designer_id_foreign",
|
|
||||||
"columnNames": [
|
|
||||||
"designer_id"
|
|
||||||
],
|
|
||||||
"localTableName": "public.orders",
|
|
||||||
"referencedColumnNames": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"referencedTableName": "public.admins",
|
|
||||||
"deleteRule": "set null",
|
|
||||||
"updateRule": "cascade"
|
|
||||||
},
|
|
||||||
"orders_creator_id_foreign": {
|
"orders_creator_id_foreign": {
|
||||||
"constraintName": "orders_creator_id_foreign",
|
"constraintName": "orders_creator_id_foreign",
|
||||||
"columnNames": [
|
"columnNames": [
|
||||||
@@ -3259,6 +3316,134 @@
|
|||||||
},
|
},
|
||||||
"nativeEnums": {}
|
"nativeEnums": {}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "char(26)",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 26,
|
||||||
|
"mappedType": "character"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"name": "created_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 6,
|
||||||
|
"default": "now()",
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"deleted_at": {
|
||||||
|
"name": "deleted_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"length": 6,
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"order_id": {
|
||||||
|
"name": "order_id",
|
||||||
|
"type": "char(26)",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 26,
|
||||||
|
"mappedType": "character"
|
||||||
|
},
|
||||||
|
"designer_id": {
|
||||||
|
"name": "designer_id",
|
||||||
|
"type": "char(26)",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 26,
|
||||||
|
"mappedType": "character"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "order_designers",
|
||||||
|
"schema": "public",
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"keyName": "order_designers_designer_id_index",
|
||||||
|
"columnNames": [
|
||||||
|
"designer_id"
|
||||||
|
],
|
||||||
|
"composite": false,
|
||||||
|
"constraint": false,
|
||||||
|
"primary": false,
|
||||||
|
"unique": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "order_designers_order_id_index",
|
||||||
|
"columnNames": [
|
||||||
|
"order_id"
|
||||||
|
],
|
||||||
|
"composite": false,
|
||||||
|
"constraint": false,
|
||||||
|
"primary": false,
|
||||||
|
"unique": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "order_designers_order_id_designer_id_unique",
|
||||||
|
"columnNames": [
|
||||||
|
"order_id",
|
||||||
|
"designer_id"
|
||||||
|
],
|
||||||
|
"composite": true,
|
||||||
|
"constraint": true,
|
||||||
|
"primary": false,
|
||||||
|
"unique": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "order_designers_pkey",
|
||||||
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"composite": false,
|
||||||
|
"constraint": true,
|
||||||
|
"primary": true,
|
||||||
|
"unique": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checks": [],
|
||||||
|
"foreignKeys": {
|
||||||
|
"order_designers_order_id_foreign": {
|
||||||
|
"constraintName": "order_designers_order_id_foreign",
|
||||||
|
"columnNames": [
|
||||||
|
"order_id"
|
||||||
|
],
|
||||||
|
"localTableName": "public.order_designers",
|
||||||
|
"referencedColumnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"referencedTableName": "public.orders",
|
||||||
|
"updateRule": "cascade"
|
||||||
|
},
|
||||||
|
"order_designers_designer_id_foreign": {
|
||||||
|
"constraintName": "order_designers_designer_id_foreign",
|
||||||
|
"columnNames": [
|
||||||
|
"designer_id"
|
||||||
|
],
|
||||||
|
"localTableName": "public.order_designers",
|
||||||
|
"referencedColumnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"referencedTableName": "public.admins",
|
||||||
|
"updateRule": "cascade"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nativeEnums": {}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"columns": {
|
"columns": {
|
||||||
"id": {
|
"id": {
|
||||||
|
|||||||
@@ -143,10 +143,10 @@ export class ChatListeners {
|
|||||||
const order = await this.em.findOne(
|
const order = await this.em.findOne(
|
||||||
Order,
|
Order,
|
||||||
{ id: refId },
|
{ id: refId },
|
||||||
{ populate: ['designer'], fields: ['id', 'designer'] },
|
{ populate: ['designers', 'designers.designer'] },
|
||||||
);
|
);
|
||||||
if (order?.designer?.id) {
|
if (order?.designers?.length) {
|
||||||
return [order?.designer?.id]
|
return order.designers.getItems().map((od) => od.designer.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ export class OrderController {
|
|||||||
@Permissions(PermissionEnum.ASSIGN_DESIGNER)
|
@Permissions(PermissionEnum.ASSIGN_DESIGNER)
|
||||||
@ApiOperation({ summary: 'Assign Order Designer ' })
|
@ApiOperation({ summary: 'Assign Order Designer ' })
|
||||||
assignDesigner(@Param('orderId') orderId: string, @Body() body: AssignDesignerDto) {
|
assignDesigner(@Param('orderId') orderId: string, @Body() body: AssignDesignerDto) {
|
||||||
return this.orderService.assignDesigner(orderId, body.designerId);
|
return this.orderService.assignDesigner(orderId, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Permission handled inside service
|
// Permission handled inside service
|
||||||
|
|||||||
@@ -1,11 +1,19 @@
|
|||||||
import {
|
import {
|
||||||
IsString
|
IsArray,
|
||||||
|
IsOptional,
|
||||||
|
IsString,
|
||||||
} from 'class-validator';
|
} from 'class-validator';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
|
||||||
export class AssignDesignerDto {
|
export class AssignDesignerDto {
|
||||||
@IsString()
|
@ApiPropertyOptional({ description: 'Single designer id (legacy)' })
|
||||||
@ApiProperty()
|
@IsOptional()
|
||||||
designerId: string;
|
@IsString()
|
||||||
}
|
designerId?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ type: [String], description: 'One or more designer ids' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsArray()
|
||||||
|
@IsString({ each: true })
|
||||||
|
designerIds?: string[];
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,11 +16,17 @@ export class CreateOrderAsAdminDto {
|
|||||||
@IsOptional()
|
@IsOptional()
|
||||||
userId?: string;
|
userId?: string;
|
||||||
|
|
||||||
@ApiPropertyOptional({ example: '' })
|
@ApiPropertyOptional({ example: '', description: 'Single designer id (legacy)' })
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
designerId?: string;
|
designerId?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ type: [String], description: 'One or more designer ids' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsArray()
|
||||||
|
@IsString({ each: true })
|
||||||
|
designerIds?: string[];
|
||||||
|
|
||||||
@ApiPropertyOptional({ example: '' })
|
@ApiPropertyOptional({ example: '' })
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { Entity, Index, ManyToOne, OptionalProps, Unique } from '@mikro-orm/core';
|
||||||
|
import { BaseEntity } from 'src/common/entities/base.entity';
|
||||||
|
import { Admin } from 'src/modules/admin/entities/admin.entity';
|
||||||
|
import { Order } from './order.entity';
|
||||||
|
|
||||||
|
@Entity({ tableName: 'order_designers' })
|
||||||
|
@Unique({ properties: ['order', 'designer'] })
|
||||||
|
@Index({ properties: ['order'] })
|
||||||
|
@Index({ properties: ['designer'] })
|
||||||
|
export class OrderDesigner extends BaseEntity {
|
||||||
|
[OptionalProps]?: 'createdAt' | 'deletedAt';
|
||||||
|
|
||||||
|
@ManyToOne(() => Order)
|
||||||
|
order!: Order;
|
||||||
|
|
||||||
|
@ManyToOne(() => Admin)
|
||||||
|
designer!: Admin;
|
||||||
|
}
|
||||||
@@ -7,7 +7,9 @@ import {
|
|||||||
PrimaryKey,
|
PrimaryKey,
|
||||||
OptionalProps,
|
OptionalProps,
|
||||||
OneToOne,
|
OneToOne,
|
||||||
Opt
|
OneToMany,
|
||||||
|
Collection,
|
||||||
|
Opt,
|
||||||
} from '@mikro-orm/core';
|
} from '@mikro-orm/core';
|
||||||
import { User } from '../../user/entities/user.entity';
|
import { User } from '../../user/entities/user.entity';
|
||||||
import { ulid } from 'ulid';
|
import { ulid } from 'ulid';
|
||||||
@@ -18,10 +20,10 @@ import { InvoiceItem } from 'src/modules/invoice/entities/invoice-item.entity';
|
|||||||
import { Product } from 'src/modules/product/entities/product.entity';
|
import { Product } from 'src/modules/product/entities/product.entity';
|
||||||
import { Category } from 'src/modules/product/entities/category.entity';
|
import { Category } from 'src/modules/product/entities/category.entity';
|
||||||
import { OrderPrint } from './order-print.entity';
|
import { OrderPrint } from './order-print.entity';
|
||||||
|
import { OrderDesigner } from './order-designer.entity';
|
||||||
|
|
||||||
@Entity({ tableName: 'orders' })
|
@Entity({ tableName: 'orders' })
|
||||||
@Index({ properties: ['user'] })
|
@Index({ properties: ['user'] })
|
||||||
@Index({ properties: ['designer'] })
|
|
||||||
@Index({ properties: ['status'] })
|
@Index({ properties: ['status'] })
|
||||||
export class Order extends BaseEntity {
|
export class Order extends BaseEntity {
|
||||||
[OptionalProps]?: 'createdAt' | 'deletedAt' | 'orderNumber'
|
[OptionalProps]?: 'createdAt' | 'deletedAt' | 'orderNumber'
|
||||||
@@ -32,10 +34,12 @@ export class Order extends BaseEntity {
|
|||||||
@ManyToOne(() => Product, { nullable: true })
|
@ManyToOne(() => Product, { nullable: true })
|
||||||
product?: Product | null;
|
product?: Product | null;
|
||||||
|
|
||||||
|
|
||||||
@OneToOne(() => OrderPrint, (orderPrint) => orderPrint.order, { owner: true, nullable: true })
|
@OneToOne(() => OrderPrint, (orderPrint) => orderPrint.order, { owner: true, nullable: true })
|
||||||
print?: OrderPrint | null
|
print?: OrderPrint | null
|
||||||
|
|
||||||
|
@OneToMany(() => OrderDesigner, (orderDesigner) => orderDesigner.order, { orphanRemoval: true })
|
||||||
|
designers = new Collection<OrderDesigner>(this);
|
||||||
|
|
||||||
@PrimaryKey({ type: 'string', columnType: 'char(26)' })
|
@PrimaryKey({ type: 'string', columnType: 'char(26)' })
|
||||||
id: string = ulid()
|
id: string = ulid()
|
||||||
|
|
||||||
@@ -48,9 +52,6 @@ export class Order extends BaseEntity {
|
|||||||
@ManyToOne(() => User)
|
@ManyToOne(() => User)
|
||||||
user!: User;
|
user!: User;
|
||||||
|
|
||||||
@ManyToOne(() => Admin, { nullable: true })
|
|
||||||
designer?: Admin
|
|
||||||
|
|
||||||
@ManyToOne(() => Admin, { nullable: true })
|
@ManyToOne(() => Admin, { nullable: true })
|
||||||
creator?: Admin
|
creator?: Admin
|
||||||
|
|
||||||
@@ -61,7 +62,6 @@ export class Order extends BaseEntity {
|
|||||||
})
|
})
|
||||||
orderNumber: number & Opt;
|
orderNumber: number & Opt;
|
||||||
|
|
||||||
|
|
||||||
@Enum(() => OrderStatusEnum)
|
@Enum(() => OrderStatusEnum)
|
||||||
status: OrderStatusEnum = OrderStatusEnum.CREATED;
|
status: OrderStatusEnum = OrderStatusEnum.CREATED;
|
||||||
|
|
||||||
@@ -70,6 +70,4 @@ export class Order extends BaseEntity {
|
|||||||
|
|
||||||
@Property({ type: 'json' })
|
@Property({ type: 'json' })
|
||||||
attachments: IAttachment[] = []
|
attachments: IAttachment[] = []
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { OrderController } from './controllers/order.controller';
|
|||||||
import { Order } from './entities/order.entity';
|
import { Order } from './entities/order.entity';
|
||||||
import { OrderPrint } from './entities/order-print.entity';
|
import { OrderPrint } from './entities/order-print.entity';
|
||||||
import { OrderPrintValue } from './entities/order-print-value.entity';
|
import { OrderPrintValue } from './entities/order-print-value.entity';
|
||||||
|
import { OrderDesigner } from './entities/order-designer.entity';
|
||||||
import { AuthModule } from '../auth/auth.module';
|
import { AuthModule } from '../auth/auth.module';
|
||||||
import { PaymentModule } from '../payment/payments.module';
|
import { PaymentModule } from '../payment/payments.module';
|
||||||
import { JwtModule } from '@nestjs/jwt';
|
import { JwtModule } from '@nestjs/jwt';
|
||||||
@@ -22,7 +23,7 @@ import { OrderPrintValueRepository } from './repositories/order-print-value.repo
|
|||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
MikroOrmModule.forFeature([Order, OrderPrint, OrderPrintValue]),
|
MikroOrmModule.forFeature([Order, OrderPrint, OrderPrintValue, OrderDesigner]),
|
||||||
AuthModule,
|
AuthModule,
|
||||||
forwardRef(() => PaymentModule),
|
forwardRef(() => PaymentModule),
|
||||||
JwtModule,
|
JwtModule,
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import { CreateOrderPrintDto } from '../dto/create-order-print.dto';
|
|||||||
import { OrderPrintValueDto } from '../dto/order-print-value.dto';
|
import { OrderPrintValueDto } from '../dto/order-print-value.dto';
|
||||||
import { OrderPrint } from '../entities/order-print.entity';
|
import { OrderPrint } from '../entities/order-print.entity';
|
||||||
import { OrderPrintValue } from '../entities/order-print-value.entity';
|
import { OrderPrintValue } from '../entities/order-print-value.entity';
|
||||||
|
import { OrderDesigner } from '../entities/order-designer.entity';
|
||||||
import { OrderPrintRepository } from '../repositories/order-print.repository';
|
import { OrderPrintRepository } from '../repositories/order-print.repository';
|
||||||
import { Field } from 'src/modules/form-builder/entities/field.entity';
|
import { Field } from 'src/modules/form-builder/entities/field.entity';
|
||||||
import { Request } from 'src/modules/request/entities/request.entity';
|
import { Request } from 'src/modules/request/entities/request.entity';
|
||||||
@@ -29,6 +30,7 @@ import { Invoice } from 'src/modules/invoice/entities/invoice.entity';
|
|||||||
import { OrderCreatedEvent } from '../events/order.events';
|
import { OrderCreatedEvent } from '../events/order.events';
|
||||||
import { InvoiceConfirmStatusEnum } from 'src/modules/invoice/enum/invoice-confirm-status.enum';
|
import { InvoiceConfirmStatusEnum } from 'src/modules/invoice/enum/invoice-confirm-status.enum';
|
||||||
import { ChattService } from 'src/modules/chat/providers/chat.service';
|
import { ChattService } from 'src/modules/chat/providers/chat.service';
|
||||||
|
import { Admin } from 'src/modules/admin/entities/admin.entity';
|
||||||
|
|
||||||
type AdminOrderTabCounts = {
|
type AdminOrderTabCounts = {
|
||||||
inProgress: number;
|
inProgress: number;
|
||||||
@@ -116,15 +118,11 @@ export class OrderService {
|
|||||||
product = invoiceItem.product;
|
product = invoiceItem.product;
|
||||||
}
|
}
|
||||||
|
|
||||||
let designer = null;
|
const designerIds = this.resolveDesignerIds(dto) ?? [];
|
||||||
if (dto.designerId) {
|
|
||||||
designer = await this.adminService.findOrFail(dto.designerId);
|
|
||||||
}
|
|
||||||
|
|
||||||
const order = this.em.create(Order, {
|
const order = this.em.create(Order, {
|
||||||
user,
|
user,
|
||||||
creator,
|
creator,
|
||||||
designer,
|
|
||||||
type,
|
type,
|
||||||
product: product ?? null,
|
product: product ?? null,
|
||||||
title: dto.title,
|
title: dto.title,
|
||||||
@@ -132,9 +130,9 @@ export class OrderService {
|
|||||||
estimatedDays: dto.estimatedDays,
|
estimatedDays: dto.estimatedDays,
|
||||||
invoiceItem,
|
invoiceItem,
|
||||||
attachments: dto.attachments,
|
attachments: dto.attachments,
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await this.setOrderDesigners(order, designerIds);
|
||||||
await this.em.persistAndFlush(order);
|
await this.em.persistAndFlush(order);
|
||||||
|
|
||||||
if (dto.keepRequestChats) {
|
if (dto.keepRequestChats) {
|
||||||
@@ -266,12 +264,9 @@ export class OrderService {
|
|||||||
order.product = product;
|
order.product = product;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dto.designerId !== undefined) {
|
const designerIds = this.resolveDesignerIds(dto);
|
||||||
if (dto.designerId == null || dto.designerId === '') {
|
if (designerIds !== undefined) {
|
||||||
order.designer = undefined;
|
await this.setOrderDesigners(order, designerIds);
|
||||||
} else {
|
|
||||||
order.designer = await this.adminService.findOrFail(dto.designerId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.em.flush();
|
await this.em.flush();
|
||||||
@@ -354,11 +349,14 @@ export class OrderService {
|
|||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
async assignDesigner(orderId: string, designerId: string) {
|
async assignDesigner(orderId: string, dto: { designerId?: string; designerIds?: string[] }) {
|
||||||
const order = await this.findOrderOrFail(orderId)
|
const order = await this.findOrderOrFail(orderId)
|
||||||
const designer = await this.adminService.findOrFail(designerId)
|
const designerIds = this.resolveDesignerIds(dto)
|
||||||
|
if (designerIds === undefined) {
|
||||||
|
throw new BadRequestException('designerIds or designerId is required')
|
||||||
|
}
|
||||||
|
|
||||||
order.designer = designer
|
await this.setOrderDesigners(order, designerIds)
|
||||||
await this.em.flush()
|
await this.em.flush()
|
||||||
return order
|
return order
|
||||||
}
|
}
|
||||||
@@ -433,11 +431,46 @@ export class OrderService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------Hrlper Methods -----------
|
// -----------Helper Methods -----------
|
||||||
|
private resolveDesignerIds(dto: {
|
||||||
|
designerId?: string | null;
|
||||||
|
designerIds?: string[];
|
||||||
|
}): string[] | undefined {
|
||||||
|
if (dto.designerIds !== undefined) {
|
||||||
|
return [...new Set(dto.designerIds.filter(Boolean))];
|
||||||
|
}
|
||||||
|
if (dto.designerId !== undefined) {
|
||||||
|
if (dto.designerId == null || dto.designerId === '') {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return [dto.designerId];
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async setOrderDesigners(order: Order, designerIds: string[]): Promise<void> {
|
||||||
|
await this.em.populate(order, ['designers']);
|
||||||
|
|
||||||
|
const designers: Admin[] = [];
|
||||||
|
for (const designerId of designerIds) {
|
||||||
|
designers.push(await this.adminService.findOrFail(designerId));
|
||||||
|
}
|
||||||
|
|
||||||
|
order.designers.removeAll();
|
||||||
|
for (const designer of designers) {
|
||||||
|
order.designers.add(
|
||||||
|
this.em.create(OrderDesigner, {
|
||||||
|
order,
|
||||||
|
designer,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async findOrderOrFail(id: string): Promise<Order> {
|
async findOrderOrFail(id: string): Promise<Order> {
|
||||||
const order = await this.em.findOne(Order, { id },
|
const order = await this.em.findOne(Order, { id },
|
||||||
{
|
{
|
||||||
populate: ['user', 'type', 'product', 'creator', 'designer', 'invoiceItem'],
|
populate: ['user', 'type', 'product', 'creator', 'designers', 'designers.designer', 'invoiceItem'],
|
||||||
});
|
});
|
||||||
if (!order) {
|
if (!order) {
|
||||||
throw new NotFoundException(`Order with ID ${id} not found.`);
|
throw new NotFoundException(`Order with ID ${id} not found.`);
|
||||||
@@ -446,12 +479,12 @@ export class OrderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async findOrderOrFailAssignedOrder(id: string, adminId: string): Promise<Order> {
|
async findOrderOrFailAssignedOrder(id: string, adminId: string): Promise<Order> {
|
||||||
const order = await this.em.findOne(Order, { id }, { populate: ['user', 'type', 'product', 'creator'] });
|
const order = await this.findOrderOrFail(id);
|
||||||
if (!order) {
|
const isAssigned = order.designers
|
||||||
throw new NotFoundException(`Order with ID ${id} not found.`);
|
.getItems()
|
||||||
}
|
.some((orderDesigner) => orderDesigner.designer.id === adminId);
|
||||||
if (order?.designer?.id !== adminId) {
|
if (!isAssigned) {
|
||||||
throw new ForbiddenException("You don't have permission to view this order")
|
throw new ForbiddenException("You don't have permission to view this order");
|
||||||
}
|
}
|
||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export class OrderRepository extends EntityRepository<Order> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (designerId) {
|
if (designerId) {
|
||||||
where.designer = { id: designerId };
|
where.designers = { designer: { id: designerId } };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (categoryId) {
|
if (categoryId) {
|
||||||
@@ -87,7 +87,7 @@ export class OrderRepository extends EntityRepository<Order> {
|
|||||||
limit,
|
limit,
|
||||||
offset,
|
offset,
|
||||||
orderBy: { [orderBy]: order.toLowerCase() as 'asc' | 'desc' },
|
orderBy: { [orderBy]: order.toLowerCase() as 'asc' | 'desc' },
|
||||||
populate: ['user', 'product', 'designer', 'invoiceItem', 'invoiceItem.invoice'],
|
populate: ['user', 'product', 'designers', 'designers.designer', 'invoiceItem', 'invoiceItem.invoice'],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user