Files
psp_api/prisma/seed.ts
T
ahasani ad470d2166 feat: add stock keeping unit management with create, update, and retrieval functionalities
- Implemented CreateStockKeepingUnitDto for creating stock keeping units.
- Added StockKeepingUnitsService for handling business logic related to stock keeping units.
- Created StockKeepingUnitsController to manage HTTP requests for stock keeping units.
- Developed UpdateStockKeepingUnitDto for updating existing stock keeping units.
- Introduced StockKeepingUnitsServiceFindAllResponseDto for response structure.
- Established stock keeping units module for encapsulation of related components.

feat: enhance sales invoice fiscal management with new endpoints

- Created SalesInvoicesFilterDto for filtering sales invoices.
- Implemented PosSalesInvoiceFiscalController for managing fiscal operations on sales invoices.
- Developed PosSalesInvoiceFiscalService to handle fiscal logic and interactions.
- Added methods for sending, retrying, and checking the status of fiscal invoices.
- Integrated error handling and response mapping for fiscal operations.
2026-05-01 19:43:59 +03:30

610 lines
18 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { PasswordUtil } from '@/common/utils/password.util'
import { generateTrackingCode } from '@/common/utils/tracking-code-generator.util'
import {
ConsumerType,
GoodPricingModel,
PartnerFiscalSwitchType,
} from '@/generated/prisma/enums'
import { GoodCreateManyInput } from '@/generated/prisma/models'
import { prisma } from '../src/lib/prisma'
async function main() {
const password = await PasswordUtil.hash('123456')
await prisma.$transaction(async tx => {
const adminUser = await tx.admin.upsert({
where: {
mobile_number: '09120258156',
},
update: {},
create: {
first_name: 'عباس',
last_name: 'حسنی',
national_code: '0016022289',
mobile_number: '09120258156',
accounts: {
create: {
account: {
create: {
username: 'superAdmin',
password,
type: 'ADMIN',
status: 'ACTIVE',
},
},
},
},
},
})
const measureUnits = await tx.measureUnits.createMany({
data: [
{ code: '1', name: 'لنگه' },
{ code: '2', name: 'ثوب' },
{ code: '3', name: 'عدل' },
{ code: '4', name: 'نیم دوجین' },
{ code: '5', name: 'جعبه' },
{ code: '6', name: 'قرقره' },
{ code: '7', name: 'توپ' },
{ code: '8', name: 'کیلوگرم' },
{ code: '9', name: 'ست' },
{ code: '10', name: 'بطری' },
{ code: '11', name: 'دست' },
{ code: '12', name: 'برگ' },
{ code: '13', name: 'کارتن' },
{ code: '14', name: 'سطل' },
{ code: '15', name: 'عدد' },
{ code: '16', name: 'ورق' },
{ code: '17', name: 'بسته' },
{ code: '18', name: 'شاخه' },
{ code: '19', name: 'پاکت' },
{ code: '20', name: 'قوطی' },
{ code: '21', name: 'دستگاه' },
{ code: '22', name: 'جلد' },
{ code: '23', name: 'تخته' },
{ code: '24', name: 'تیوب' },
{ code: '25', name: 'رول' },
{ code: '26', name: 'متر' },
{ code: '27', name: 'طاقه' },
{ code: '28', name: 'کلاف' },
{ code: '29', name: 'جفت' },
{ code: '30', name: 'کیسه' },
{ code: '31', name: 'متر مربع' },
{ code: '32', name: 'طغرا' },
{ code: '33', name: 'پالت' },
{ code: '34', name: 'بشکه' },
{ code: '35', name: 'دوجین' },
{ code: '36', name: 'گالن' },
{ code: '37', name: '(رینگ)حلقه' },
{ code: '38', name: 'فاقد بسته بندی' },
{ code: '39', name: 'قراص' },
{ code: '40', name: 'کارتن' },
{ code: '41', name: 'قراصه' },
{ code: '42', name: 'صفحه' },
{ code: '43', name: 'لیتر' },
{ code: '44', name: 'مخزن' },
{ code: '45', name: 'ساشه' },
{ code: '46', name: 'تانکر' },
{ code: '47', name: 'کپسول' },
{ code: '48', name: 'دبه' },
{ code: '49', name: 'بندیل' },
{ code: '50', name: 'سبد' },
{ code: '51', name: '(رول)حلقه' },
{ code: '52', name: 'تن' },
{ code: '53', name: 'قالب' },
{ code: '54', name: 'بانکه' },
{ code: '55', name: 'شانه' },
{ code: '56', name: 'سیلندر' },
{ code: '57', name: 'متر مکعب' },
{ code: '58', name: 'فوت مربع' },
{ code: '59', name: 'حلب' },
{ code: '60', name: 'شیت' },
{ code: '61', name: 'چلیک' },
{ code: '62', name: 'جام' },
{ code: '63', name: 'گرم' },
{ code: '64', name: 'نخ' },
{ code: '65', name: 'شعله' },
{ code: '66', name: 'قیراط' },
{ code: '67', name: 'میلی لیتر' },
{ code: '68', name: 'میلی متر' },
{ code: '69', name: 'میلی گرم' },
{ code: '70', name: 'ساعت' },
{ code: '71', name: 'روز' },
{ code: '72', name: 'تن کیلومتر' },
{ code: '73', name: 'کیلووات ساعت' },
{ code: '74', name: 'نفر' },
{ code: '75', name: 'ثانیه' },
{ code: '76', name: 'دقیقه' },
{ code: '77', name: 'ماه' },
{ code: '78', name: 'سال' },
{ code: '79', name: 'قطعه' },
{ code: '80', name: 'سانتی متر' },
{ code: '81', name: 'سانتی متر مربع' },
{ code: '82', name: 'فروند' },
{ code: '83', name: 'واحد' },
{ code: '84', name: 'لیوان' },
{ code: '85', name: 'نوبت)`,' },
],
skipDuplicates: true,
})
// ****************** GUILD Start ****************** //
let guilds = await tx.guild.findMany()
if (!guilds.length) {
await tx.guild.createMany({
data: [
{
name: 'طلا',
code: 'Gold',
},
{
name: 'میوه و تره‌بار',
code: 'Fruit',
},
],
})
guilds = await tx.guild.findMany()
}
// ****************** GUILD Good Categories Start ****************** //
const goldGuild = await tx.guild.findFirst({
where: {
code: 'Gold',
},
})
const goldGuildId = goldGuild?.id
const goldGuildGoodCategories = await tx.goodCategory.findMany({
where: {
guild_id: goldGuildId,
is_default_guild_good: true,
},
})
if (!goldGuildGoodCategories?.length) {
const categoryFactory = (name: string) => ({
name,
guild_id: goldGuildId,
is_default_guild_good: true,
})
await tx.goodCategory.createMany({
data: [
categoryFactory('زیورآلات'),
// categoryFactory('طلا'),
// categoryFactory('سایر'),
// categoryFactory('سکه'),
// categoryFactory('شمش'),
// categoryFactory('شمش'),
],
})
}
const measureUnit = await tx.measureUnits.findFirst({
where: {
code: '63',
},
})
if (measureUnit) {
// ****************** GUILD Good Start ****************** //
async function goodFactory(
name: string,
categoryId: string,
pricingModel: GoodPricingModel,
sku_code: string,
measure_unit_code: string,
): Promise<GoodCreateManyInput | null> {
const sku = await tx.stockKeepingUnits.findUnique({
where: {
code: sku_code,
},
})
console.log(name)
console.log(sku?.id)
if (sku) {
return {
name,
category_id: categoryId,
pricing_model: pricingModel,
sku_id: sku.id,
measure_unit_id: measureUnit!.id,
is_default_guild_good: true,
}
}
return null
}
const zivarCategory = await tx.goodCategory.findFirst({
where: {
name: 'زیورآلات',
},
})
if (zivarCategory) {
const zivarGoods = await tx.good.count({
where: {
category_id: zivarCategory?.id,
},
})
if (!zivarGoods) {
const goodItems: GoodCreateManyInput[] = []
const preparedGoodItems = [
await goodFactory(
'آویز گردنبند طلا',
zivarCategory.id,
GoodPricingModel.GOLD,
'2720000044696',
'63',
),
await goodFactory(
'النگو',
zivarCategory.id,
GoodPricingModel.GOLD,
'2720000044665',
'63',
),
await goodFactory(
'انگشتر',
zivarCategory.id,
GoodPricingModel.GOLD,
'2720000044672',
'63',
),
await goodFactory(
'دست‌بند',
zivarCategory.id,
GoodPricingModel.GOLD,
'2720000044689',
'63',
),
await goodFactory(
'زنجیر',
zivarCategory.id,
GoodPricingModel.GOLD,
'2720000044702',
'63',
),
await goodFactory(
'سرویس',
zivarCategory.id,
GoodPricingModel.GOLD,
'2720000044733',
'63',
),
await goodFactory(
'گوشواره',
zivarCategory.id,
GoodPricingModel.GOLD,
'2720000044726',
'63',
),
].filter((item): item is GoodCreateManyInput => item !== null)
goodItems.push(...preparedGoodItems)
await tx.good.createMany({ data: goodItems })
}
}
// const goldCategory = await tx.goodCategory.findFirst({
// where: {
// name: 'طلا',
// },
// })
// if (goldCategory) {
// const goldGoods = await tx.good.count({
// where: {
// category_id: goldCategory?.id,
// },
// })
// if (!goldGoods) {
// const goodItems: GoodCreateInput[] = []
// goodItems.push(
// ...[
// goodFactory(
// 'طلای آب شده',
// goldCategory.id,
// GoodPricingModel.GOLD,
// UnitType.GRAM,
// ),
// goodFactory(
// 'طلای شکسته',
// goldCategory.id,
// GoodPricingModel.GOLD,
// UnitType.GRAM,
// ),
// goodFactory(
// 'طلای مستعمل',
// goldCategory.id,
// GoodPricingModel.GOLD,
// UnitType.GRAM,
// ),
// ],
// )
// await tx.good.createMany({ data: goodItems })
// }
// }
// const coinCategory = await tx.goodCategory.findFirst({
// where: {
// name: 'سکه',
// },
// })
// if (coinCategory) {
// const coinGoods = await tx.good.count({
// where: {
// category_id: coinCategory?.id,
// },
// })
// if (!coinGoods) {
// const goodItems: GoodCreateInput[] = []
// goodItems.push(
// ...[
// goodFactory(
// 'مسکوکات خارجی',
// coinCategory.id,
// GoodPricingModel.STANDARD,
// UnitType.COUNT,
// ),
// goodFactory(
// 'مسکوکات داخلی (پارسیان)',
// coinCategory.id,
// GoodPricingModel.STANDARD,
// UnitType.COUNT,
// ),
// goodFactory(
// 'تمام بهار آزادی (طرح جدید)',
// coinCategory.id,
// GoodPricingModel.STANDARD,
// UnitType.COUNT,
// ),
// goodFactory(
// 'تمام بهار آزادی (طرح قدیم)',
// coinCategory.id,
// GoodPricingModel.STANDARD,
// UnitType.COUNT,
// ),
// ],
// )
// await tx.good.createMany({ data: goodItems })
// }
// }
// const shemshCategory = await tx.goodCategory.findFirst({
// where: {
// name: 'شمش',
// },
// })
// if (shemshCategory) {
// const shemshGoods = await tx.good.count({
// where: {
// category_id: shemshCategory?.id,
// },
// })
// if (!shemshGoods) {
// await tx.good.create({
// data: goodFactory(
// 'شمش استاندارد',
// shemshCategory.id,
// GoodPricingModel.GOLD,
// UnitType.GRAM,
// ),
// })
// }
// }
}
// ****************** partner Start ****************** //
let partner = await tx.partner.findFirst()
let license = await tx.license.findFirst()
if (!partner) {
partner = await tx.partner.create({
data: {
name: 'تیس',
code: 'TIS',
status: 'ACTIVE',
fiscal_switch_type: PartnerFiscalSwitchType.NAMA,
accounts: {
create: {
role: 'OWNER',
account: {
create: {
username: 'tis',
password: await PasswordUtil.hash('123456'),
status: 'ACTIVE',
type: 'PARTNER',
},
},
},
},
},
})
}
if (partner && !license) {
await tx.$transaction(async tx => {
const startOfToday = new Date()
startOfToday.setHours(0, 0, 0, 0)
const month = startOfToday.getMonth()
let year = startOfToday.getFullYear()
let expMonth = month + 3
if (expMonth > 11) {
expMonth = expMonth - 11
year = year + 1
}
startOfToday.setFullYear(year)
startOfToday.setMonth(expMonth)
const transaction = await tx.licenseChargeTransaction.create({
data: {
activation_expires_at: startOfToday,
purchased_count: 1,
tracking_code: generateTrackingCode('LIC', 6),
partner: {
connect: {
id: partner.id,
},
},
},
select: {
id: true,
},
})
if (transaction)
license = await tx.license.create({
data: {
charge_transaction: {
connect: {
id: transaction.id,
},
},
},
})
})
}
// ****************** BA Start ****************** //
const ba = await tx.businessActivity.count()
if (!ba && license) {
const startOfToday = new Date()
startOfToday.setHours(0, 0, 0, 0)
let year = startOfToday.getFullYear()
let expYear = year + 1
// if (expMonth > 11) {
// expMonth = expMonth - 11
// year = year + 1
// }
startOfToday.setFullYear(expYear)
await tx.businessActivity.create({
data: {
name: 'طلا فروشی',
economic_code: '0111111111',
fiscal_id: '0111111111',
partner_token: 'TIS-BA-001',
license_activation: {
create: {
expires_at: startOfToday,
starts_at: new Date(),
license: {
connect: {
id: license.id,
},
},
},
},
consumer: {
create: {
type: ConsumerType.INDIVIDUAL,
individual: {
create: {
first_name: 'محمد',
last_name: 'زرگر',
mobile_number: '09120258155',
national_code: '1234567890',
partner: {
connect: {
id: partner.id,
},
},
},
},
accounts: {
create: {
role: 'OWNER',
account: {
create: {
username: 'zargar',
password: await PasswordUtil.hash('123456'),
status: 'ACTIVE',
type: 'CONSUMER',
},
},
},
},
},
},
guild: {
connect: {
id: guilds[0].id,
},
},
complexes: {
create: {
name: 'فروشگاه طلای مرکزی',
address: 'تهران، خیابان جمهوری',
branch_code: '12332',
// pos_list: {
// create: {
// name: 'لاین ۱',
// pos_type: POSType.WEB,
// status: 'ACTIVE',
// account: {
// create: {
// role: 'OPERATOR',
// account_allocation: {
// },
// account: {
// create: {
// username: 'line1',
// password: await PasswordUtil.hash('123456'),
// status: 'ACTIVE',
// type: 'CONSUMER',
// },
// },
// }
// }
// },
// },
},
},
},
})
}
// ****************** BA Start ****************** //
// ****************** provider Start ****************** //
const provider = await tx.provider.count()
if (!provider) {
await tx.provider.create({
data: {
name: 'توسن',
code: 'Tosan',
status: 'ACTIVE',
accounts: {
create: {
role: 'OWNER',
account: {
create: {
username: 'tosan',
password: await PasswordUtil.hash('123456'),
status: 'ACTIVE',
type: 'PROVIDER',
},
},
},
},
},
})
}
})
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async e => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})