feat(products): port missing variant fields from henza and redesign variant modal

This commit is contained in:
mahmood
2026-10-25 16:06:17 +03:30
parent 143d9aefbb
commit 55d27151c9
236 changed files with 1009 additions and 352 deletions
@@ -0,0 +1,5 @@
-- AlterTable: Add legacy variant fields (color, rialWage, details, description)
ALTER TABLE "ProductVariant" ADD COLUMN IF NOT EXISTS "color" INTEGER;
ALTER TABLE "ProductVariant" ADD COLUMN IF NOT EXISTS "rialWage" DECIMAL(18,0);
ALTER TABLE "ProductVariant" ADD COLUMN IF NOT EXISTS "details" TEXT;
ALTER TABLE "ProductVariant" ADD COLUMN IF NOT EXISTS "description" TEXT;
+9
View File
@@ -728,6 +728,15 @@ model ProductVariant {
isPreOrder Boolean @default(false)
isActive Boolean @default(true)
/// Legacy color enum: 0=سفید, 1=زرد, 2=شکلاتی, 3=رزگلد
color Int?
/// Legacy rial_pay — fixed Rial making charge per variant.
rialWage Decimal? @db.Decimal(18, 0)
/// Legacy details — short description for variant.
details String? @db.Text
/// Legacy description — full description for variant.
description String? @db.Text
/// The gallery image shown for this variant, picked from its own product's
/// images — never a re-uploaded copy. onDelete: SetNull because dropping an
/// image must never cascade into the variant: OrderItem rows reference
+50 -6
View File
@@ -81854,10 +81854,25 @@ var require_catalog_service = __commonJS({
});
const stockBlocked = await this.accounting.stockBlocker();
const out = [];
const colorNames = { 0: "\u0633\u0641\u06CC\u062F", 1: "\u0632\u0631\u062F", 2: "\u0634\u06A9\u0644\u0627\u062A\u06CC", 3: "\u0631\u0632\u06AF\u0644\u062F" };
for (const p of products) {
const { accountingStockWeight, accountingStockCount, accountingStockAt, ...product } = p;
const blocked = stockBlocked({ accountingStockWeight, accountingStockCount, accountingStockAt });
out.push(blocked ? { ...product, variants: product.variants.map((v) => v.isPreOrder ? v : { ...v, qty: 0 }) } : product);
const mappedVariants = product.variants.map((v) => {
const cNum = v.color != null ? Number(v.color) : null;
const color_str = cNum != null ? colorNames[cNum] ?? null : null;
const base = {
...v,
color: cNum,
color_str,
rial_pay: v.rialWage != null ? Number(v.rialWage) : null
};
return blocked && !v.isPreOrder ? { ...base, qty: 0 } : base;
});
out.push({
...product,
variants: mappedVariants
});
}
return out;
}
@@ -98615,7 +98630,7 @@ var require_admin_products_service = __commonJS({
};
var AdminProductsService_1;
Object.defineProperty(exports2, "__esModule", { value: true });
exports2.AdminProductsService = void 0;
exports2.AdminProductsService = exports2.VARIANT_COLORS = void 0;
var common_12 = require_common();
var client_1 = require("@prisma/client");
var prisma_service_1 = require_prisma_service();
@@ -98626,6 +98641,12 @@ var require_admin_products_service = __commonJS({
2: "\u06AF\u0648\u0634\u06CC",
3: "\u0633\u0627\u06CC\u062A \u0648 \u06AF\u0648\u0634\u06CC"
};
exports2.VARIANT_COLORS = {
0: "\u0633\u0641\u06CC\u062F",
1: "\u0632\u0631\u062F",
2: "\u0634\u06A9\u0644\u0627\u062A\u06CC",
3: "\u0631\u0632\u06AF\u0644\u062F"
};
var AdminProductsService = class AdminProductsService {
static {
AdminProductsService_1 = this;
@@ -98777,6 +98798,7 @@ var require_admin_products_service = __commonJS({
};
}
variantRow(v) {
const colorNum = v.color != null ? Number(v.color) : null;
return {
id: v.id,
product_id_id: v.productId,
@@ -98792,12 +98814,20 @@ var require_admin_products_service = __commonJS({
// without a second lookup. Only populated where the query included it.
image_id: v.imageId,
image: v.image ? { id: v.image.id, url: v.image.url } : null,
// Legacy had a separate rial making-charge column; the schema models wage
// as a percentage only. Returned as null rather than faked.
rial_pay: null,
color_str: null
color: colorNum,
color_str: colorNum != null ? exports2.VARIANT_COLORS[colorNum] ?? null : null,
rial_pay: v.rialWage != null ? Number(v.rialWage) : null,
details: v.details ?? null,
description: v.description ?? null
};
}
/** Legacy `GET product/color` — options for variant color dropdown. */
colors() {
return Object.entries(exports2.VARIANT_COLORS).map(([id, title]) => ({
id: Number(id),
title
}));
}
/** Legacy `POST get/variants` — a POST that reads, per legacy's own routing. */
async listVariants(query) {
this.table.assertNotExport(query);
@@ -98898,6 +98928,10 @@ var require_admin_products_service = __commonJS({
qty: Number(v.qty ?? 0),
isPreOrder: Boolean(v.is_pre_order),
isActive: v.is_active !== void 0 ? Boolean(v.is_active) : true,
color: v.color !== void 0 && v.color !== null && v.color !== "" ? Number(v.color) : null,
rialWage: v.rial_pay !== void 0 && v.rial_pay !== null && v.rial_pay !== "" ? new client_1.Prisma.Decimal(String(v.rial_pay)) : null,
details: v.details ? String(v.details) : null,
description: v.description ? String(v.description) : null,
imageId
};
}
@@ -99300,6 +99334,9 @@ var require_admin_products_controller = __commonJS({
createVariant(body) {
return this.products.createVariant(body);
}
colors() {
return this.products.colors();
}
showTypeOptions() {
return this.products.showTypeOptions();
}
@@ -99375,6 +99412,13 @@ var require_admin_products_controller = __commonJS({
__metadata3("design:paramtypes", [Object]),
__metadata3("design:returntype", void 0)
], AdminProductsController.prototype, "createVariant", null);
__decorate4([
(0, common_12.Get)("colors"),
(0, guards_1.RequirePermission)("product.list"),
__metadata3("design:type", Function),
__metadata3("design:paramtypes", []),
__metadata3("design:returntype", void 0)
], AdminProductsController.prototype, "colors", null);
__decorate4([
(0, common_12.Get)("show-type-options"),
(0, guards_1.RequirePermission)("product.list"),
@@ -0,0 +1,5 @@
-- AlterTable: Add legacy variant fields (color, rialWage, details, description)
ALTER TABLE "ProductVariant" ADD COLUMN IF NOT EXISTS "color" INTEGER;
ALTER TABLE "ProductVariant" ADD COLUMN IF NOT EXISTS "rialWage" DECIMAL(18,0);
ALTER TABLE "ProductVariant" ADD COLUMN IF NOT EXISTS "details" TEXT;
ALTER TABLE "ProductVariant" ADD COLUMN IF NOT EXISTS "description" TEXT;
File diff suppressed because one or more lines are too long
@@ -327,6 +327,10 @@ exports.Prisma.ProductVariantScalarFieldEnum = {
qty: 'qty',
isPreOrder: 'isPreOrder',
isActive: 'isActive',
color: 'color',
rialWage: 'rialWage',
details: 'details',
description: 'description',
imageId: 'imageId'
};
+204
View File
@@ -23372,12 +23372,16 @@ export namespace Prisma {
rashWeightGrams: Decimal | null
defaultWagePercent: Decimal | null
qty: number | null
color: number | null
rialWage: Decimal | null
}
export type ProductVariantSumAggregateOutputType = {
rashWeightGrams: Decimal | null
defaultWagePercent: Decimal | null
qty: number | null
color: number | null
rialWage: Decimal | null
}
export type ProductVariantMinAggregateOutputType = {
@@ -23390,6 +23394,10 @@ export namespace Prisma {
qty: number | null
isPreOrder: boolean | null
isActive: boolean | null
color: number | null
rialWage: Decimal | null
details: string | null
description: string | null
imageId: string | null
}
@@ -23403,6 +23411,10 @@ export namespace Prisma {
qty: number | null
isPreOrder: boolean | null
isActive: boolean | null
color: number | null
rialWage: Decimal | null
details: string | null
description: string | null
imageId: string | null
}
@@ -23416,6 +23428,10 @@ export namespace Prisma {
qty: number
isPreOrder: number
isActive: number
color: number
rialWage: number
details: number
description: number
imageId: number
_all: number
}
@@ -23425,12 +23441,16 @@ export namespace Prisma {
rashWeightGrams?: true
defaultWagePercent?: true
qty?: true
color?: true
rialWage?: true
}
export type ProductVariantSumAggregateInputType = {
rashWeightGrams?: true
defaultWagePercent?: true
qty?: true
color?: true
rialWage?: true
}
export type ProductVariantMinAggregateInputType = {
@@ -23443,6 +23463,10 @@ export namespace Prisma {
qty?: true
isPreOrder?: true
isActive?: true
color?: true
rialWage?: true
details?: true
description?: true
imageId?: true
}
@@ -23456,6 +23480,10 @@ export namespace Prisma {
qty?: true
isPreOrder?: true
isActive?: true
color?: true
rialWage?: true
details?: true
description?: true
imageId?: true
}
@@ -23469,6 +23497,10 @@ export namespace Prisma {
qty?: true
isPreOrder?: true
isActive?: true
color?: true
rialWage?: true
details?: true
description?: true
imageId?: true
_all?: true
}
@@ -23569,6 +23601,10 @@ export namespace Prisma {
qty: number
isPreOrder: boolean
isActive: boolean
color: number | null
rialWage: Decimal | null
details: string | null
description: string | null
imageId: string | null
_count: ProductVariantCountAggregateOutputType | null
_avg: ProductVariantAvgAggregateOutputType | null
@@ -23601,6 +23637,10 @@ export namespace Prisma {
qty?: boolean
isPreOrder?: boolean
isActive?: boolean
color?: boolean
rialWage?: boolean
details?: boolean
description?: boolean
imageId?: boolean
product?: boolean | ProductDefaultArgs<ExtArgs>
image?: boolean | ProductVariant$imageArgs<ExtArgs>
@@ -23618,6 +23658,10 @@ export namespace Prisma {
qty?: boolean
isPreOrder?: boolean
isActive?: boolean
color?: boolean
rialWage?: boolean
details?: boolean
description?: boolean
imageId?: boolean
product?: boolean | ProductDefaultArgs<ExtArgs>
image?: boolean | ProductVariant$imageArgs<ExtArgs>
@@ -23633,6 +23677,10 @@ export namespace Prisma {
qty?: boolean
isPreOrder?: boolean
isActive?: boolean
color?: boolean
rialWage?: boolean
details?: boolean
description?: boolean
imageId?: boolean
}
@@ -23678,6 +23726,22 @@ export namespace Prisma {
*/
isPreOrder: boolean
isActive: boolean
/**
* Legacy color enum: 0=سفید, 1=زرد, 2=شکلاتی, 3=رزگلد
*/
color: number | null
/**
* Legacy rial_pay — fixed Rial making charge per variant.
*/
rialWage: Prisma.Decimal | null
/**
* Legacy details — short description for variant.
*/
details: string | null
/**
* Legacy description — full description for variant.
*/
description: string | null
/**
* The gallery image shown for this variant, picked from its own product's
* images — never a re-uploaded copy. onDelete: SetNull because dropping an
@@ -24090,6 +24154,10 @@ export namespace Prisma {
readonly qty: FieldRef<"ProductVariant", 'Int'>
readonly isPreOrder: FieldRef<"ProductVariant", 'Boolean'>
readonly isActive: FieldRef<"ProductVariant", 'Boolean'>
readonly color: FieldRef<"ProductVariant", 'Int'>
readonly rialWage: FieldRef<"ProductVariant", 'Decimal'>
readonly details: FieldRef<"ProductVariant", 'String'>
readonly description: FieldRef<"ProductVariant", 'String'>
readonly imageId: FieldRef<"ProductVariant", 'String'>
}
@@ -50956,6 +51024,10 @@ export namespace Prisma {
qty: 'qty',
isPreOrder: 'isPreOrder',
isActive: 'isActive',
color: 'color',
rialWage: 'rialWage',
details: 'details',
description: 'description',
imageId: 'imageId'
};
@@ -53121,6 +53193,10 @@ export namespace Prisma {
qty?: IntFilter<"ProductVariant"> | number
isPreOrder?: BoolFilter<"ProductVariant"> | boolean
isActive?: BoolFilter<"ProductVariant"> | boolean
color?: IntNullableFilter<"ProductVariant"> | number | null
rialWage?: DecimalNullableFilter<"ProductVariant"> | Decimal | DecimalJsLike | number | string | null
details?: StringNullableFilter<"ProductVariant"> | string | null
description?: StringNullableFilter<"ProductVariant"> | string | null
imageId?: StringNullableFilter<"ProductVariant"> | string | null
product?: XOR<ProductRelationFilter, ProductWhereInput>
image?: XOR<ProductImageNullableRelationFilter, ProductImageWhereInput> | null
@@ -53137,6 +53213,10 @@ export namespace Prisma {
qty?: SortOrder
isPreOrder?: SortOrder
isActive?: SortOrder
color?: SortOrderInput | SortOrder
rialWage?: SortOrderInput | SortOrder
details?: SortOrderInput | SortOrder
description?: SortOrderInput | SortOrder
imageId?: SortOrderInput | SortOrder
product?: ProductOrderByWithRelationInput
image?: ProductImageOrderByWithRelationInput
@@ -53156,6 +53236,10 @@ export namespace Prisma {
qty?: IntFilter<"ProductVariant"> | number
isPreOrder?: BoolFilter<"ProductVariant"> | boolean
isActive?: BoolFilter<"ProductVariant"> | boolean
color?: IntNullableFilter<"ProductVariant"> | number | null
rialWage?: DecimalNullableFilter<"ProductVariant"> | Decimal | DecimalJsLike | number | string | null
details?: StringNullableFilter<"ProductVariant"> | string | null
description?: StringNullableFilter<"ProductVariant"> | string | null
imageId?: StringNullableFilter<"ProductVariant"> | string | null
product?: XOR<ProductRelationFilter, ProductWhereInput>
image?: XOR<ProductImageNullableRelationFilter, ProductImageWhereInput> | null
@@ -53172,6 +53256,10 @@ export namespace Prisma {
qty?: SortOrder
isPreOrder?: SortOrder
isActive?: SortOrder
color?: SortOrderInput | SortOrder
rialWage?: SortOrderInput | SortOrder
details?: SortOrderInput | SortOrder
description?: SortOrderInput | SortOrder
imageId?: SortOrderInput | SortOrder
_count?: ProductVariantCountOrderByAggregateInput
_avg?: ProductVariantAvgOrderByAggregateInput
@@ -53193,6 +53281,10 @@ export namespace Prisma {
qty?: IntWithAggregatesFilter<"ProductVariant"> | number
isPreOrder?: BoolWithAggregatesFilter<"ProductVariant"> | boolean
isActive?: BoolWithAggregatesFilter<"ProductVariant"> | boolean
color?: IntNullableWithAggregatesFilter<"ProductVariant"> | number | null
rialWage?: DecimalNullableWithAggregatesFilter<"ProductVariant"> | Decimal | DecimalJsLike | number | string | null
details?: StringNullableWithAggregatesFilter<"ProductVariant"> | string | null
description?: StringNullableWithAggregatesFilter<"ProductVariant"> | string | null
imageId?: StringNullableWithAggregatesFilter<"ProductVariant"> | string | null
}
@@ -56695,6 +56787,10 @@ export namespace Prisma {
qty?: number
isPreOrder?: boolean
isActive?: boolean
color?: number | null
rialWage?: Decimal | DecimalJsLike | number | string | null
details?: string | null
description?: string | null
product: ProductCreateNestedOneWithoutVariantsInput
image?: ProductImageCreateNestedOneWithoutVariantsInput
orderItems?: OrderItemCreateNestedManyWithoutProductVariantInput
@@ -56710,6 +56806,10 @@ export namespace Prisma {
qty?: number
isPreOrder?: boolean
isActive?: boolean
color?: number | null
rialWage?: Decimal | DecimalJsLike | number | string | null
details?: string | null
description?: string | null
imageId?: string | null
orderItems?: OrderItemUncheckedCreateNestedManyWithoutProductVariantInput
}
@@ -56723,6 +56823,10 @@ export namespace Prisma {
qty?: IntFieldUpdateOperationsInput | number
isPreOrder?: BoolFieldUpdateOperationsInput | boolean
isActive?: BoolFieldUpdateOperationsInput | boolean
color?: NullableIntFieldUpdateOperationsInput | number | null
rialWage?: NullableDecimalFieldUpdateOperationsInput | Decimal | DecimalJsLike | number | string | null
details?: NullableStringFieldUpdateOperationsInput | string | null
description?: NullableStringFieldUpdateOperationsInput | string | null
product?: ProductUpdateOneRequiredWithoutVariantsNestedInput
image?: ProductImageUpdateOneWithoutVariantsNestedInput
orderItems?: OrderItemUpdateManyWithoutProductVariantNestedInput
@@ -56738,6 +56842,10 @@ export namespace Prisma {
qty?: IntFieldUpdateOperationsInput | number
isPreOrder?: BoolFieldUpdateOperationsInput | boolean
isActive?: BoolFieldUpdateOperationsInput | boolean
color?: NullableIntFieldUpdateOperationsInput | number | null
rialWage?: NullableDecimalFieldUpdateOperationsInput | Decimal | DecimalJsLike | number | string | null
details?: NullableStringFieldUpdateOperationsInput | string | null
description?: NullableStringFieldUpdateOperationsInput | string | null
imageId?: NullableStringFieldUpdateOperationsInput | string | null
orderItems?: OrderItemUncheckedUpdateManyWithoutProductVariantNestedInput
}
@@ -56752,6 +56860,10 @@ export namespace Prisma {
qty?: number
isPreOrder?: boolean
isActive?: boolean
color?: number | null
rialWage?: Decimal | DecimalJsLike | number | string | null
details?: string | null
description?: string | null
imageId?: string | null
}
@@ -56764,6 +56876,10 @@ export namespace Prisma {
qty?: IntFieldUpdateOperationsInput | number
isPreOrder?: BoolFieldUpdateOperationsInput | boolean
isActive?: BoolFieldUpdateOperationsInput | boolean
color?: NullableIntFieldUpdateOperationsInput | number | null
rialWage?: NullableDecimalFieldUpdateOperationsInput | Decimal | DecimalJsLike | number | string | null
details?: NullableStringFieldUpdateOperationsInput | string | null
description?: NullableStringFieldUpdateOperationsInput | string | null
}
export type ProductVariantUncheckedUpdateManyInput = {
@@ -56776,6 +56892,10 @@ export namespace Prisma {
qty?: IntFieldUpdateOperationsInput | number
isPreOrder?: BoolFieldUpdateOperationsInput | boolean
isActive?: BoolFieldUpdateOperationsInput | boolean
color?: NullableIntFieldUpdateOperationsInput | number | null
rialWage?: NullableDecimalFieldUpdateOperationsInput | Decimal | DecimalJsLike | number | string | null
details?: NullableStringFieldUpdateOperationsInput | string | null
description?: NullableStringFieldUpdateOperationsInput | string | null
imageId?: NullableStringFieldUpdateOperationsInput | string | null
}
@@ -60196,6 +60316,10 @@ export namespace Prisma {
qty?: SortOrder
isPreOrder?: SortOrder
isActive?: SortOrder
color?: SortOrder
rialWage?: SortOrder
details?: SortOrder
description?: SortOrder
imageId?: SortOrder
}
@@ -60203,6 +60327,8 @@ export namespace Prisma {
rashWeightGrams?: SortOrder
defaultWagePercent?: SortOrder
qty?: SortOrder
color?: SortOrder
rialWage?: SortOrder
}
export type ProductVariantMaxOrderByAggregateInput = {
@@ -60215,6 +60341,10 @@ export namespace Prisma {
qty?: SortOrder
isPreOrder?: SortOrder
isActive?: SortOrder
color?: SortOrder
rialWage?: SortOrder
details?: SortOrder
description?: SortOrder
imageId?: SortOrder
}
@@ -60228,6 +60358,10 @@ export namespace Prisma {
qty?: SortOrder
isPreOrder?: SortOrder
isActive?: SortOrder
color?: SortOrder
rialWage?: SortOrder
details?: SortOrder
description?: SortOrder
imageId?: SortOrder
}
@@ -60235,6 +60369,8 @@ export namespace Prisma {
rashWeightGrams?: SortOrder
defaultWagePercent?: SortOrder
qty?: SortOrder
color?: SortOrder
rialWage?: SortOrder
}
export type EnumOrderChannelFilter<$PrismaModel = never> = {
@@ -70906,6 +71042,10 @@ export namespace Prisma {
qty?: number
isPreOrder?: boolean
isActive?: boolean
color?: number | null
rialWage?: Decimal | DecimalJsLike | number | string | null
details?: string | null
description?: string | null
image?: ProductImageCreateNestedOneWithoutVariantsInput
orderItems?: OrderItemCreateNestedManyWithoutProductVariantInput
}
@@ -70919,6 +71059,10 @@ export namespace Prisma {
qty?: number
isPreOrder?: boolean
isActive?: boolean
color?: number | null
rialWage?: Decimal | DecimalJsLike | number | string | null
details?: string | null
description?: string | null
imageId?: string | null
orderItems?: OrderItemUncheckedCreateNestedManyWithoutProductVariantInput
}
@@ -71186,6 +71330,10 @@ export namespace Prisma {
qty?: IntFilter<"ProductVariant"> | number
isPreOrder?: BoolFilter<"ProductVariant"> | boolean
isActive?: BoolFilter<"ProductVariant"> | boolean
color?: IntNullableFilter<"ProductVariant"> | number | null
rialWage?: DecimalNullableFilter<"ProductVariant"> | Decimal | DecimalJsLike | number | string | null
details?: StringNullableFilter<"ProductVariant"> | string | null
description?: StringNullableFilter<"ProductVariant"> | string | null
imageId?: StringNullableFilter<"ProductVariant"> | string | null
}
@@ -71362,6 +71510,10 @@ export namespace Prisma {
qty?: number
isPreOrder?: boolean
isActive?: boolean
color?: number | null
rialWage?: Decimal | DecimalJsLike | number | string | null
details?: string | null
description?: string | null
product: ProductCreateNestedOneWithoutVariantsInput
orderItems?: OrderItemCreateNestedManyWithoutProductVariantInput
}
@@ -71376,6 +71528,10 @@ export namespace Prisma {
qty?: number
isPreOrder?: boolean
isActive?: boolean
color?: number | null
rialWage?: Decimal | DecimalJsLike | number | string | null
details?: string | null
description?: string | null
orderItems?: OrderItemUncheckedCreateNestedManyWithoutProductVariantInput
}
@@ -72631,6 +72787,10 @@ export namespace Prisma {
qty?: number
isPreOrder?: boolean
isActive?: boolean
color?: number | null
rialWage?: Decimal | DecimalJsLike | number | string | null
details?: string | null
description?: string | null
product: ProductCreateNestedOneWithoutVariantsInput
image?: ProductImageCreateNestedOneWithoutVariantsInput
}
@@ -72645,6 +72805,10 @@ export namespace Prisma {
qty?: number
isPreOrder?: boolean
isActive?: boolean
color?: number | null
rialWage?: Decimal | DecimalJsLike | number | string | null
details?: string | null
description?: string | null
imageId?: string | null
}
@@ -72726,6 +72890,10 @@ export namespace Prisma {
qty?: IntFieldUpdateOperationsInput | number
isPreOrder?: BoolFieldUpdateOperationsInput | boolean
isActive?: BoolFieldUpdateOperationsInput | boolean
color?: NullableIntFieldUpdateOperationsInput | number | null
rialWage?: NullableDecimalFieldUpdateOperationsInput | Decimal | DecimalJsLike | number | string | null
details?: NullableStringFieldUpdateOperationsInput | string | null
description?: NullableStringFieldUpdateOperationsInput | string | null
product?: ProductUpdateOneRequiredWithoutVariantsNestedInput
image?: ProductImageUpdateOneWithoutVariantsNestedInput
}
@@ -72740,6 +72908,10 @@ export namespace Prisma {
qty?: IntFieldUpdateOperationsInput | number
isPreOrder?: BoolFieldUpdateOperationsInput | boolean
isActive?: BoolFieldUpdateOperationsInput | boolean
color?: NullableIntFieldUpdateOperationsInput | number | null
rialWage?: NullableDecimalFieldUpdateOperationsInput | Decimal | DecimalJsLike | number | string | null
details?: NullableStringFieldUpdateOperationsInput | string | null
description?: NullableStringFieldUpdateOperationsInput | string | null
imageId?: NullableStringFieldUpdateOperationsInput | string | null
}
@@ -79534,6 +79706,10 @@ export namespace Prisma {
qty?: number
isPreOrder?: boolean
isActive?: boolean
color?: number | null
rialWage?: Decimal | DecimalJsLike | number | string | null
details?: string | null
description?: string | null
imageId?: string | null
}
@@ -79596,6 +79772,10 @@ export namespace Prisma {
qty?: IntFieldUpdateOperationsInput | number
isPreOrder?: BoolFieldUpdateOperationsInput | boolean
isActive?: BoolFieldUpdateOperationsInput | boolean
color?: NullableIntFieldUpdateOperationsInput | number | null
rialWage?: NullableDecimalFieldUpdateOperationsInput | Decimal | DecimalJsLike | number | string | null
details?: NullableStringFieldUpdateOperationsInput | string | null
description?: NullableStringFieldUpdateOperationsInput | string | null
image?: ProductImageUpdateOneWithoutVariantsNestedInput
orderItems?: OrderItemUpdateManyWithoutProductVariantNestedInput
}
@@ -79609,6 +79789,10 @@ export namespace Prisma {
qty?: IntFieldUpdateOperationsInput | number
isPreOrder?: BoolFieldUpdateOperationsInput | boolean
isActive?: BoolFieldUpdateOperationsInput | boolean
color?: NullableIntFieldUpdateOperationsInput | number | null
rialWage?: NullableDecimalFieldUpdateOperationsInput | Decimal | DecimalJsLike | number | string | null
details?: NullableStringFieldUpdateOperationsInput | string | null
description?: NullableStringFieldUpdateOperationsInput | string | null
imageId?: NullableStringFieldUpdateOperationsInput | string | null
orderItems?: OrderItemUncheckedUpdateManyWithoutProductVariantNestedInput
}
@@ -79622,6 +79806,10 @@ export namespace Prisma {
qty?: IntFieldUpdateOperationsInput | number
isPreOrder?: BoolFieldUpdateOperationsInput | boolean
isActive?: BoolFieldUpdateOperationsInput | boolean
color?: NullableIntFieldUpdateOperationsInput | number | null
rialWage?: NullableDecimalFieldUpdateOperationsInput | Decimal | DecimalJsLike | number | string | null
details?: NullableStringFieldUpdateOperationsInput | string | null
description?: NullableStringFieldUpdateOperationsInput | string | null
imageId?: NullableStringFieldUpdateOperationsInput | string | null
}
@@ -79789,6 +79977,10 @@ export namespace Prisma {
qty?: number
isPreOrder?: boolean
isActive?: boolean
color?: number | null
rialWage?: Decimal | DecimalJsLike | number | string | null
details?: string | null
description?: string | null
}
export type ProductVariantUpdateWithoutImageInput = {
@@ -79800,6 +79992,10 @@ export namespace Prisma {
qty?: IntFieldUpdateOperationsInput | number
isPreOrder?: BoolFieldUpdateOperationsInput | boolean
isActive?: BoolFieldUpdateOperationsInput | boolean
color?: NullableIntFieldUpdateOperationsInput | number | null
rialWage?: NullableDecimalFieldUpdateOperationsInput | Decimal | DecimalJsLike | number | string | null
details?: NullableStringFieldUpdateOperationsInput | string | null
description?: NullableStringFieldUpdateOperationsInput | string | null
product?: ProductUpdateOneRequiredWithoutVariantsNestedInput
orderItems?: OrderItemUpdateManyWithoutProductVariantNestedInput
}
@@ -79814,6 +80010,10 @@ export namespace Prisma {
qty?: IntFieldUpdateOperationsInput | number
isPreOrder?: BoolFieldUpdateOperationsInput | boolean
isActive?: BoolFieldUpdateOperationsInput | boolean
color?: NullableIntFieldUpdateOperationsInput | number | null
rialWage?: NullableDecimalFieldUpdateOperationsInput | Decimal | DecimalJsLike | number | string | null
details?: NullableStringFieldUpdateOperationsInput | string | null
description?: NullableStringFieldUpdateOperationsInput | string | null
orderItems?: OrderItemUncheckedUpdateManyWithoutProductVariantNestedInput
}
@@ -79827,6 +80027,10 @@ export namespace Prisma {
qty?: IntFieldUpdateOperationsInput | number
isPreOrder?: BoolFieldUpdateOperationsInput | boolean
isActive?: BoolFieldUpdateOperationsInput | boolean
color?: NullableIntFieldUpdateOperationsInput | number | null
rialWage?: NullableDecimalFieldUpdateOperationsInput | Decimal | DecimalJsLike | number | string | null
details?: NullableStringFieldUpdateOperationsInput | string | null
description?: NullableStringFieldUpdateOperationsInput | string | null
}
export type OrderItemCreateManyProductVariantInput = {
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name": "prisma-client-2865f0245bc905fafa9ec2b299c03c4ad7a157188246b5449e2f920f2b3a6c3d",
"name": "prisma-client-8945b25ad1891f9eaff8d38ca7f3c1b19a3f2d11c0c8521549c219186ff7566b",
"main": "index.js",
"types": "index.d.ts",
"browser": "index-browser.js",
+9
View File
@@ -728,6 +728,15 @@ model ProductVariant {
isPreOrder Boolean @default(false)
isActive Boolean @default(true)
/// Legacy color enum: 0=سفید, 1=زرد, 2=شکلاتی, 3=رزگلد
color Int?
/// Legacy rial_pay — fixed Rial making charge per variant.
rialWage Decimal? @db.Decimal(18, 0)
/// Legacy details — short description for variant.
details String? @db.Text
/// Legacy description — full description for variant.
description String? @db.Text
/// The gallery image shown for this variant, picked from its own product's
/// images — never a re-uploaded copy. onDelete: SetNull because dropping an
/// image must never cascade into the variant: OrderItem rows reference
+4
View File
@@ -327,6 +327,10 @@ exports.Prisma.ProductVariantScalarFieldEnum = {
qty: 'qty',
isPreOrder: 'isPreOrder',
isActive: 'isActive',
color: 'color',
rialWage: 'rialWage',
details: 'details',
description: 'description',
imageId: 'imageId'
};
@@ -73,6 +73,12 @@ export class AdminProductsController {
return this.products.createVariant(body);
}
@Get('colors')
@RequirePermission('product.list')
colors() {
return this.products.colors();
}
@Get('show-type-options')
@RequirePermission('product.list')
showTypeOptions() {
@@ -20,6 +20,13 @@ const SHOW_TYPE_LABELS: Record<number, string> = {
3: 'سایت و گوشی',
};
export const VARIANT_COLORS: Record<number, string> = {
0: 'سفید',
1: 'زرد',
2: 'شکلاتی',
3: 'رزگلد',
};
@Injectable()
export class AdminProductsService {
constructor(
@@ -201,6 +208,7 @@ export class AdminProductsService {
}
private variantRow(v: Prisma.ProductVariantGetPayload<object> & { image?: { id: string; url: string } | null }) {
const colorNum = v.color != null ? Number(v.color) : null;
return {
id: v.id,
product_id_id: v.productId,
@@ -216,13 +224,22 @@ export class AdminProductsService {
// without a second lookup. Only populated where the query included it.
image_id: v.imageId,
image: v.image ? { id: v.image.id, url: v.image.url } : null,
// Legacy had a separate rial making-charge column; the schema models wage
// as a percentage only. Returned as null rather than faked.
rial_pay: null,
color_str: null,
color: colorNum,
color_str: colorNum != null ? (VARIANT_COLORS[colorNum] ?? null) : null,
rial_pay: v.rialWage != null ? Number(v.rialWage) : null,
details: v.details ?? null,
description: v.description ?? null,
};
}
/** Legacy `GET product/color` — options for variant color dropdown. */
colors() {
return Object.entries(VARIANT_COLORS).map(([id, title]) => ({
id: Number(id),
title,
}));
}
/** Legacy `POST get/variants` — a POST that reads, per legacy's own routing. */
async listVariants(query: TableQueryDto & { product_id?: string }) {
this.table.assertNotExport(query);
@@ -339,6 +356,13 @@ export class AdminProductsService {
qty: Number(v.qty ?? 0),
isPreOrder: Boolean(v.is_pre_order),
isActive: v.is_active !== undefined ? Boolean(v.is_active) : true,
color: v.color !== undefined && v.color !== null && v.color !== '' ? Number(v.color) : null,
rialWage:
v.rial_pay !== undefined && v.rial_pay !== null && v.rial_pay !== ''
? new Prisma.Decimal(String(v.rial_pay))
: null,
details: v.details ? String(v.details) : null,
description: v.description ? String(v.description) : null,
imageId,
};
}
@@ -225,6 +225,8 @@ export class CatalogService {
const stockBlocked = await this.accounting.stockBlocker();
const out = [];
const colorNames: Record<number, string> = { 0: 'سفید', 1: 'زرد', 2: 'شکلاتی', 3: 'رزگلد' };
for (const p of products) {
const { accountingStockWeight, accountingStockCount, accountingStockAt, ...product } = p;
// D27 — out of stock in the accounting software: every variant reads as
@@ -232,7 +234,22 @@ export class CatalogService {
// the cart unless it is a pre-order variant. The stock figures themselves
// stay server-side; this endpoint is public.
const blocked = stockBlocked({ accountingStockWeight, accountingStockCount, accountingStockAt });
out.push(blocked ? { ...product, variants: product.variants.map((v) => (v.isPreOrder ? v : { ...v, qty: 0 })) } : product);
const mappedVariants = product.variants.map((v) => {
const cNum = v.color != null ? Number(v.color) : null;
const color_str = cNum != null ? (colorNames[cNum] ?? null) : null;
const base = {
...v,
color: cNum,
color_str,
rial_pay: v.rialWage != null ? Number(v.rialWage) : null,
};
return blocked && !v.isPreOrder ? { ...base, qty: 0 } : base;
});
out.push({
...product,
variants: mappedVariants,
});
}
return out;
}