diff --git a/src/helper/enum-list.ts b/src/helper/enum-list.ts index 2ba4d88..8c29165 100644 --- a/src/helper/enum-list.ts +++ b/src/helper/enum-list.ts @@ -25,6 +25,8 @@ export enum coaType { EXPENSE, ACCOUNT_RECEIVABLE, ACCOUNT_PAYABLE, + BUDGET, + CONTRA_BUDGET, } export enum balanceType { diff --git a/src/product/dto/product/create-product.dto.ts b/src/product/dto/product/create-product.dto.ts index be1ab0c..74433dc 100644 --- a/src/product/dto/product/create-product.dto.ts +++ b/src/product/dto/product/create-product.dto.ts @@ -18,4 +18,7 @@ export class CreateProductDto { @IsUUID() subCategoriesId: string; + + @IsUUID() + supplierId: string; } diff --git a/src/product/entities/product-history-price.entity.ts b/src/product/entities/product-history-price.entity.ts index e50d22d..6abf098 100644 --- a/src/product/entities/product-history-price.entity.ts +++ b/src/product/entities/product-history-price.entity.ts @@ -2,6 +2,7 @@ import { Entity, Column, PrimaryGeneratedColumn, ManyToOne } from 'typeorm'; import { Product } from './product.entity'; import { BaseModel } from '../../config/basemodel.entity'; import { productType } from '../../helper/enum-list'; +import { User } from '../../users/entities/user.entity'; @Entity() export class ProductHistoryPrice extends BaseModel { @@ -11,6 +12,9 @@ export class ProductHistoryPrice extends BaseModel { @ManyToOne(() => Product, (product) => product.id) product: Product; + @ManyToOne(() => User, (user) => user.id) + user: User; + @Column() price: number; diff --git a/src/product/entities/product.entity.ts b/src/product/entities/product.entity.ts index 982fa3b..cc2241f 100644 --- a/src/product/entities/product.entity.ts +++ b/src/product/entities/product.entity.ts @@ -11,6 +11,7 @@ import { } from 'typeorm'; import { ProductSubCategories } from './product-sub-category.entity'; import { BaseModel } from '../../config/basemodel.entity'; +import { Supplier } from '../../users/entities/supplier.entity'; @Entity() export class Product extends BaseModel { @@ -43,4 +44,14 @@ export class Product extends BaseModel { }, ) sub_categories: ProductSubCategories; + + @ManyToOne( + () => { + return Supplier; + }, + (partner) => { + return partner.id; + }, + ) + supplier: Supplier; } diff --git a/src/transaction/coa.service.ts b/src/transaction/coa.service.ts index d828f5f..33beffc 100644 --- a/src/transaction/coa.service.ts +++ b/src/transaction/coa.service.ts @@ -1,4 +1,10 @@ -import { forwardRef, HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; +import { + forwardRef, + HttpException, + HttpStatus, + Inject, + Injectable, +} from '@nestjs/common'; import { EntityNotFoundError, Repository } from 'typeorm'; import { InjectRepository } from '@nestjs/typeorm'; import { COA } from './entities/coa.entity'; @@ -10,24 +16,40 @@ export class CoaService { constructor( @InjectRepository(COA) private coaRepository: Repository, - @Inject(forwardRef(() => UsersService)) + @Inject( + forwardRef(() => { + return UsersService; + }), + ) private userService: UsersService, ) {} async create(inputCoaDto: InputCoaDto) { - const user = inputCoaDto.user - let coaData = new COA(); - coaData.user = user.id; - coaData.name = coaType[inputCoaDto.type] + '-' + user.username; + const coaData = new COA(); + let name = ''; + if (inputCoaDto.user) { + coaData.user = inputCoaDto.user.id; + name = inputCoaDto.user.username; + } + + if (inputCoaDto.supplier) { + coaData.supplier = inputCoaDto.supplier.id; + name = inputCoaDto.supplier.code; + } + + coaData.name = `${coaType[inputCoaDto.type]}-${name}`; coaData.balanceType = inputCoaDto.balanceType; coaData.type = inputCoaDto.type; coaData.amount = 0; - const result = await inputCoaDto.coaEntityManager.insert(COA,coaData); + const result = await inputCoaDto.coaEntityManager.insert(COA, coaData); - if(inputCoaDto.type == coaType.ACCOUNT_RECEIVABLE || inputCoaDto.type == coaType.ACCOUNT_PAYABLE){ + if ( + inputCoaDto.type == coaType.ACCOUNT_RECEIVABLE || + inputCoaDto.type == coaType.ACCOUNT_PAYABLE + ) { coaData.relatedUser = inputCoaDto.relatedUserId; - await inputCoaDto.coaEntityManager.save(coaData) + await inputCoaDto.coaEntityManager.save(coaData); } return coaData; @@ -35,7 +57,10 @@ export class CoaService { async findByUser(id: string, typeOfCoa: coaType) { try { - return await this.coaRepository.findOneOrFail({ user: id, type: typeOfCoa }); + return await this.coaRepository.findOneOrFail({ + user: id, + type: typeOfCoa, + }); } catch (e) { if (e instanceof EntityNotFoundError) { throw new HttpException( @@ -51,9 +76,17 @@ export class CoaService { } } - async findByUserWithRelated(id: string, relatedId: string, typeOfCoa: coaType) { + async findByUserWithRelated( + id: string, + relatedId: string, + typeOfCoa: coaType, + ) { try { - return await this.coaRepository.findOneOrFail({ user: id, type: typeOfCoa, relatedUser:relatedId }); + return await this.coaRepository.findOneOrFail({ + user: id, + type: typeOfCoa, + relatedUser: relatedId, + }); } catch (e) { if (e instanceof EntityNotFoundError) { throw new HttpException( diff --git a/src/transaction/dto/input-coa.dto.ts b/src/transaction/dto/input-coa.dto.ts index 5e068dc..b6c580d 100644 --- a/src/transaction/dto/input-coa.dto.ts +++ b/src/transaction/dto/input-coa.dto.ts @@ -2,6 +2,7 @@ import { IsNotEmpty, IsUUID } from 'class-validator'; import { balanceType, coaType } from 'src/helper/enum-list'; import { User } from 'src/users/entities/user.entity'; import { EntityManager } from 'typeorm'; +import { Supplier } from '../../users/entities/supplier.entity'; export class InputCoaDto { @IsUUID() @@ -16,6 +17,9 @@ export class InputCoaDto { @IsUUID() relatedUserId: string; + @IsUUID() + supplier: Supplier; + @IsNotEmpty() coaEntityManager: EntityManager; } diff --git a/src/transaction/entities/coa.entity.ts b/src/transaction/entities/coa.entity.ts index a463b68..b26ece3 100644 --- a/src/transaction/entities/coa.entity.ts +++ b/src/transaction/entities/coa.entity.ts @@ -1,7 +1,4 @@ -import { - Entity, - Column, -} from 'typeorm'; +import { Entity, Column } from 'typeorm'; import { BaseModel } from '../../config/basemodel.entity'; import { coaType, balanceType } from '../../helper/enum-list'; @@ -19,11 +16,18 @@ export class COA extends BaseModel { @Column() amount: number; - @Column() + @Column({ + nullable: true, + }) user: string; @Column({ - nullable:true + nullable: true, }) relatedUser: string; + + @Column({ + nullable: true, + }) + supplier: string; } diff --git a/src/transaction/entities/transaction-journal.entity.ts b/src/transaction/entities/transaction-journal.entity.ts index ad5ba0a..821fc71 100644 --- a/src/transaction/entities/transaction-journal.entity.ts +++ b/src/transaction/entities/transaction-journal.entity.ts @@ -9,7 +9,6 @@ import { import { BaseModel } from '../../config/basemodel.entity'; import { COA } from './coa.entity'; import { Transactions } from './transactions.entity'; -import { TransactionType } from './transaction-type.entity'; import { balanceType } from '../../helper/enum-list'; @Entity() diff --git a/src/transaction/entities/transaction-type.entity.ts b/src/transaction/entities/transaction-type.entity.ts deleted file mode 100644 index c146c85..0000000 --- a/src/transaction/entities/transaction-type.entity.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { - Entity, - Column, -} from 'typeorm'; -import { BaseModel } from '../../config/basemodel.entity'; - -@Entity() -export class TransactionType extends BaseModel { - @Column() - name: string; -} diff --git a/src/transaction/transaction.module.ts b/src/transaction/transaction.module.ts index 8b1f631..698ef2b 100644 --- a/src/transaction/transaction.module.ts +++ b/src/transaction/transaction.module.ts @@ -4,7 +4,6 @@ import { TransactionController } from './transaction.controller'; import { PpobCallbackController } from './ppob_callback.controller'; import { TypeOrmModule } from '@nestjs/typeorm'; import { COA } from './entities/coa.entity'; -import { TransactionType } from './entities/transaction-type.entity'; import { TransactionJournal } from './entities/transaction-journal.entity'; import { Transactions } from './entities/transactions.entity'; import { CoaService } from './coa.service'; @@ -13,17 +12,12 @@ import { UsersModule } from 'src/users/users.module'; @Module({ imports: [ - TypeOrmModule.forFeature([ - TransactionType, - COA, - TransactionJournal, - Transactions, - ]), + TypeOrmModule.forFeature([COA, TransactionJournal, Transactions]), ProductModule, forwardRef(() => UsersModule), ], controllers: [TransactionController, PpobCallbackController], providers: [TransactionService, CoaService], - exports:[CoaService] + exports: [CoaService], }) export class TransactionModule {} diff --git a/src/transaction/transaction.service.ts b/src/transaction/transaction.service.ts index 9e818f9..17769fd 100644 --- a/src/transaction/transaction.service.ts +++ b/src/transaction/transaction.service.ts @@ -5,7 +5,6 @@ import { InjectRepository } from '@nestjs/typeorm'; import { Transactions } from './entities/transactions.entity'; import { Connection, EntityManager, Repository } from 'typeorm'; import { COA } from './entities/coa.entity'; -import { TransactionType } from './entities/transaction-type.entity'; import { TransactionJournal } from './entities/transaction-journal.entity'; import { CoaService } from './coa.service'; import * as uuid from 'uuid'; @@ -34,8 +33,6 @@ export class TransactionService { constructor( @InjectRepository(Transactions) private transactionRepository: Repository, - @InjectRepository(TransactionType) - private transactionTypeRepository: Repository, @InjectRepository(TransactionJournal) private transactionJournalRepository: Repository, @InjectRepository(COA) diff --git a/src/users/dto/create-partner.dto.ts b/src/users/dto/create-partner.dto.ts new file mode 100644 index 0000000..b4acc45 --- /dev/null +++ b/src/users/dto/create-partner.dto.ts @@ -0,0 +1,15 @@ +import { IsNotEmpty } from 'class-validator'; + +export class CreatePartnerDto { + @IsNotEmpty() + name: string; + + @IsNotEmpty() + address: string; + + @IsNotEmpty() + owner: string; + + @IsNotEmpty() + npwp: string; +} diff --git a/src/users/dto/create-supplier.dto.ts b/src/users/dto/create-supplier.dto.ts new file mode 100644 index 0000000..8a2e585 --- /dev/null +++ b/src/users/dto/create-supplier.dto.ts @@ -0,0 +1,9 @@ +import { IsNotEmpty } from 'class-validator'; + +export class CreateSupplierDto { + @IsNotEmpty() + name: string; + + @IsNotEmpty() + code: string; +} diff --git a/src/users/entities/partner.entity.ts b/src/users/entities/supplier.entity.ts similarity index 77% rename from src/users/entities/partner.entity.ts rename to src/users/entities/supplier.entity.ts index 8ff03d9..080c04c 100644 --- a/src/users/entities/partner.entity.ts +++ b/src/users/entities/supplier.entity.ts @@ -4,10 +4,16 @@ import { BaseModel } from '../../config/basemodel.entity'; import { hashPassword } from '../../helper/hash_password'; @Entity() -export class User extends BaseModel { +export class Supplier extends BaseModel { @PrimaryGeneratedColumn('uuid') id: string; @Column() name: string; + + @Column() + code: string; + + @Column() + status: boolean; } diff --git a/src/users/supplier.service.spec.ts b/src/users/supplier.service.spec.ts new file mode 100644 index 0000000..9eb9cce --- /dev/null +++ b/src/users/supplier.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { SupplierService } from './supplier.service'; + +describe('PartnerService', () => { + let service: SupplierService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [SupplierService], + }).compile(); + + service = module.get(SupplierService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/users/supplier.service.ts b/src/users/supplier.service.ts new file mode 100644 index 0000000..a5ccbcf --- /dev/null +++ b/src/users/supplier.service.ts @@ -0,0 +1,114 @@ +import { + forwardRef, + HttpException, + HttpStatus, + Inject, + Injectable, +} from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Connection, EntityNotFoundError, Repository } from 'typeorm'; +import { Supplier } from './entities/supplier.entity'; +import { InputCoaDto } from '../transaction/dto/input-coa.dto'; +import { balanceType, coaType } from '../helper/enum-list'; +import { CreateSupplierDto } from './dto/create-supplier.dto'; +import { CoaService } from '../transaction/coa.service'; +import * as uuid from 'uuid'; + +@Injectable() +export class SupplierService { + constructor( + @InjectRepository(Supplier) + private supplierRepository: Repository, + @Inject( + forwardRef(() => { + return CoaService; + }), + ) + private coaService: CoaService, + private connection: Connection, + ) {} + + async create(createSupplierDto: CreateSupplierDto) { + const check = await this.supplierRepository.findOne({ + code: createSupplierDto.code, + }); + + if (check) { + throw new HttpException( + { + statusCode: HttpStatus.NOT_ACCEPTABLE, + error: 'Supplier Already Exist', + }, + HttpStatus.NOT_FOUND, + ); + } + + const supplierData = new Supplier(); + supplierData.id = uuid.v4(); + supplierData.name = createSupplierDto.name; + supplierData.code = createSupplierDto.code; + supplierData.status = true; + + await this.connection.transaction(async (manager) => { + const result = await manager.insert(Supplier, supplierData); + + const dataCoaInventory = new InputCoaDto(); + dataCoaInventory.supplier = supplierData; + dataCoaInventory.balanceType = balanceType.DEBIT; + dataCoaInventory.type = coaType.INVENTORY; + dataCoaInventory.coaEntityManager = manager; + await this.coaService.create(dataCoaInventory); + + const dataCoaCostOfSales = new InputCoaDto(); + dataCoaCostOfSales.supplier = supplierData; + dataCoaCostOfSales.balanceType = balanceType.DEBIT; + dataCoaCostOfSales.type = coaType.COST_OF_SALES; + dataCoaCostOfSales.coaEntityManager = manager; + await this.coaService.create(dataCoaCostOfSales); + + const dataCoaBudget = new InputCoaDto(); + dataCoaBudget.supplier = supplierData; + dataCoaBudget.balanceType = balanceType.DEBIT; + dataCoaBudget.type = coaType.BUDGET; + dataCoaBudget.coaEntityManager = manager; + await this.coaService.create(dataCoaBudget); + + const dataCoaContraBudget = new InputCoaDto(); + dataCoaContraBudget.supplier = supplierData; + dataCoaContraBudget.balanceType = balanceType.CREDIT; + dataCoaContraBudget.type = coaType.CONTRA_BUDGET; + dataCoaContraBudget.coaEntityManager = manager; + await this.coaService.create(dataCoaContraBudget); + }); + + return supplierData; + } + + findAllSupplier(page) { + return this.supplierRepository.findAndCount({ + skip: page * 10, + take: 10, + order: { + version: 'DESC', + }, + }); + } + + async findOne(id: string) { + try { + return await this.supplierRepository.findOneOrFail(id); + } catch (e) { + if (e instanceof EntityNotFoundError) { + throw new HttpException( + { + statusCode: HttpStatus.NOT_FOUND, + error: 'Data not found', + }, + HttpStatus.NOT_FOUND, + ); + } else { + throw e; + } + } + } +} diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index addb15e..7980740 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -15,13 +15,18 @@ import { UsersService } from './users.service'; import { CreateUserDto } from './dto/create-user.dto'; import { UpdateUserDto } from './dto/update-user.dto'; import { Public } from '../auth/public.decorator'; +import { CreateSupplierDto } from './dto/create-supplier.dto'; +import { SupplierService } from './supplier.service'; @Controller({ path: 'users', version: '1', }) export class UsersController { - constructor(private readonly usersService: UsersService) {} + constructor( + private readonly usersService: UsersService, + private readonly supplierService: SupplierService, + ) {} @Post() async create(@Request() req, @Body() createUserDto: CreateUserDto) { @@ -32,6 +37,15 @@ export class UsersController { }; } + @Post('supplier') + async createPartner(@Body() createPartnerDto: CreateSupplierDto) { + return { + data: await this.supplierService.create(createPartnerDto), + statusCode: HttpStatus.CREATED, + message: 'success', + }; + } + @Public() @Get() async findAll(@Query('page') page: number) { diff --git a/src/users/users.module.ts b/src/users/users.module.ts index c9ef16d..637a6ea 100644 --- a/src/users/users.module.ts +++ b/src/users/users.module.ts @@ -5,11 +5,17 @@ import { UsersController } from './users.controller'; import { User } from './entities/user.entity'; import { TransactionModule } from 'src/transaction/transaction.module'; import { ConfigurableModule } from 'src/configurable/configurable.module'; +import { SupplierService } from './supplier.service'; +import { Supplier } from './entities/supplier.entity'; @Module({ - imports: [TypeOrmModule.forFeature([User]), forwardRef(() => TransactionModule), ConfigurableModule], + imports: [ + TypeOrmModule.forFeature([User, Supplier]), + forwardRef(() => TransactionModule), + ConfigurableModule, + ], controllers: [UsersController], - providers: [UsersService], + providers: [UsersService, SupplierService], exports: [UsersService], }) export class UsersModule {}