Compare commits
No commits in common. "22d4306b2a24f5f245f148f645d2615d91aa46d2" and "f52cd5263edbd25978fea293de617c04ee5ab816" have entirely different histories.
22d4306b2a
...
f52cd5263e
|
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"nxConsole.generateAiAgentRules": true
|
|
||||||
}
|
|
||||||
|
|
@ -10,7 +10,6 @@ import { AppController } from './app.controller';
|
||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service';
|
||||||
import { LanguageController } from './language/language.controller';
|
import { LanguageController } from './language/language.controller';
|
||||||
import { I18nextModule } from './i18next/i18next.module';
|
import { I18nextModule } from './i18next/i18next.module';
|
||||||
import { ShopCategoryDocumentModule } from './shop-category-document/shop-category-document.module';
|
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
|
@ -29,7 +28,6 @@ import { ShopCategoryDocumentModule } from './shop-category-document/shop-catego
|
||||||
ShopCategoryModule,
|
ShopCategoryModule,
|
||||||
LanguageModule,
|
LanguageModule,
|
||||||
I18nextModule,
|
I18nextModule,
|
||||||
ShopCategoryDocumentModule,
|
|
||||||
],
|
],
|
||||||
controllers: [AppController, LanguageController],
|
controllers: [AppController, LanguageController],
|
||||||
providers: [AppService],
|
providers: [AppService],
|
||||||
|
|
|
||||||
|
|
@ -1,145 +1,67 @@
|
||||||
import { Inject, Injectable, NotFoundException, InternalServerErrorException } from '@nestjs/common';
|
import { Inject, Injectable, NotFoundException } from '@nestjs/common';
|
||||||
import { InjectModel } from '@nestjs/mongoose';
|
import { InjectModel } from '@nestjs/mongoose';
|
||||||
import { Model } from 'mongoose';
|
import { Model } from 'mongoose';
|
||||||
import { Language } from '../../schemas/language.schema';
|
import { Language } from '../../schemas/language.schema';
|
||||||
import { CreateLanguageDto, UpdateLanguageDto } from './dto/language.dto';
|
import { CreateLanguageDto, UpdateLanguageDto } from './dto/language.dto';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
import { I18nContext, I18nService } from 'nestjs-i18n';
|
||||||
import i18next from 'i18next';
|
import i18next from 'i18next';
|
||||||
|
|
||||||
export interface ApiResponse<T = any> {
|
|
||||||
success: boolean;
|
|
||||||
message: string;
|
|
||||||
data?: T | null;
|
|
||||||
errors?: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LanguageService {
|
export class LanguageService {
|
||||||
constructor(
|
constructor(@InjectModel(Language.name) private languageModel: Model<Language>,
|
||||||
@InjectModel(Language.name) private languageModel: Model<Language>,
|
@Inject('I18NEXT') private readonly i18n: typeof i18next) {}
|
||||||
@Inject('I18NEXT') private readonly i18n: typeof i18next
|
|
||||||
) {}
|
|
||||||
|
|
||||||
/** Create Language */
|
async create(
|
||||||
async create(createLanguageDto: CreateLanguageDto, lang: string): Promise<ApiResponse> {
|
createLanguageDto: CreateLanguageDto,lang:string): Promise<any> {
|
||||||
try {
|
const createdLanguage = new this.languageModel({
|
||||||
const createdLanguage = new this.languageModel({
|
...createLanguageDto,
|
||||||
...createLanguageDto,
|
ID: uuidv4(),
|
||||||
ID: uuidv4(),
|
Status: true,
|
||||||
Status: true,
|
createdAt: new Date(),
|
||||||
createdAt: new Date(),
|
updatedAt: new Date(),
|
||||||
updatedAt: new Date(),
|
});
|
||||||
});
|
const result = await createdLanguage.save();
|
||||||
const result = await createdLanguage.save();
|
console.log("language -----------------", await this.i18n.t('created', { lng: lang ,ns: 'language' }))
|
||||||
const message = await this.i18n.t('created', { lng: lang, ns: 'language' });
|
console.log("language -------sdadasd----------", lang)
|
||||||
|
return {
|
||||||
return { success: true, message, data: result };
|
success: true,
|
||||||
} catch (error) {
|
message: await this.i18n.t('created', { lng:lang }),
|
||||||
const message = await this.i18n.t('create_error', { lng: lang, ns: 'language' });
|
data: result,
|
||||||
return { success: false, message, errors: error.message };
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Find All Languages */
|
|
||||||
async findAll(lang: string): Promise<ApiResponse<Language[]>> {
|
|
||||||
try {
|
|
||||||
const result = await this.languageModel.find().exec();
|
|
||||||
const message = await this.i18n.t('retrieved_all', { lng: lang, ns: 'language' });
|
|
||||||
return { success: true, message, data: result };
|
|
||||||
} catch (error) {
|
|
||||||
const message = await this.i18n.t('retrieve_error', { lng: lang, ns: 'language' });
|
|
||||||
return { success: false, message, errors: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Find Active Languages */
|
|
||||||
async findActive(lang: string): Promise<ApiResponse<Language[]>> {
|
|
||||||
try {
|
|
||||||
const result = await this.languageModel.find({ Status: true }).exec();
|
|
||||||
const message = await this.i18n.t('retrieved_active', { lng: lang, ns: 'language' });
|
|
||||||
return { success: true, message, data: result };
|
|
||||||
} catch (error) {
|
|
||||||
const message = await this.i18n.t('retrieve_error', { lng: lang, ns: 'language' });
|
|
||||||
return { success: false, message, errors: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Toggle Status */
|
|
||||||
async toggleStatus(id: string, lang: string): Promise<ApiResponse<Language>> {
|
|
||||||
try {
|
|
||||||
const language = await this.languageModel.findOne({ ID: id }).exec();
|
|
||||||
if (!language) {
|
|
||||||
const message = await this.i18n.t('not_found', { lng: lang, ns: 'language' });
|
|
||||||
return { success: false, message, data: null };
|
|
||||||
}
|
|
||||||
|
|
||||||
language.Status = !language.Status;
|
|
||||||
const result = await language.save();
|
|
||||||
const message = await this.i18n.t('status_toggled', { lng: lang, ns: 'language' });
|
|
||||||
return { success: true, message, data: result };
|
|
||||||
} catch (error) {
|
|
||||||
const message = await this.i18n.t('update_error', { lng: lang, ns: 'language' });
|
|
||||||
return { success: false, message, errors: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Find One by ID */
|
|
||||||
async findOneWithID(id: string, lang: string): Promise<ApiResponse<any>> {
|
|
||||||
try {
|
|
||||||
const language = await this.languageModel.findOne({ ID: id }).exec();
|
|
||||||
if (!language) {
|
|
||||||
const message = await this.i18n.t('not_found', { lng: lang, ns: 'language' });
|
|
||||||
return { success: false, message, data: null };
|
|
||||||
}
|
|
||||||
const message = await this.i18n.t('retrieved', { lng: lang, ns: 'language' });
|
|
||||||
return { success: true, message, data: language };
|
|
||||||
} catch (error) {
|
|
||||||
const message = await this.i18n.t('retrieve_error', { lng: lang, ns: 'language' });
|
|
||||||
return { success: false, message, errors: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Find One by _id */
|
|
||||||
async findOneWithid(id: string, lang: string): Promise<ApiResponse<Language>> {
|
|
||||||
try {
|
|
||||||
const language = await this.languageModel.findOne({ _id: id }).exec();
|
|
||||||
if (!language) {
|
|
||||||
const message = await this.i18n.t('not_found', { lng: lang, ns: 'language' });
|
|
||||||
return { success: false, message, data: null };
|
|
||||||
}
|
|
||||||
const message = await this.i18n.t('retrieved', { lng: lang, ns: 'language' });
|
|
||||||
return { success: true, message, data: language };
|
|
||||||
} catch (error) {
|
|
||||||
const message = await this.i18n.t('retrieve_error', { lng: lang, ns: 'language' });
|
|
||||||
return { success: false, message, errors: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Update Language */
|
|
||||||
async updateLanguage(
|
|
||||||
id: string,
|
|
||||||
updateLanguageDto: UpdateLanguageDto,
|
|
||||||
lang: string
|
|
||||||
): Promise<ApiResponse<Language>> {
|
|
||||||
try {
|
|
||||||
const updatedLanguage = await this.languageModel
|
|
||||||
.findOneAndUpdate(
|
|
||||||
{ ID: id },
|
|
||||||
{ ...updateLanguageDto, updatedAt: new Date() },
|
|
||||||
{ new: true }
|
|
||||||
)
|
|
||||||
.exec();
|
|
||||||
|
|
||||||
if (!updatedLanguage) {
|
|
||||||
const message = await this.i18n.t('not_found', { lng: lang, ns: 'language' });
|
|
||||||
return { success: false, message, data: null };
|
|
||||||
}
|
|
||||||
|
|
||||||
const message = await this.i18n.t('updated', { lng: lang, ns: 'language' });
|
|
||||||
return { success: true, message, data: updatedLanguage };
|
|
||||||
} catch (error) {
|
|
||||||
const message = await this.i18n.t('update_error', { lng: lang, ns: 'language' });
|
|
||||||
return { success: false, message, errors: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async findAll(): Promise<Language[]> {
|
||||||
|
return this.languageModel.find().exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
async findOne(id: string): Promise<Language> {
|
||||||
|
const language = await this.languageModel.findOne({ ID: id }).exec();
|
||||||
|
if (!language) {
|
||||||
|
throw new NotFoundException(`Language with ID ${id} not found`);
|
||||||
|
}
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
|
||||||
|
async update(id: string, updateLanguageDto: UpdateLanguageDto): Promise<Language> {
|
||||||
|
const language = await this.languageModel
|
||||||
|
.findOneAndUpdate(
|
||||||
|
{ ID: id },
|
||||||
|
{ ...updateLanguageDto, updatedAt: new Date() },
|
||||||
|
{ new: true },
|
||||||
|
)
|
||||||
|
.exec();
|
||||||
|
|
||||||
|
if (!language) {
|
||||||
|
throw new NotFoundException(`Language with ID ${id} not found`);
|
||||||
|
}
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
|
||||||
|
async remove(id: string): Promise<void> {
|
||||||
|
const result = await this.languageModel.deleteOne({ ID: id }).exec();
|
||||||
|
if (result.deletedCount === 0) {
|
||||||
|
throw new NotFoundException(`Language with ID ${id} not found`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import { IsString, IsOptional, IsNumber, Min, Max, IsNotEmpty } from 'class-validator';
|
|
||||||
import { Types } from 'mongoose';
|
|
||||||
import { i18nValidationMessage } from 'nestjs-i18n';
|
|
||||||
import { IsMongoId } from 'class-validator';
|
|
||||||
|
|
||||||
export class CreateShopCategoryDocumentDto {
|
|
||||||
|
|
||||||
@IsString({ message: i18nValidationMessage('validation.isString') })
|
|
||||||
@IsNotEmpty({ message: i18nValidationMessage('validation.notEmpty') })
|
|
||||||
Name?: string;
|
|
||||||
|
|
||||||
|
|
||||||
@IsString({ message: i18nValidationMessage('validation.isString') })
|
|
||||||
@IsNotEmpty({ message: i18nValidationMessage('validation.notEmpty') })
|
|
||||||
Description?: string;
|
|
||||||
|
|
||||||
|
|
||||||
@IsString({ message: i18nValidationMessage('validation.isMongoId') })
|
|
||||||
@IsNotEmpty({ message: i18nValidationMessage('validation.notEmpty') })
|
|
||||||
ShopCategory?:string;
|
|
||||||
|
|
||||||
@IsString({ message: i18nValidationMessage('validation.isString') })
|
|
||||||
@IsNotEmpty({ message: i18nValidationMessage('validation.notEmpty') })
|
|
||||||
Language?: string
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
import { IsString, IsOptional, IsMongoId, IsNumber, Min, Max } from 'class-validator';
|
|
||||||
import { Types } from 'mongoose';
|
|
||||||
import { i18nValidationMessage } from 'nestjs-i18n';
|
|
||||||
|
|
||||||
export class UpdateShopCategoryDocumentDto {
|
|
||||||
@IsString({ message: i18nValidationMessage('validation.isString') })
|
|
||||||
@IsOptional()
|
|
||||||
Name?: string;
|
|
||||||
|
|
||||||
@IsString({ message: i18nValidationMessage('validation.isString') })
|
|
||||||
@IsOptional()
|
|
||||||
Description?: string;
|
|
||||||
|
|
||||||
@IsString({ message: i18nValidationMessage('validation.isMongoId') })
|
|
||||||
@IsOptional()
|
|
||||||
Language?: string;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
|
||||||
import { ShopCategoryDocumentController } from './shop-category-document.controller';
|
|
||||||
|
|
||||||
describe('ShopCategoryDocumentController', () => {
|
|
||||||
let controller: ShopCategoryDocumentController;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
|
||||||
controllers: [ShopCategoryDocumentController],
|
|
||||||
}).compile();
|
|
||||||
|
|
||||||
controller = module.get<ShopCategoryDocumentController>(
|
|
||||||
ShopCategoryDocumentController
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be defined', () => {
|
|
||||||
expect(controller).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
import { Controller } from '@nestjs/common';
|
|
||||||
|
|
||||||
@Controller('shop-category-document')
|
|
||||||
export class ShopCategoryDocumentController {}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
import { forwardRef, Module } from '@nestjs/common';
|
|
||||||
import { ShopCategoryDocumentService } from './shop-category-document.service';
|
|
||||||
import { ShopCategoryDocumentController } from './shop-category-document.controller';
|
|
||||||
import { MongooseModule } from '@nestjs/mongoose';
|
|
||||||
import { ShopCategoryDocument, ShopCategoryDocumentSchema } from '../../schemas/shopCategoryDocument';
|
|
||||||
import { ShopCategoryService } from '../shop-category/shop-category.service';
|
|
||||||
import { ShopCategoryModule } from '../shop-category/shop-category.module';
|
|
||||||
import { LanguageModule } from '../language/language.module';
|
|
||||||
|
|
||||||
@Module({
|
|
||||||
imports:[MongooseModule.forFeature([{ name:ShopCategoryDocument.name, schema:ShopCategoryDocumentSchema }]),
|
|
||||||
forwardRef(() => ShopCategoryModule),LanguageModule],
|
|
||||||
providers: [ShopCategoryDocumentService],
|
|
||||||
controllers: [ShopCategoryDocumentController],
|
|
||||||
})
|
|
||||||
export class ShopCategoryDocumentModule {}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
import { Test, TestingModule } from '@nestjs/testing';
|
|
||||||
import { ShopCategoryDocumentService } from './shop-category-document.service';
|
|
||||||
|
|
||||||
describe('ShopCategoryDocumentService', () => {
|
|
||||||
let service: ShopCategoryDocumentService;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
|
||||||
providers: [ShopCategoryDocumentService],
|
|
||||||
}).compile();
|
|
||||||
|
|
||||||
service = module.get<ShopCategoryDocumentService>(
|
|
||||||
ShopCategoryDocumentService
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be defined', () => {
|
|
||||||
expect(service).toBeDefined();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -1,129 +0,0 @@
|
||||||
import { forwardRef, Inject, Injectable } from '@nestjs/common';
|
|
||||||
import { InjectModel } from '@nestjs/mongoose';
|
|
||||||
import { ShopCategoryDoc } from '../../schemas/shopCategory.schema';
|
|
||||||
import { ShopCategoryDocument, ShopCategoryDocumentSchema } from '../../schemas/shopCategoryDocument';
|
|
||||||
import { Model } from 'mongoose';
|
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
|
||||||
import { I18nService } from 'nestjs-i18n';
|
|
||||||
import { CreateShopCategoryDocumentDto } from './dto/creat-shop-category-document.dto';
|
|
||||||
import { ApiResponse, LanguageService } from '../language/language.service';
|
|
||||||
import i18next from 'i18next';
|
|
||||||
import { UpdateShopCategoryDocumentDto } from './dto/update-shop-category-document.dto';
|
|
||||||
import { ShopCategoryService } from '../shop-category/shop-category.service';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class ShopCategoryDocumentService {
|
|
||||||
|
|
||||||
constructor(@InjectModel(ShopCategoryDocument.name) private shopCategoryDocumentModel: Model<ShopCategoryDoc>,
|
|
||||||
private readonly languageService: LanguageService,
|
|
||||||
@Inject(forwardRef(() => ShopCategoryService)) private readonly shopCategoryService: ShopCategoryService,
|
|
||||||
@Inject('I18NEXT') private readonly i18n: typeof i18next) { }
|
|
||||||
|
|
||||||
async create(
|
|
||||||
createShopCategoryDocumentDto: CreateShopCategoryDocumentDto,
|
|
||||||
lang: string
|
|
||||||
): Promise<ApiResponse> {
|
|
||||||
try {
|
|
||||||
// بررسی زبان
|
|
||||||
const language = await this.languageService.findOneWithID(
|
|
||||||
createShopCategoryDocumentDto.Language,
|
|
||||||
lang
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!language.success) {
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
message: await this.i18n.t('not_found', { lng: lang, ns: 'shopCategoryDocument' }),
|
|
||||||
data: null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const shopCategory = await this.shopCategoryService.findOne(createShopCategoryDocumentDto.ShopCategory, lang)
|
|
||||||
if (!shopCategory.success) {
|
|
||||||
return {
|
|
||||||
success: false,
|
|
||||||
message: await this.i18n.t('not_found', { lng: lang, ns: 'shopCategoryDocument' }),
|
|
||||||
data: null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const createdDoc = new this.shopCategoryDocumentModel({
|
|
||||||
Name: createShopCategoryDocumentDto.Name,
|
|
||||||
Description: createShopCategoryDocumentDto.Description,
|
|
||||||
Language: language.data._id,
|
|
||||||
ID: uuidv4(),
|
|
||||||
Status: true,
|
|
||||||
Tags: [],
|
|
||||||
ShopCategory: shopCategory.data._id,
|
|
||||||
createdAt: new Date(),
|
|
||||||
updatedAt: new Date(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await createdDoc.save();
|
|
||||||
|
|
||||||
const message = await this.i18n.t('created', { lng: lang, ns: 'shopCategoryDocument' });
|
|
||||||
|
|
||||||
return { success: true, message, data: result };
|
|
||||||
} catch (error) {
|
|
||||||
const message = await this.i18n.t('create_error', { lng: lang, ns: 'shopCategoryDocument' });
|
|
||||||
return { success: false, message, errors: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async update(
|
|
||||||
id: string,
|
|
||||||
updateShopCategoryDocumentDto: UpdateShopCategoryDocumentDto,
|
|
||||||
lang: string
|
|
||||||
): Promise<ApiResponse> {
|
|
||||||
try {
|
|
||||||
|
|
||||||
const existingDoc = await this.shopCategoryDocumentModel.findOne({ ID: id }).exec();
|
|
||||||
if (!existingDoc) {
|
|
||||||
const message = await this.i18n.t('not_found', { lng: lang, ns: 'shopCategoryDocument' });
|
|
||||||
return { success: false, message, data: null };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updateShopCategoryDocumentDto.Language) {
|
|
||||||
const language = await this.languageService.findOneWithID(updateShopCategoryDocumentDto.Language, 'en');
|
|
||||||
if (!language.success) {
|
|
||||||
const message = await this.i18n.t('not_found', { lng: lang, ns: 'shopCategoryDocument' });
|
|
||||||
return { success: false, message, data: null };
|
|
||||||
}
|
|
||||||
updateShopCategoryDocumentDto.Language = language.data._id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// آپدیت فیلدها
|
|
||||||
Object.assign(existingDoc, updateShopCategoryDocumentDto, { updatedAt: new Date() });
|
|
||||||
|
|
||||||
const updatedDoc = await existingDoc.save();
|
|
||||||
|
|
||||||
const message = await this.i18n.t('updated', { lng: lang, ns: 'shopCategoryDocument' });
|
|
||||||
return { success: true, message, data: updatedDoc };
|
|
||||||
} catch (error) {
|
|
||||||
const message = await this.i18n.t('update_error', { lng: lang, ns: 'shopCategoryDocument' });
|
|
||||||
return { success: false, message, errors: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async toggleStatus(
|
|
||||||
id: string,
|
|
||||||
lang: string
|
|
||||||
): Promise<ApiResponse> {
|
|
||||||
try {
|
|
||||||
const existingDoc = await this.shopCategoryDocumentModel.findOne({ ID: id }).exec();
|
|
||||||
if (!existingDoc) {
|
|
||||||
const message = await this.i18n.t('not_found', { lng: lang, ns: 'shopCategoryDocument' });
|
|
||||||
return { success: false, message, data: null };
|
|
||||||
}
|
|
||||||
existingDoc.Status = !existingDoc.Status;
|
|
||||||
existingDoc.updatedAt = new Date();
|
|
||||||
|
|
||||||
const updatedDoc = await existingDoc.save();
|
|
||||||
|
|
||||||
const message = await this.i18n.t('status_toggled', { lng: lang, ns: 'shopCategoryDocument' });
|
|
||||||
return { success: true, message, data: updatedDoc };
|
|
||||||
} catch (error) {
|
|
||||||
const message = await this.i18n.t('update_error', { lng: lang, ns: 'shopCategoryDocument' });
|
|
||||||
return { success: false, message, errors: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
import { IsString, IsOptional, IsNumber, Min, Max, IsNotEmpty } from 'class-validator';
|
import { IsString, IsOptional, IsNumber, IsNotEmpty } from 'class-validator';
|
||||||
import { Types } from 'mongoose';
|
import { Types } from 'mongoose';
|
||||||
import { i18nValidationMessage } from 'nestjs-i18n';
|
import { i18nValidationMessage } from 'nestjs-i18n';
|
||||||
import { IsMongoId } from 'class-validator';
|
import { IsMongoId } from 'class-validator';
|
||||||
|
|
||||||
export class CreateShopCategoryDto {
|
export class CreateShopCategoryDto {
|
||||||
@IsString({ message: i18nValidationMessage('validation.isString') })
|
@IsString({ message: i18nValidationMessage('validation.isString') })
|
||||||
@IsNotEmpty({ message: i18nValidationMessage('validation.notEmpty') })
|
@IsOptional()
|
||||||
@IsOptional()
|
|
||||||
Name?: string;
|
Name?: string;
|
||||||
|
|
||||||
@IsString({ message: i18nValidationMessage('validation.isString') })
|
@IsString({ message: i18nValidationMessage('validation.isString') })
|
||||||
|
|
@ -17,11 +16,15 @@ export class CreateShopCategoryDto {
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
Icon?: string;
|
Icon?: string;
|
||||||
|
|
||||||
|
@IsNumber({}, { message: i18nValidationMessage('validation.isNumber') })
|
||||||
|
@IsOptional()
|
||||||
|
Level?: number;
|
||||||
|
|
||||||
@IsMongoId({ message: i18nValidationMessage('validation.isMongoId') })
|
@IsMongoId({ message: i18nValidationMessage('validation.isMongoId') })
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
ParentCategory?: Types.ObjectId;
|
ParentCategory?: Types.ObjectId;
|
||||||
|
|
||||||
@IsString({ message: i18nValidationMessage('validation.isString') })
|
@IsMongoId({ message: i18nValidationMessage('validation.isMongoId') })
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
Language?: string
|
Language?: Types.ObjectId;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,12 @@
|
||||||
import { forwardRef, Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
import { ShopCategoryController } from './shop-category.controller';
|
import { ShopCategoryController } from './shop-category.controller';
|
||||||
import { ShopCategoryService } from './shop-category.service';
|
import { ShopCategoryService } from './shop-category.service';
|
||||||
import { MongooseModule } from '@nestjs/mongoose';
|
import { MongooseModule } from '@nestjs/mongoose';
|
||||||
import { ShopCategory, ShopCategorySchema } from '../../schemas/shopCategory.schema';
|
import { ShopCategory, ShopCategorySchema } from '../../schemas/shopCategory.schema';
|
||||||
import { LanguageModule } from '../language/language.module';
|
|
||||||
import { ShopCategoryDocument } from '../../schemas/shopCategoryDocument';
|
|
||||||
import { ShopCategoryDocumentModule } from '../shop-category-document/shop-category-document.module';
|
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
MongooseModule.forFeature([{ name: ShopCategory.name, schema: ShopCategorySchema }]),
|
MongooseModule.forFeature([{ name: ShopCategory.name, schema: ShopCategorySchema }]),
|
||||||
LanguageModule,forwardRef(() => ShopCategoryDocumentModule)
|
|
||||||
],
|
],
|
||||||
controllers: [ShopCategoryController],
|
controllers: [ShopCategoryController],
|
||||||
providers: [ShopCategoryService],
|
providers: [ShopCategoryService],
|
||||||
|
|
|
||||||
|
|
@ -1,126 +1,47 @@
|
||||||
import { forwardRef, Inject, Injectable } from '@nestjs/common';
|
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||||
import { InjectModel } from '@nestjs/mongoose';
|
import { InjectModel } from '@nestjs/mongoose';
|
||||||
import { Model } from 'mongoose';
|
import { Model } from 'mongoose';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { ShopCategory,ShopCategoryDoc } from '../../schemas/shopCategory.schema';
|
||||||
import { ShopCategory, ShopCategoryDoc } from '../../schemas/shopCategory.schema';
|
|
||||||
import { CreateShopCategoryDto } from './dto/create-shop-category.dto';
|
import { CreateShopCategoryDto } from './dto/create-shop-category.dto';
|
||||||
import { LanguageService, ApiResponse } from '../language/language.service';
|
import { I18n, I18nContext } from 'nestjs-i18n';
|
||||||
import { ShopCategoryDocumentService } from '../shop-category-document/shop-category-document.service';
|
|
||||||
import { I18nService } from 'nestjs-i18n';
|
|
||||||
import i18next from 'i18next';
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ShopCategoryService {
|
export class ShopCategoryService {
|
||||||
constructor(
|
constructor(
|
||||||
@InjectModel(ShopCategory.name) private shopCategoryModel: Model<ShopCategoryDoc>,
|
@InjectModel(ShopCategory.name) private shopCategoryModel: Model<ShopCategoryDoc>,
|
||||||
private readonly languageService: LanguageService,
|
|
||||||
private readonly shopCategoryDocumentService: ShopCategoryDocumentService,
|
|
||||||
@Inject('I18NEXT') private readonly i18n: typeof i18next
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async create(createShopCategoryDto: CreateShopCategoryDto, lang: string): Promise<ApiResponse> {
|
async create(createShopCategoryDto: CreateShopCategoryDto): Promise<any> {
|
||||||
try {
|
|
||||||
const language = await this.languageService.findOneWithID(createShopCategoryDto.Language, lang);
|
|
||||||
if (!language.success) {
|
|
||||||
return { success: false, message: await this.i18n.t('not_found', { lng: lang, ns: 'shopCategory' }), data: null };
|
|
||||||
}
|
|
||||||
|
|
||||||
let parent = null;
|
|
||||||
if (createShopCategoryDto.ParentCategory) {
|
|
||||||
parent = await this.shopCategoryModel.findOne({ ID: createShopCategoryDto.ParentCategory }).exec();
|
|
||||||
if (!parent) {
|
|
||||||
return { success: false, message: await this.i18n.t('parent_not_found', { lng: lang, ns: 'shopCategory' }), data: null };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const newShopCategory = new this.shopCategoryModel({
|
|
||||||
ID: uuidv4(),
|
|
||||||
Name: createShopCategoryDto.Name,
|
|
||||||
Description: createShopCategoryDto.Description,
|
|
||||||
Icon: createShopCategoryDto.Icon,
|
|
||||||
ParentCategory: parent ? parent._id : null,
|
|
||||||
Status: true,
|
|
||||||
Document: null,
|
|
||||||
createdAt: new Date(),
|
|
||||||
updatedAt: new Date(),
|
|
||||||
Tags: []
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await newShopCategory.save();
|
|
||||||
|
|
||||||
const createdDocument = await this.shopCategoryDocumentService.create(
|
|
||||||
{
|
|
||||||
Name: createShopCategoryDto.Name,
|
|
||||||
Description: createShopCategoryDto.Description,
|
|
||||||
Language: createShopCategoryDto.Language,
|
|
||||||
ShopCategory: result.ID
|
|
||||||
},
|
|
||||||
lang
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!createdDocument.success) {
|
|
||||||
return { success: false, message: createdDocument.message, data: null, errors: createdDocument.errors };
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.shopCategoryModel.updateOne(
|
|
||||||
{ _id: result._id },
|
|
||||||
{ $set: { Document: createdDocument.data._id } }
|
|
||||||
);
|
|
||||||
|
|
||||||
const message = await this.i18n.t('created', { lng: lang, ns: 'shopCategory' });
|
|
||||||
return { success: true, message, data: { ...result.toObject(), Document: createdDocument.data } };
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
const message = await this.i18n.t('create_error', { lng: lang, ns: 'shopCategory' });
|
|
||||||
return { success: false, message, errors: error.message };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async findAll(lang: string): Promise<ApiResponse> {
|
async findAll(): Promise<ShopCategory[]> {
|
||||||
try {
|
return this.shopCategoryModel.find()
|
||||||
const categories = await this.shopCategoryModel.find()
|
.populate('Tags')
|
||||||
.populate('Tags')
|
.populate('ParentCategory')
|
||||||
.populate('ParentCategory')
|
.populate('Document')
|
||||||
.populate('Document')
|
.exec();
|
||||||
.exec();
|
|
||||||
|
|
||||||
const message = await this.i18n.t('retrieved_all', { lng: lang, ns: 'shopCategory' });
|
|
||||||
return { success: true, message, data: categories };
|
|
||||||
} catch (error) {
|
|
||||||
const message = await this.i18n.t('retrieve_error', { lng: lang, ns: 'shopCategory' });
|
|
||||||
return { success: false, message, errors: error.message };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async findOne(id: string, lang: string): Promise<ApiResponse> {
|
async findOne(id: string): Promise<ShopCategory> {
|
||||||
try {
|
const category = await this.shopCategoryModel.findOne({ ID: id })
|
||||||
const category = await this.shopCategoryModel.findOne({ ID: id })
|
.populate('Tags')
|
||||||
.exec();
|
.populate('ParentCategory')
|
||||||
|
.populate('Document')
|
||||||
if (!category) {
|
.exec();
|
||||||
const message = await this.i18n.t('not_found', { lng: lang, ns: 'shopCategory' });
|
if (!category) {
|
||||||
return { success: false, message, data: null };
|
throw new NotFoundException(`ShopCategory with ID ${id} not found`);
|
||||||
}
|
|
||||||
|
|
||||||
const message = await this.i18n.t('retrieved', { lng: lang, ns: 'shopCategory' });
|
|
||||||
return { success: true, message, data: category };
|
|
||||||
} catch (error) {
|
|
||||||
const message = await this.i18n.t('retrieve_error', { lng: lang, ns: 'shopCategory' });
|
|
||||||
return { success: false, message, errors: error.message };
|
|
||||||
}
|
}
|
||||||
|
return category;
|
||||||
}
|
}
|
||||||
|
|
||||||
async remove(id: string, lang: string): Promise<ApiResponse> {
|
|
||||||
try {
|
async remove(id: string): Promise<void> {
|
||||||
const result = await this.shopCategoryModel.deleteOne({ ID: id }).exec();
|
const result = await this.shopCategoryModel.deleteOne({ ID: id }).exec();
|
||||||
if (result.deletedCount === 0) {
|
if (result.deletedCount === 0) {
|
||||||
const message = await this.i18n.t('not_found', { lng: lang, ns: 'shopCategory' });
|
throw new NotFoundException(`ShopCategory with ID ${id} not found`);
|
||||||
return { success: false, message, data: null };
|
|
||||||
}
|
|
||||||
const message = await this.i18n.t('deleted', { lng: lang, ns: 'shopCategory' });
|
|
||||||
return { success: true, message, data: null };
|
|
||||||
} catch (error) {
|
|
||||||
const message = await this.i18n.t('delete_error', { lng: lang, ns: 'shopCategory' });
|
|
||||||
return { success: false, message, errors: error.message };
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
export interface ApiResponse<T = any> {
|
|
||||||
success: boolean; // آیا عملیات موفق بوده یا نه
|
|
||||||
message: string; // پیام قابل نمایش به کاربر (ترجمه شده)
|
|
||||||
data?: T | null; // داده بازگشتی (در GET یا CREATE)
|
|
||||||
errors?: any; // جزئیات خطا (در صورت وجود)
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +1,3 @@
|
||||||
{
|
{
|
||||||
"created": "Language created successfully",
|
"created": "Language created successfully"
|
||||||
"create_error": "Error occurred while creating language",
|
}
|
||||||
"retrieved_all": "Languages retrieved successfully",
|
|
||||||
"retrieved_active": "Active languages retrieved successfully",
|
|
||||||
"retrieved": "Language retrieved successfully",
|
|
||||||
"retrieve_error": "Error occurred while retrieving language(s)",
|
|
||||||
"not_found": "Language not found",
|
|
||||||
"updated": "Language updated successfully",
|
|
||||||
"update_error": "Error occurred while updating language",
|
|
||||||
"deleted": "Language deleted successfully",
|
|
||||||
"delete_error": "Error occurred while deleting language",
|
|
||||||
"status_toggled": "Language status updated successfully"
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +1,3 @@
|
||||||
{
|
{
|
||||||
"created": "زبان با موفقیت ایجاد شد",
|
"created": "زبان با موفقیت ایجاد شد"
|
||||||
"create_error": "خطا در ایجاد زبان رخ داد",
|
}
|
||||||
"retrieved_all": "تمام زبانها با موفقیت دریافت شدند",
|
|
||||||
"retrieved_active": "زبانهای فعال با موفقیت دریافت شدند",
|
|
||||||
"retrieved": "زبان با موفقیت دریافت شد",
|
|
||||||
"retrieve_error": "خطا در دریافت زبانها رخ داد",
|
|
||||||
"not_found": "زبان مورد نظر پیدا نشد",
|
|
||||||
"updated": "زبان با موفقیت بروزرسانی شد",
|
|
||||||
"update_error": "خطا در بروزرسانی زبان رخ داد",
|
|
||||||
"deleted": "زبان با موفقیت حذف شد",
|
|
||||||
"delete_error": "خطا در حذف زبان رخ داد",
|
|
||||||
"status_toggled": "وضعیت زبان با موفقیت تغییر کرد"
|
|
||||||
}
|
|
||||||
|
|
@ -18,6 +18,9 @@ export class ShopCategory {
|
||||||
@Prop()
|
@Prop()
|
||||||
Icon: string;
|
Icon: string;
|
||||||
|
|
||||||
|
@Prop()
|
||||||
|
Level: number;
|
||||||
|
|
||||||
@Prop({ type: [{ type: Types.ObjectId, ref: 'Tag' }] })
|
@Prop({ type: [{ type: Types.ObjectId, ref: 'Tag' }] })
|
||||||
Tags: Types.ObjectId[];
|
Tags: Types.ObjectId[];
|
||||||
|
|
||||||
|
|
@ -28,7 +31,7 @@ export class ShopCategory {
|
||||||
Document: Types.ObjectId;
|
Document: Types.ObjectId;
|
||||||
|
|
||||||
@Prop()
|
@Prop()
|
||||||
Status: boolean;
|
Status: string;
|
||||||
|
|
||||||
@Prop({ type: Date, default: Date.now })
|
@Prop({ type: Date, default: Date.now })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ export class ShopCategoryDocument {
|
||||||
Tags: Types.ObjectId[];
|
Tags: Types.ObjectId[];
|
||||||
|
|
||||||
@Prop()
|
@Prop()
|
||||||
Status: boolean;
|
Status: string;
|
||||||
|
|
||||||
@Prop({ type: Types.ObjectId, ref: 'Language' })
|
@Prop({ type: Types.ObjectId, ref: 'Language' })
|
||||||
Language: Types.ObjectId;
|
Language: Types.ObjectId;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue