diff --git a/src/offers/dto/buy-carbon.dto.ts b/src/offers/dto/buy-carbon.dto.ts new file mode 100644 index 0000000..8974bbc --- /dev/null +++ b/src/offers/dto/buy-carbon.dto.ts @@ -0,0 +1,17 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsString, IsNumber } from 'class-validator'; +export class BuyCarbonDto { + @ApiProperty({ + description: 'offer id', + example: 'fk3jof83jdo3eiqeir', + }) + @IsString() + id: string; + + @ApiProperty({ + description: 'amount', + example: 20, + }) + @IsNumber() + amount: number; +} diff --git a/src/offers/dto/create-offer.dto.ts b/src/offers/dto/create-offer.dto.ts index 8240075..6256d33 100644 --- a/src/offers/dto/create-offer.dto.ts +++ b/src/offers/dto/create-offer.dto.ts @@ -1 +1,57 @@ -export class CreateOfferDto {} +import { ApiProperty } from '@nestjs/swagger'; +import { + IsString, + IsDate, + IsNumber, + IsObject, + IsUrl, + IsPositive, + isNotEmpty, +} from 'class-validator'; +import { Project } from '@/projects/schemas/project.schema'; + +export class CreateOfferDto { + @ApiProperty({ + description: 'Offer Name', + example: 'ปลูกต้นไม้100ล้านต้น', + }) + @IsString() + name: string; + + @ApiProperty({ + description: 'Offer description', + example: 'ปลูกต้นไม่กับพี่ตูน', + }) + @IsString() + description: string; + + @ApiProperty({ + description: 'Project Reference', + example: 'ปลูกต้นไม่กับพี่ตูน', + }) + @IsString() + project_id: String; + + @ApiProperty({ + description: 'Carbon credit sell price', + example: 50, + }) + @IsNumber() + @IsPositive() + price_per_kg: number; + + @ApiProperty({ + description: 'Offer image', + example: 'img_path', + }) + @IsUrl() + image: string; + + @ApiProperty({ + description: 'how much this offer cab sell', + example: 10000, + }) + @IsNumber() + @IsPositive() + avaliable: number; +} diff --git a/src/offers/offers.controller.ts b/src/offers/offers.controller.ts index 087013d..109ed19 100644 --- a/src/offers/offers.controller.ts +++ b/src/offers/offers.controller.ts @@ -10,14 +10,24 @@ import { import { OffersService } from './offers.service'; import { CreateOfferDto } from './dto/create-offer.dto'; import { UpdateOfferDto } from './dto/update-offer.dto'; - +import { GetUser } from '@/common/decorators/get-user.decorator'; +import { ApiTags, ApiBearerAuth } from '@nestjs/swagger'; +import { JwtGuard } from '@/common/guards/jwt.guard'; +import { Role } from '@/common/enums/role.enum'; +import { UseGuards } from '@nestjs/common'; +import { Roles } from '@/common/decorators/roles.decorator'; +import { RolesGuard } from '@/common/guards/roles.guard'; +@ApiTags('Offers') +@ApiBearerAuth() @Controller('offers') export class OffersController { constructor(private readonly offersService: OffersService) {} @Post() - create(@Body() createOfferDto: CreateOfferDto) { - return this.offersService.create(createOfferDto); + @UseGuards(JwtGuard, RolesGuard) + @Roles(Role.Provider, Role.Admin) + create(@Body() createOfferDto: CreateOfferDto, @GetUser() user) { + return this.offersService.create(createOfferDto, user); } @Get() @@ -26,8 +36,8 @@ export class OffersController { } @Get(':id') - findOne(@Param('id') id: string) { - return this.offersService.findOne(+id); + async findOne(@Param('id') id: string) { + return this.offersService.findOne(id); } @Patch(':id') diff --git a/src/offers/offers.module.ts b/src/offers/offers.module.ts index 6de076f..4dfe16b 100644 --- a/src/offers/offers.module.ts +++ b/src/offers/offers.module.ts @@ -1,8 +1,14 @@ import { Module } from '@nestjs/common'; import { OffersService } from './offers.service'; import { OffersController } from './offers.controller'; - +import { MongooseModule } from '@nestjs/mongoose'; +import { Offer, OfferSchema } from './schemas/offer.schema'; +import { ProjectsModule } from '@/projects/projects.module'; @Module({ + imports: [ + MongooseModule.forFeature([{ name: Offer.name, schema: OfferSchema }]), + ProjectsModule, + ], controllers: [OffersController], providers: [OffersService], }) diff --git a/src/offers/offers.service.ts b/src/offers/offers.service.ts index 6b97689..a5153a2 100644 --- a/src/offers/offers.service.ts +++ b/src/offers/offers.service.ts @@ -1,19 +1,51 @@ import { Injectable } from '@nestjs/common'; import { CreateOfferDto } from './dto/create-offer.dto'; import { UpdateOfferDto } from './dto/update-offer.dto'; - +import { OfferDocument } from './schemas/offer.schema'; +import { InjectModel } from '@nestjs/mongoose'; +import { Model } from 'mongoose'; +import { Offer } from './entities/offer.entity'; +import { BuyCarbonDto } from './dto/buy-carbon.dto'; +import { Project, ProjectDocument } from '@/projects/schemas/project.schema'; +import { ProjectsService } from '@/projects/projects.service'; +import { Inject } from '@nestjs/common'; @Injectable() export class OffersService { - create(createOfferDto: CreateOfferDto) { - return 'This action adds a new offer'; + @Inject(ProjectsService) + private readonly projectsService: ProjectsService; + + constructor( + @InjectModel(Offer.name) private offerModel: Model, //@InjectModel(Project.name) private projectModel: Model, + ) {} + + async create(createOfferDto: CreateOfferDto, user) { + return await this.offerModel.create({ + ...createOfferDto, + owner: user._id, + }); + } + + async findAll() { + return await this.offerModel.find({}); } - findAll() { - return `This action returns all offers`; + async buyCarbon(buyCarbonDto: BuyCarbonDto, user) { + const offer = await this.offerModel.findById(buyCarbonDto.id); + if (offer.available < buyCarbonDto.amount) { + throw new Error('Not enough carbon available'); + } + const project = await this.projectsService.findOne(offer.project); + console.log(project); + // offer.available -= buyCarbonDto.amount; + // offer.save(); + // return await this.offerModel.create({ + // ...buyCarbonDto, + // owner: user._id, + // }); } - findOne(id: number) { - return `This action returns a #${id} offer`; + async findOne(id: string) { + return await this.offerModel.findById(id); } update(id: number, updateOfferDto: UpdateOfferDto) { diff --git a/src/offers/schemas/offer.schema.ts b/src/offers/schemas/offer.schema.ts index 129214a..ad678fe 100644 --- a/src/offers/schemas/offer.schema.ts +++ b/src/offers/schemas/offer.schema.ts @@ -1,29 +1,38 @@ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; -import { HydratedDocument, Document } from 'mongoose'; +import { HydratedDocument, Document, Types } from 'mongoose'; +import { User } from '@/users/schemas/user.schema'; +import { Project } from '@/projects/schemas/project.schema'; export type OfferDocument = Offer & HydratedDocument; -export interface TimePeriod { - start: Date; - end: Date; -} - -export interface Contract { - name: string; - email: string; - tel: number; -} - @Schema() export class Offer extends Document { @Prop({ required: true }) - type: string; + name: string; @Prop({ required: true }) - owner: string; + description: string; @Prop({ required: true }) - _id: string; + project: string; + + @Prop({ required: false, type: Types.ObjectId, ref: 'User' }) + owner: User; + + @Prop({ default: 50 }) + price_per_kg: number; + + @Prop({ required: true }) + image: string; + + @Prop({ default: 420 }) + available: number; + + @Prop({ default: Date.now }) + createdAt: Date; + + @Prop({ default: Date.now }) + updatedAt: Date; } export const OfferSchema = SchemaFactory.createForClass(Offer); diff --git a/src/projects/projects.controller.ts b/src/projects/projects.controller.ts index 79d6697..e314679 100644 --- a/src/projects/projects.controller.ts +++ b/src/projects/projects.controller.ts @@ -76,11 +76,6 @@ export class ProjectsController { } } - @Patch(':id') - update(@Param('id') id: string, @Body() updateProjectDto: UpdateProjectDto) { - return this.projectsService.update(+id, updateProjectDto); - } - @Delete(':id') @UseGuards(JwtGuard, RolesGuard) @Roles(Role.Provider, Role.Admin) diff --git a/src/projects/projects.module.ts b/src/projects/projects.module.ts index e537790..5155e6d 100644 --- a/src/projects/projects.module.ts +++ b/src/projects/projects.module.ts @@ -9,5 +9,6 @@ import { Project, ProjectSchema } from './schemas/project.schema'; ], controllers: [ProjectsController], providers: [ProjectsService], + exports: [ProjectsService], }) export class ProjectsModule {} diff --git a/src/projects/projects.service.ts b/src/projects/projects.service.ts index fc6eaaa..ca64f27 100644 --- a/src/projects/projects.service.ts +++ b/src/projects/projects.service.ts @@ -78,8 +78,6 @@ export class ProjectsService { } } - async findMember(id: string) {} - async findOne(id: string) { const projectExits = await this.projectModel.findById(id).exec(); if (projectExits) { @@ -87,10 +85,6 @@ export class ProjectsService { } } - update(id: number, updateProjectDto: UpdateProjectDto) { - return `This action updates a #${id} project`; - } - async remove(id: string) { //todo return await this.projectModel.findByIdAndDelete(id).exec();