diff --git a/database/migrations/.snapshot-dkala.json b/database/migrations/.snapshot-dkala.json index 631414b..cdb62c9 100644 --- a/database/migrations/.snapshot-dkala.json +++ b/database/migrations/.snapshot-dkala.json @@ -127,6 +127,99 @@ "foreignKeys": {}, "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" + }, + "updated_at": { + "name": "updated_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" + }, + "url": { + "name": "url", + "type": "varchar(255)", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 255, + "mappedType": "string" + } + }, + "name": "backgrounds", + "schema": "public", + "indexes": [ + { + "keyName": "backgrounds_created_at_index", + "columnNames": [ + "created_at" + ], + "composite": false, + "constraint": false, + "primary": false, + "unique": false + }, + { + "keyName": "backgrounds_deleted_at_index", + "columnNames": [ + "deleted_at" + ], + "composite": false, + "constraint": false, + "primary": false, + "unique": false + }, + { + "keyName": "backgrounds_pkey", + "columnNames": [ + "id" + ], + "composite": false, + "constraint": true, + "primary": true, + "unique": true + } + ], + "checks": [], + "foreignKeys": {}, + "nativeEnums": {} + }, { "columns": { "id": { @@ -1059,6 +1152,56 @@ "nullable": true, "length": 6, "mappedType": "datetime" + }, + "bg_type": { + "name": "bg_type", + "type": "varchar(255)", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "length": 255, + "mappedType": "string" + }, + "bg_url": { + "name": "bg_url", + "type": "varchar(255)", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "length": 255, + "mappedType": "string" + }, + "bg_opacity": { + "name": "bg_opacity", + "type": "varchar(255)", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "length": 255, + "mappedType": "string" + }, + "bg_blur": { + "name": "bg_blur", + "type": "varchar(255)", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "length": 255, + "mappedType": "string" + }, + "bg_overlay": { + "name": "bg_overlay", + "type": "varchar(255)", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "length": 255, + "mappedType": "string" } }, "name": "shops", @@ -2826,23 +2969,27 @@ }, "max_purchase_quantity": { "name": "max_purchase_quantity", - "type": "int", + "type": "numeric(10,3)", "unsigned": false, "autoincrement": false, "primary": false, "nullable": true, + "precision": 10, + "scale": 3, "default": "null", - "mappedType": "integer" + "mappedType": "decimal" }, "min_purchase_quantity": { "name": "min_purchase_quantity", - "type": "int", + "type": "numeric(10,3)", "unsigned": false, "autoincrement": false, "primary": false, "nullable": true, + "precision": 10, + "scale": 3, "default": "null", - "mappedType": "integer" + "mappedType": "decimal" }, "pricing_type": { "name": "pricing_type", @@ -3865,13 +4012,15 @@ }, "total_items": { "name": "total_items", - "type": "int", + "type": "numeric(10,3)", "unsigned": false, "autoincrement": false, "primary": false, "nullable": false, + "precision": 10, + "scale": 3, "default": "0", - "mappedType": "integer" + "mappedType": "decimal" }, "description": { "name": "description", @@ -3890,14 +4039,14 @@ "primary": false, "nullable": false, "enumItems": [ + "needConfirmation", "pendingPayment", "paid", "preparing", "deliveredToRecepient", "shipped", "completed", - "canceled", - "needConfirmation" + "canceled" ], "mappedType": "enum" }, @@ -5011,6 +5160,176 @@ }, "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" + }, + "updated_at": { + "name": "updated_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" + }, + "user_id": { + "name": "user_id", + "type": "char(26)", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 26, + "mappedType": "character" + }, + "shop_id": { + "name": "shop_id", + "type": "char(26)", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 26, + "mappedType": "character" + }, + "order_count": { + "name": "order_count", + "type": "int", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "default": "0", + "mappedType": "integer" + }, + "total_order_amount": { + "name": "total_order_amount", + "type": "int", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "default": "0", + "mappedType": "integer" + } + }, + "name": "user_shops", + "schema": "public", + "indexes": [ + { + "keyName": "user_shops_created_at_index", + "columnNames": [ + "created_at" + ], + "composite": false, + "constraint": false, + "primary": false, + "unique": false + }, + { + "keyName": "user_shops_deleted_at_index", + "columnNames": [ + "deleted_at" + ], + "composite": false, + "constraint": false, + "primary": false, + "unique": false + }, + { + "keyName": "user_shops_user_id_shop_id_index", + "columnNames": [ + "user_id", + "shop_id" + ], + "composite": true, + "constraint": false, + "primary": false, + "unique": false + }, + { + "keyName": "user_shops_user_id_shop_id_unique", + "columnNames": [ + "user_id", + "shop_id" + ], + "composite": true, + "constraint": true, + "primary": false, + "unique": true + }, + { + "keyName": "user_shops_pkey", + "columnNames": [ + "id" + ], + "composite": false, + "constraint": true, + "primary": true, + "unique": true + } + ], + "checks": [], + "foreignKeys": { + "user_shops_user_id_foreign": { + "constraintName": "user_shops_user_id_foreign", + "columnNames": [ + "user_id" + ], + "localTableName": "public.user_shops", + "referencedColumnNames": [ + "id" + ], + "referencedTableName": "public.users", + "updateRule": "cascade" + }, + "user_shops_shop_id_foreign": { + "constraintName": "user_shops_shop_id_foreign", + "columnNames": [ + "shop_id" + ], + "localTableName": "public.user_shops", + "referencedColumnNames": [ + "id" + ], + "referencedTableName": "public.shops", + "updateRule": "cascade" + } + }, + "nativeEnums": {} + }, { "columns": { "id": { @@ -5088,13 +5407,15 @@ }, "stock": { "name": "stock", - "type": "int", + "type": "numeric(10,3)", "unsigned": false, "autoincrement": false, "primary": false, "nullable": true, + "precision": 10, + "scale": 3, "default": "null", - "mappedType": "integer" + "mappedType": "decimal" } }, "name": "variants", @@ -5224,12 +5545,14 @@ }, "quantity": { "name": "quantity", - "type": "int", + "type": "numeric(10,3)", "unsigned": false, "autoincrement": false, "primary": false, "nullable": false, - "mappedType": "integer" + "precision": 10, + "scale": 3, + "mappedType": "decimal" }, "unit_price": { "name": "unit_price", diff --git a/database/migrations/Migration20260709080612_updateProductType.ts b/database/migrations/Migration20260709080612_updateProductType.ts new file mode 100644 index 0000000..86b1603 --- /dev/null +++ b/database/migrations/Migration20260709080612_updateProductType.ts @@ -0,0 +1,20 @@ +import { Migration } from '@mikro-orm/migrations'; + +export class Migration20260709080612_updateProductType extends Migration { + + override async up(): Promise { + this.addSql(`alter table "products" alter column "max_purchase_quantity" type numeric(10,3) using ("max_purchase_quantity"::numeric(10,3));`); + this.addSql(`alter table "products" alter column "min_purchase_quantity" type numeric(10,3) using ("min_purchase_quantity"::numeric(10,3));`); + + this.addSql(`alter table "order_items" alter column "quantity" type numeric(10,3) using ("quantity"::numeric(10,3));`); + } + + override async down(): Promise { + + this.addSql(`alter table "products" alter column "max_purchase_quantity" type int using ("max_purchase_quantity"::int);`); + this.addSql(`alter table "products" alter column "min_purchase_quantity" type int using ("min_purchase_quantity"::int);`); + + this.addSql(`alter table "order_items" alter column "quantity" type int using ("quantity"::int);`); + } + +} diff --git a/src/modules/products/entities/product.entity.ts b/src/modules/products/entities/product.entity.ts index 6028375..85ae108 100644 --- a/src/modules/products/entities/product.entity.ts +++ b/src/modules/products/entities/product.entity.ts @@ -58,10 +58,10 @@ export class Product extends BaseEntity { /** Maximum quantity per order; null means unlimited */ - @Property({ type: 'decimal', precision: 10, scale: 3, nullable: true, default: null }) + @Property({ type: 'decimal', precision: 10, scale: 3, nullable: true, default: null, runtimeType: 'number' }) maxPurchaseQuantity: number | null = null; - @Property({ type: 'decimal', precision: 10, scale: 3, nullable: true, default: null }) + @Property({ type: 'decimal', precision: 10, scale: 3, nullable: true, default: null, runtimeType: 'number' }) minPurchaseQuantity: number | null = null; // برای کالا هایی مثل گوشت متغیر میشه @@ -78,6 +78,7 @@ export class Product extends BaseEntity { scale: 3, nullable: true, default: null, + runtimeType: 'number', }) purchasePitch?: number | null = null; diff --git a/src/modules/products/entities/variant.entity.ts b/src/modules/products/entities/variant.entity.ts index 0212c1a..522e9f8 100644 --- a/src/modules/products/entities/variant.entity.ts +++ b/src/modules/products/entities/variant.entity.ts @@ -11,10 +11,10 @@ export class Variant extends BaseEntity { @Property({ type: 'string' }) value: string - @Property({ type: 'decimal', precision: 10, scale: 0, nullable: true }) + @Property({ type: 'decimal', precision: 10, scale: 0, nullable: true, runtimeType: 'number' }) price?: number; /** Available quantity; null means unlimited */ - @Property({ type: 'decimal', precision: 10, scale: 3, nullable: true, default: null }) + @Property({ type: 'decimal', precision: 10, scale: 3, nullable: true, default: null, runtimeType: 'number' }) stock: number | null = null; } diff --git a/src/modules/products/providers/product.service.ts b/src/modules/products/providers/product.service.ts index a47483f..9fde44b 100644 --- a/src/modules/products/providers/product.service.ts +++ b/src/modules/products/providers/product.service.ts @@ -161,7 +161,11 @@ export class ProductService { } // Update the variant fields - this.em.assign(existingVariant, { value, price, stock: stock ?? null }); + this.em.assign(existingVariant, { + value, + price, + stock: stock ?? null, + }); updatedVariantIds.add(id); } else { // Create new variant @@ -182,8 +186,15 @@ export class ProductService { } } } + const sanitizedRest = { + ...rest, + maxPurchaseQuantity: rest.maxPurchaseQuantity, + minPurchaseQuantity: rest.minPurchaseQuantity, + purchasePitch: rest.purchasePitch, + }; + // assign other fields from DTO (excluding dailyStock handled below) - this.em.assign(product, rest); + this.em.assign(product, sanitizedRest); await this.em.persistAndFlush(product);