diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index e0212c1..78f8b4b 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -28,6 +28,7 @@ export class AuthService { username: user.username, sub: user.id, role: user.roles.name, + partner: user.partner.id, }; return { diff --git a/src/configurable/roles.service.ts b/src/configurable/roles.service.ts index 9404376..7147f1a 100644 --- a/src/configurable/roles.service.ts +++ b/src/configurable/roles.service.ts @@ -28,7 +28,7 @@ export class RoleService { throw new HttpException( { statusCode: HttpStatus.NOT_FOUND, - error: 'Data not found', + error: 'Data Role not found', }, HttpStatus.NOT_FOUND, ); diff --git a/src/transaction/transaction.service.ts b/src/transaction/transaction.service.ts index f831e16..3af4c7a 100644 --- a/src/transaction/transaction.service.ts +++ b/src/transaction/transaction.service.ts @@ -21,7 +21,7 @@ import * as irsService from '../helper/irs-service'; import { CreateJournalDto } from './dto/create-journal.dto'; import { UsersService } from 'src/users/users.service'; import { AddSaldoSupplier } from './dto/add-saldo-supplier.dto'; -import { SupplierService } from '../users/supplier.service'; +import { SupplierService } from '../users/supplier/supplier.service'; interface JournalEntry { coa_id: string; diff --git a/src/users/dto/create-partner.dto.ts b/src/users/dto/create-partner.dto.ts index b4acc45..2fbac10 100644 --- a/src/users/dto/create-partner.dto.ts +++ b/src/users/dto/create-partner.dto.ts @@ -12,4 +12,7 @@ export class CreatePartnerDto { @IsNotEmpty() npwp: string; + + @IsNotEmpty() + password_account: string; } diff --git a/src/users/dto/create-user.dto.ts b/src/users/dto/create-user.dto.ts index d9f00b8..122fd85 100644 --- a/src/users/dto/create-user.dto.ts +++ b/src/users/dto/create-user.dto.ts @@ -1,4 +1,5 @@ import { IsNotEmpty, IsOptional, IsUUID, ValidateIf } from 'class-validator'; +import { Partner } from '../entities/partner.entity'; export class CreateUserDto { @IsNotEmpty() @@ -13,6 +14,7 @@ export class CreateUserDto { @IsNotEmpty() superior: boolean; + partner: Partner; // @ValidateIf((o) => { // return !!o.superior; // }) diff --git a/src/users/entities/partner.entity.ts b/src/users/entities/partner.entity.ts new file mode 100644 index 0000000..9d2402b --- /dev/null +++ b/src/users/entities/partner.entity.ts @@ -0,0 +1,22 @@ +import { Roles } from 'src/configurable/entities/roles.entity'; +import { Entity, Column, PrimaryGeneratedColumn, ManyToOne } from 'typeorm'; +import { BaseModel } from '../../config/basemodel.entity'; +import { hashPassword } from '../../helper/hash_password'; + +@Entity() +export class Partner extends BaseModel { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column() + name: string; + + @Column() + npwp: string; + + @Column() + address: string; + + @Column({ default: true }) + status: boolean; +} diff --git a/src/users/entities/user.entity.ts b/src/users/entities/user.entity.ts index 5a121c6..89bc47f 100644 --- a/src/users/entities/user.entity.ts +++ b/src/users/entities/user.entity.ts @@ -2,6 +2,7 @@ import { Roles } from 'src/configurable/entities/roles.entity'; import { Entity, Column, PrimaryGeneratedColumn, ManyToOne } from 'typeorm'; import { BaseModel } from '../../config/basemodel.entity'; import { hashPassword } from '../../helper/hash_password'; +import { Partner } from './partner.entity'; @Entity() export class User extends BaseModel { @@ -39,4 +40,14 @@ export class User extends BaseModel { }, ) roles: Roles; + + @ManyToOne( + () => { + return Partner; + }, + (partner) => { + return partner.id; + }, + ) + partner: Partner; } diff --git a/src/users/partner/partner.service.spec.ts b/src/users/partner/partner.service.spec.ts new file mode 100644 index 0000000..81edeba --- /dev/null +++ b/src/users/partner/partner.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { PartnerService } from './partner.service'; + +describe('PartnerService', () => { + let service: PartnerService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [PartnerService], + }).compile(); + + service = module.get(PartnerService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/src/users/partner/partner.service.ts b/src/users/partner/partner.service.ts new file mode 100644 index 0000000..78ca16d --- /dev/null +++ b/src/users/partner/partner.service.ts @@ -0,0 +1,79 @@ +import { + forwardRef, + HttpException, + HttpStatus, + Inject, + Injectable, +} from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Connection, EntityNotFoundError, Repository } from 'typeorm'; +import { CoaService } from '../../transaction/coa.service'; +import { CreatePartnerDto } from '../dto/create-partner.dto'; +import { Partner } from '../entities/partner.entity'; +import * as uuid from 'uuid'; +import { UsersService } from '../users.service'; +import { CreateUserDto } from '../dto/create-user.dto'; + +@Injectable() +export class PartnerService { + constructor( + @InjectRepository(Partner) + private partnerRepository: Repository, + @Inject( + forwardRef(() => { + return CoaService; + }), + ) + private coaService: CoaService, + private userService: UsersService, + private connection: Connection, + ) {} + + async create(createPartnerDto: CreatePartnerDto, currentUser: any) { + const check = await this.partnerRepository.findOne({ + npwp: createPartnerDto.npwp, + }); + + if (check) { + throw new HttpException( + { + statusCode: HttpStatus.NOT_ACCEPTABLE, + error: 'N Already Exist', + }, + HttpStatus.NOT_FOUND, + ); + } + + const partnerData = new Partner(); + partnerData.id = uuid.v4(); + partnerData.name = createPartnerDto.name; + partnerData.npwp = createPartnerDto.npwp; + partnerData.address = createPartnerDto.address; + partnerData.status = true; + + await this.connection.transaction(async (manager) => { + const result = await manager.insert(Partner, partnerData); + }); + + const dataUser = new CreateUserDto(); + dataUser.username = `admin_${partnerData.name}`; + dataUser.roleId = '21dceea2-416e-4b55-b74c-12605e1f8d1b'; + dataUser.superior = false; + dataUser.partner = partnerData; + dataUser.password = createPartnerDto.password_account; + + await this.userService.create(dataUser, currentUser); + + return partnerData; + } + + findAllPartner(page) { + return this.partnerRepository.findAndCount({ + skip: page * 10, + take: 10, + order: { + version: 'DESC', + }, + }); + } +} diff --git a/src/users/supplier.service.spec.ts b/src/users/supplier/supplier.service.spec.ts similarity index 100% rename from src/users/supplier.service.spec.ts rename to src/users/supplier/supplier.service.spec.ts diff --git a/src/users/supplier.service.ts b/src/users/supplier/supplier.service.ts similarity index 91% rename from src/users/supplier.service.ts rename to src/users/supplier/supplier.service.ts index 6f5278b..3bff728 100644 --- a/src/users/supplier.service.ts +++ b/src/users/supplier/supplier.service.ts @@ -7,11 +7,11 @@ import { } 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 { 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() diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 7980740..e6a77ff 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -16,7 +16,9 @@ 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'; +import { SupplierService } from './supplier/supplier.service'; +import { PartnerService } from './partner/partner.service'; +import { CreatePartnerDto } from './dto/create-partner.dto'; @Controller({ path: 'users', @@ -26,6 +28,7 @@ export class UsersController { constructor( private readonly usersService: UsersService, private readonly supplierService: SupplierService, + private readonly partnerService: PartnerService, ) {} @Post() @@ -38,7 +41,7 @@ export class UsersController { } @Post('supplier') - async createPartner(@Body() createPartnerDto: CreateSupplierDto) { + async createSupplier(@Body() createPartnerDto: CreateSupplierDto) { return { data: await this.supplierService.create(createPartnerDto), statusCode: HttpStatus.CREATED, @@ -46,10 +49,49 @@ export class UsersController { }; } - @Public() + @Post('partner') + async createPartner( + @Request() req, + @Body() createPartnerDto: CreatePartnerDto, + ) { + return { + data: await this.partnerService.create(createPartnerDto, req.user), + statusCode: HttpStatus.CREATED, + message: 'success', + }; + } + @Get() - async findAll(@Query('page') page: number) { - const [data, count] = await this.usersService.findAll(page); + async findAll(@Request() req, @Query('page') page: number) { + const [data, count] = await this.usersService.findAll( + page, + req.user.userId, + ); + + return { + data, + count, + statusCode: HttpStatus.OK, + message: 'success', + }; + } + + @Public() + @Get('supplier') + async findAllSupplier(@Query('page') page: number) { + const [data, count] = await this.supplierService.findAllSupplier(page); + + return { + data, + count, + statusCode: HttpStatus.OK, + message: 'success', + }; + } + + @Get('partner') + async findAllPartner(@Query('page') page: number) { + const [data, count] = await this.partnerService.findAllPartner(page); return { data, @@ -65,6 +107,7 @@ export class UsersController { req.user.userId, page, ); + return { data, count, @@ -79,6 +122,7 @@ export class UsersController { @Query('page') page: number, ) { const [data, count] = await this.usersService.findByRoles(id, page); + return { data, count, diff --git a/src/users/users.module.ts b/src/users/users.module.ts index 0cf442a..079856d 100644 --- a/src/users/users.module.ts +++ b/src/users/users.module.ts @@ -5,17 +5,19 @@ 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 { SupplierService } from './supplier/supplier.service'; import { Supplier } from './entities/supplier.entity'; +import { Partner } from './entities/partner.entity'; +import { PartnerService } from './partner/partner.service'; @Module({ imports: [ - TypeOrmModule.forFeature([User, Supplier]), + TypeOrmModule.forFeature([User, Supplier, Partner]), forwardRef(() => TransactionModule), ConfigurableModule, ], controllers: [UsersController], - providers: [UsersService, SupplierService], + providers: [UsersService, SupplierService, PartnerService], exports: [UsersService, SupplierService], }) export class UsersModule {} diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 2f3cb0e..e94e43f 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -7,7 +7,13 @@ import { } from '@nestjs/common'; import { CreateUserDto } from './dto/create-user.dto'; import { UpdateUserDto } from './dto/update-user.dto'; -import { Connection, EntityNotFoundError, Repository } from 'typeorm'; +import { + Connection, + EntityNotFoundError, + Equal, + Not, + Repository, +} from 'typeorm'; import { User } from './entities/user.entity'; import { InjectRepository } from '@nestjs/typeorm'; import { randomStringGenerator } from '@nestjs/common/utils/random-string-generator.util'; @@ -59,53 +65,56 @@ export class UsersService { userData.username = createUserDto.username; userData.password = await hashPassword(createUserDto.password, salt); userData.salt = salt; - userData.superior = superior; + if (createUserDto.superior) { + userData.superior = superior; + } else { + userData.superior = null; + userData.partner = createUserDto.partner; + } userData.roles = roles; await this.connection.transaction(async (manager) => { const result = await manager.insert(User, userData); const dataCoaWallet = new InputCoaDto(); - dataCoaWallet.user = userData; dataCoaWallet.balanceType = balanceType.CREDIT; dataCoaWallet.type = coaType.WALLET; dataCoaWallet.coaEntityManager = manager; + await this.coaService.create(dataCoaWallet); if (createUserDto.superior) { const dataCoaAP = new InputCoaDto(); - dataCoaAP.user = userData; dataCoaAP.balanceType = balanceType.CREDIT; dataCoaAP.relatedUserId = superior.id; dataCoaAP.type = coaType.ACCOUNT_PAYABLE; dataCoaAP.coaEntityManager = manager; + await this.coaService.create(dataCoaAP); const dataCoaAR = new InputCoaDto(); - dataCoaAR.user = userData; dataCoaAR.balanceType = balanceType.DEBIT; dataCoaAR.relatedUserId = superior.id; dataCoaAR.type = coaType.ACCOUNT_RECEIVABLE; dataCoaAR.coaEntityManager = manager; - - await this.coaService.create(dataCoaAP); await this.coaService.create(dataCoaAR); } - - await this.coaService.create(dataCoaWallet); }); return userData; } - findAll(page: number) { + findAll(page: number, id: string) { return this.usersRepository.findAndCount({ skip: page * 10, take: 10, order: { version: 'DESC', }, + where: { + id: Not(Equal(id)), + }, }); }