Merge branch 'development' into 'devops-staging'
Development See merge request empatnusabangsa/ppob/ppob-backend!16
This commit is contained in:
		@@ -28,6 +28,7 @@ export class AuthService {
 | 
			
		||||
      username: user.username,
 | 
			
		||||
      sub: user.id,
 | 
			
		||||
      role: user.roles.name,
 | 
			
		||||
      partner: user.partner.id,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										48
									
								
								src/configurable/commission.service.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/configurable/commission.service.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
 | 
			
		||||
import { EntityNotFoundError, Repository } from 'typeorm';
 | 
			
		||||
import { Roles } from './entities/roles.entity';
 | 
			
		||||
import { InjectRepository } from '@nestjs/typeorm';
 | 
			
		||||
import { UpdateUserDto } from '../users/dto/update-user.dto';
 | 
			
		||||
import { CommissionSetting } from './entities/commission_setting.entity';
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class CommissionService {
 | 
			
		||||
  constructor(
 | 
			
		||||
    @InjectRepository(CommissionSetting)
 | 
			
		||||
    private commissionRepository: Repository<CommissionSetting>,
 | 
			
		||||
  ) {}
 | 
			
		||||
 | 
			
		||||
  findAllRoles(page) {
 | 
			
		||||
    return this.commissionRepository.findAndCount({
 | 
			
		||||
      skip: page * 10,
 | 
			
		||||
      take: 10,
 | 
			
		||||
      order: {
 | 
			
		||||
        version: 'DESC',
 | 
			
		||||
      },
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async updateCommission(id: string, request) {
 | 
			
		||||
    try {
 | 
			
		||||
      await this.commissionRepository.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;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const result = await this.commissionRepository.update(id, {
 | 
			
		||||
      commission: request.value,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return this.commissionRepository.findOneOrFail(id);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -11,13 +11,17 @@ import {
 | 
			
		||||
  Query,
 | 
			
		||||
} from '@nestjs/common';
 | 
			
		||||
import { RoleService } from './roles.service';
 | 
			
		||||
import { CommissionService } from './commission.service';
 | 
			
		||||
 | 
			
		||||
@Controller({
 | 
			
		||||
  path: 'config',
 | 
			
		||||
  version: '1',
 | 
			
		||||
})
 | 
			
		||||
export class ConfigurableController {
 | 
			
		||||
  constructor(private readonly roleService: RoleService) {}
 | 
			
		||||
  constructor(
 | 
			
		||||
    private readonly roleService: RoleService,
 | 
			
		||||
    private readonly commissionService: CommissionService,
 | 
			
		||||
  ) {}
 | 
			
		||||
 | 
			
		||||
  @Get('/roles')
 | 
			
		||||
  async findAll(@Query('page') page: number) {
 | 
			
		||||
@@ -31,6 +35,18 @@ export class ConfigurableController {
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Get('/commission')
 | 
			
		||||
  async findCommission(@Query('page') page: number) {
 | 
			
		||||
    const [data, count] = await this.commissionService.findAllRoles(page);
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      data,
 | 
			
		||||
      count,
 | 
			
		||||
      statusCode: HttpStatus.OK,
 | 
			
		||||
      message: 'success',
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Get(':id')
 | 
			
		||||
  async findOne(@Param('id', ParseUUIDPipe) id: string) {
 | 
			
		||||
    return {
 | 
			
		||||
@@ -39,4 +55,16 @@ export class ConfigurableController {
 | 
			
		||||
      message: 'success',
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Put('/commission/:id')
 | 
			
		||||
  async updateCommission(
 | 
			
		||||
    @Param('id', ParseUUIDPipe) id: string,
 | 
			
		||||
    @Body() request,
 | 
			
		||||
  ) {
 | 
			
		||||
    return {
 | 
			
		||||
      data: await this.commissionService.updateCommission(id, request),
 | 
			
		||||
      statusCode: HttpStatus.OK,
 | 
			
		||||
      message: 'success',
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,11 +3,13 @@ import { TypeOrmModule } from '@nestjs/typeorm';
 | 
			
		||||
import { Roles } from './entities/roles.entity';
 | 
			
		||||
import { ConfigurableController } from './configurable.controller';
 | 
			
		||||
import { RoleService } from './roles.service';
 | 
			
		||||
import { CommissionService } from './commission.service';
 | 
			
		||||
import { CommissionSetting } from './entities/commission_setting.entity';
 | 
			
		||||
 | 
			
		||||
@Module({
 | 
			
		||||
  imports: [TypeOrmModule.forFeature([Roles])],
 | 
			
		||||
  imports: [TypeOrmModule.forFeature([Roles, CommissionSetting])],
 | 
			
		||||
  controllers: [ConfigurableController],
 | 
			
		||||
  providers: [RoleService],
 | 
			
		||||
  exports: [RoleService]
 | 
			
		||||
  providers: [RoleService, CommissionService],
 | 
			
		||||
  exports: [RoleService],
 | 
			
		||||
})
 | 
			
		||||
export class ConfigurableModule {}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								src/configurable/entities/commission_setting.entity.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/configurable/entities/commission_setting.entity.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
import { Entity, Column, OneToOne, JoinColumn } from 'typeorm';
 | 
			
		||||
import { BaseModel } from '../../config/basemodel.entity';
 | 
			
		||||
import { Roles } from './roles.entity';
 | 
			
		||||
 | 
			
		||||
@Entity()
 | 
			
		||||
export class CommissionSetting extends BaseModel {
 | 
			
		||||
  @Column()
 | 
			
		||||
  name: string;
 | 
			
		||||
 | 
			
		||||
  @Column()
 | 
			
		||||
  commission: number;
 | 
			
		||||
 | 
			
		||||
  @OneToOne(() => Roles)
 | 
			
		||||
  @JoinColumn()
 | 
			
		||||
  role: Roles;
 | 
			
		||||
}
 | 
			
		||||
@@ -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,
 | 
			
		||||
        );
 | 
			
		||||
 
 | 
			
		||||
@@ -24,10 +24,17 @@ export enum coaType {
 | 
			
		||||
  BANK,
 | 
			
		||||
  EXPENSE,
 | 
			
		||||
  ACCOUNT_RECEIVABLE,
 | 
			
		||||
  ACCOUNT_PAYABLE
 | 
			
		||||
  ACCOUNT_PAYABLE,
 | 
			
		||||
  BUDGET,
 | 
			
		||||
  CONTRA_BUDGET,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum balanceType {
 | 
			
		||||
  DEBIT,
 | 
			
		||||
  CREDIT,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum accountType {
 | 
			
		||||
  PARTNER,
 | 
			
		||||
  CUSTOMER,
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,4 +18,7 @@ export class CreateProductDto {
 | 
			
		||||
 | 
			
		||||
  @IsUUID()
 | 
			
		||||
  subCategoriesId: string;
 | 
			
		||||
 | 
			
		||||
  @IsUUID()
 | 
			
		||||
  supplierId: string;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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<COA>,
 | 
			
		||||
    @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);
 | 
			
		||||
 | 
			
		||||
    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(
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,16 @@
 | 
			
		||||
import { IsNotEmpty, IsUUID } from 'class-validator';
 | 
			
		||||
import { balanceType, coaType, statusTransaction, typeTransaction } from 'src/helper/enum-list';
 | 
			
		||||
import {
 | 
			
		||||
  balanceType,
 | 
			
		||||
  coaType,
 | 
			
		||||
  statusTransaction,
 | 
			
		||||
  typeTransaction,
 | 
			
		||||
} from 'src/helper/enum-list';
 | 
			
		||||
import { EntityManager } from 'typeorm';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export class AddSaldoSupplier {
 | 
			
		||||
  @IsNotEmpty()
 | 
			
		||||
    supplier?: string;
 | 
			
		||||
  supplier: string;
 | 
			
		||||
 | 
			
		||||
  @IsNotEmpty()
 | 
			
		||||
    amount?: number;
 | 
			
		||||
  amount: number;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,4 +6,7 @@ export class DistributeTransactionDto {
 | 
			
		||||
 | 
			
		||||
  @IsNotEmpty()
 | 
			
		||||
  destination: string;
 | 
			
		||||
 | 
			
		||||
  @IsNotEmpty()
 | 
			
		||||
  supplier: string;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
@@ -20,15 +19,15 @@ export class TransactionJournal extends BaseModel {
 | 
			
		||||
  @Column()
 | 
			
		||||
  amount: number;
 | 
			
		||||
 | 
			
		||||
  @OneToOne(
 | 
			
		||||
  @ManyToOne(
 | 
			
		||||
    () => {
 | 
			
		||||
      return Transactions;
 | 
			
		||||
    },
 | 
			
		||||
    (trans) => {
 | 
			
		||||
      return trans.id;
 | 
			
		||||
    (transaction) => {
 | 
			
		||||
      return transaction.id;
 | 
			
		||||
    },
 | 
			
		||||
  )
 | 
			
		||||
  transaction: Transactions;
 | 
			
		||||
  transaction_head: Transactions;
 | 
			
		||||
 | 
			
		||||
  @ManyToOne(
 | 
			
		||||
    () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
import {
 | 
			
		||||
  Entity,
 | 
			
		||||
  Column,
 | 
			
		||||
} from 'typeorm';
 | 
			
		||||
import { BaseModel } from '../../config/basemodel.entity';
 | 
			
		||||
 | 
			
		||||
@Entity()
 | 
			
		||||
export class TransactionType extends BaseModel {
 | 
			
		||||
  @Column()
 | 
			
		||||
  name: string;
 | 
			
		||||
}
 | 
			
		||||
@@ -54,7 +54,7 @@ export class TransactionController {
 | 
			
		||||
    @Request() req,
 | 
			
		||||
  ) {
 | 
			
		||||
    return {
 | 
			
		||||
      data: await this.transactionService.addIRSWallet(
 | 
			
		||||
      data: await this.transactionService.addPartnerSaldo(
 | 
			
		||||
        addSaldoSupplier,
 | 
			
		||||
        req.user,
 | 
			
		||||
      ),
 | 
			
		||||
 
 | 
			
		||||
@@ -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 {}
 | 
			
		||||
 
 | 
			
		||||
@@ -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';
 | 
			
		||||
@@ -22,6 +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/supplier.service';
 | 
			
		||||
 | 
			
		||||
interface JournalEntry {
 | 
			
		||||
  coa_id: string;
 | 
			
		||||
@@ -34,8 +34,6 @@ export class TransactionService {
 | 
			
		||||
  constructor(
 | 
			
		||||
    @InjectRepository(Transactions)
 | 
			
		||||
    private transactionRepository: Repository<Transactions>,
 | 
			
		||||
    @InjectRepository(TransactionType)
 | 
			
		||||
    private transactionTypeRepository: Repository<TransactionType>,
 | 
			
		||||
    @InjectRepository(TransactionJournal)
 | 
			
		||||
    private transactionJournalRepository: Repository<TransactionJournal>,
 | 
			
		||||
    @InjectRepository(COA)
 | 
			
		||||
@@ -43,17 +41,29 @@ export class TransactionService {
 | 
			
		||||
    private coaService: CoaService,
 | 
			
		||||
    private productService: ProductService,
 | 
			
		||||
    private userService: UsersService,
 | 
			
		||||
    private supplierService: SupplierService,
 | 
			
		||||
    private connection: Connection,
 | 
			
		||||
  ) {}
 | 
			
		||||
 | 
			
		||||
  async addIRSWallet(addSaldoSupplier: AddSaldoSupplier, currentUser: any) {
 | 
			
		||||
  async addPartnerSaldo(addSaldoSupplier: AddSaldoSupplier, currentUser: any) {
 | 
			
		||||
    const supplier = await this.supplierService.findByCode(
 | 
			
		||||
      addSaldoSupplier.supplier,
 | 
			
		||||
    );
 | 
			
		||||
    // GET COA
 | 
			
		||||
    const coaBank = await this.coaService.findByName(
 | 
			
		||||
      `${coaType[coaType.BANK]}-SYSTEM`,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const coaInventory = await this.coaService.findByName(
 | 
			
		||||
      `${coaType[coaType.INVENTORY]}-${addSaldoSupplier.supplier}`,
 | 
			
		||||
      `${coaType[coaType.INVENTORY]}-${supplier.code}`,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const coaBudget = await this.coaService.findByName(
 | 
			
		||||
      `${coaType[coaType.BUDGET]}-${supplier.code}`,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    const coaContraBudget = await this.coaService.findByName(
 | 
			
		||||
      `${coaType[coaType.CONTRA_BUDGET]}-${supplier.code}`,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    //GET USER
 | 
			
		||||
@@ -81,10 +91,18 @@ export class TransactionService {
 | 
			
		||||
        journals: [
 | 
			
		||||
          {
 | 
			
		||||
            coa_id: coaBank.id,
 | 
			
		||||
            debit: transactionData.amount,
 | 
			
		||||
            credit: transactionData.amount,
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            coa_id: coaInventory.id,
 | 
			
		||||
            debit: transactionData.amount,
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            coa_id: coaBudget.id,
 | 
			
		||||
            debit: transactionData.amount,
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            coa_id: coaContraBudget.id,
 | 
			
		||||
            credit: transactionData.amount,
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
@@ -98,6 +116,25 @@ export class TransactionService {
 | 
			
		||||
    distributeTransactionDto: DistributeTransactionDto,
 | 
			
		||||
    currentUser: any,
 | 
			
		||||
  ) {
 | 
			
		||||
    //GET USER
 | 
			
		||||
    const userData = await this.userService.findByUsername(
 | 
			
		||||
      currentUser.username,
 | 
			
		||||
    );
 | 
			
		||||
    if (userData.roles.name != 'Admin') {
 | 
			
		||||
      throw new HttpException(
 | 
			
		||||
        {
 | 
			
		||||
          statusCode: HttpStatus.NOT_ACCEPTABLE,
 | 
			
		||||
          error: 'Roles Not Admin',
 | 
			
		||||
        },
 | 
			
		||||
        HttpStatus.NOT_ACCEPTABLE,
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //GET Supplier
 | 
			
		||||
    const supplier = await this.supplierService.findByCode(
 | 
			
		||||
      distributeTransactionDto.supplier,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // GET COA
 | 
			
		||||
    const coaAR = await this.coaService.findByUser(
 | 
			
		||||
      distributeTransactionDto.destination,
 | 
			
		||||
@@ -107,10 +144,12 @@ export class TransactionService {
 | 
			
		||||
      distributeTransactionDto.destination,
 | 
			
		||||
      coaType.WALLET,
 | 
			
		||||
    );
 | 
			
		||||
    const coaBudget = await this.coaService.findByName(
 | 
			
		||||
      `${coaType[coaType.BUDGET]}-${supplier.code}`,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    //GET USER
 | 
			
		||||
    const userData = await this.userService.findByUsername(
 | 
			
		||||
      currentUser.username,
 | 
			
		||||
    const coaContraBudget = await this.coaService.findByName(
 | 
			
		||||
      `${coaType[coaType.CONTRA_BUDGET]}-${supplier.code}`,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    await this.connection.transaction(async (manager) => {
 | 
			
		||||
@@ -139,6 +178,14 @@ export class TransactionService {
 | 
			
		||||
            coa_id: coaWallet.id,
 | 
			
		||||
            credit: transactionData.amount,
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            coa_id: coaBudget.id,
 | 
			
		||||
            credit: transactionData.amount,
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            coa_id: coaContraBudget.id,
 | 
			
		||||
            debit: transactionData.amount,
 | 
			
		||||
          },
 | 
			
		||||
        ],
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
@@ -394,9 +441,9 @@ export class TransactionService {
 | 
			
		||||
          ? balanceType.DEBIT
 | 
			
		||||
          : balanceType.CREDIT;
 | 
			
		||||
        journalEntry.amount = journal.debit ? journal.debit : journal.credit;
 | 
			
		||||
        journalEntry.transaction = transaction;
 | 
			
		||||
        journalEntry.transaction_head = transaction;
 | 
			
		||||
 | 
			
		||||
        return this.transactionJournalRepository.save(journalEntry);
 | 
			
		||||
        return createJournalDto.transactionalEntityManager.save(journalEntry);
 | 
			
		||||
      }),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
@@ -432,15 +479,12 @@ export class TransactionService {
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        let balance = new Decimal(coa.amount);
 | 
			
		||||
 | 
			
		||||
        if (coa.balanceType === balanceType.DEBIT) {
 | 
			
		||||
        if (coa.balanceType == balanceType.DEBIT) {
 | 
			
		||||
          balance = balance.plus(debitSum.minus(creditSum));
 | 
			
		||||
        } else if (coa.balanceType === balanceType.CREDIT) {
 | 
			
		||||
        } else if (coa.balanceType == balanceType.CREDIT) {
 | 
			
		||||
          balance = balance.plus(creditSum.minus(debitSum));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const diff = balance.minus(new Decimal(coa.amount));
 | 
			
		||||
 | 
			
		||||
        return createJournalDto.transactionalEntityManager
 | 
			
		||||
          .createQueryBuilder()
 | 
			
		||||
          .update(COA)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								src/users/dto/create-partner.dto.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/users/dto/create-partner.dto.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
import { IsNotEmpty } from 'class-validator';
 | 
			
		||||
 | 
			
		||||
export class CreatePartnerDto {
 | 
			
		||||
  @IsNotEmpty()
 | 
			
		||||
  name: string;
 | 
			
		||||
 | 
			
		||||
  @IsNotEmpty()
 | 
			
		||||
  address: string;
 | 
			
		||||
 | 
			
		||||
  @IsNotEmpty()
 | 
			
		||||
  owner: string;
 | 
			
		||||
 | 
			
		||||
  @IsNotEmpty()
 | 
			
		||||
  npwp: string;
 | 
			
		||||
 | 
			
		||||
  @IsNotEmpty()
 | 
			
		||||
  password_account: string;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								src/users/dto/create-supplier.dto.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/users/dto/create-supplier.dto.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
import { IsNotEmpty } from 'class-validator';
 | 
			
		||||
 | 
			
		||||
export class CreateSupplierDto {
 | 
			
		||||
  @IsNotEmpty()
 | 
			
		||||
  name: string;
 | 
			
		||||
 | 
			
		||||
  @IsNotEmpty()
 | 
			
		||||
  code: string;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
  // })
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								src/users/entities/partner.entity.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/users/entities/partner.entity.ts
									
									
									
									
									
										Normal file
									
								
							@@ -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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								src/users/entities/supplier.entity.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/users/entities/supplier.entity.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
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 Supplier extends BaseModel {
 | 
			
		||||
  @PrimaryGeneratedColumn('uuid')
 | 
			
		||||
  id: string;
 | 
			
		||||
 | 
			
		||||
  @Column()
 | 
			
		||||
  name: string;
 | 
			
		||||
 | 
			
		||||
  @Column()
 | 
			
		||||
  code: string;
 | 
			
		||||
 | 
			
		||||
  @Column()
 | 
			
		||||
  status: boolean;
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
import {
 | 
			
		||||
  Entity,
 | 
			
		||||
  Column,
 | 
			
		||||
  PrimaryGeneratedColumn,
 | 
			
		||||
  UpdateDateColumn,
 | 
			
		||||
  DeleteDateColumn,
 | 
			
		||||
  VersionColumn,
 | 
			
		||||
  CreateDateColumn,
 | 
			
		||||
} from 'typeorm';
 | 
			
		||||
 | 
			
		||||
@Entity()
 | 
			
		||||
export class User {
 | 
			
		||||
  @PrimaryGeneratedColumn('uuid')
 | 
			
		||||
  id: string;
 | 
			
		||||
 | 
			
		||||
  @Column()
 | 
			
		||||
  firstName: string;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								src/users/entities/user_detail.entity.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/users/entities/user_detail.entity.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
 | 
			
		||||
import { accountType } from '../../helper/enum-list';
 | 
			
		||||
 | 
			
		||||
@Entity()
 | 
			
		||||
export class UserDetail {
 | 
			
		||||
  @PrimaryGeneratedColumn('uuid')
 | 
			
		||||
  id: string;
 | 
			
		||||
 | 
			
		||||
  @Column()
 | 
			
		||||
  name: string;
 | 
			
		||||
 | 
			
		||||
  @Column()
 | 
			
		||||
  first_name: string;
 | 
			
		||||
 | 
			
		||||
  @Column()
 | 
			
		||||
  phone_number: string;
 | 
			
		||||
 | 
			
		||||
  @Column({
 | 
			
		||||
    nullable: true,
 | 
			
		||||
  })
 | 
			
		||||
  type: accountType;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								src/users/partner/partner.service.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/users/partner/partner.service.spec.ts
									
									
									
									
									
										Normal file
									
								
							@@ -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>(PartnerService);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should be defined', () => {
 | 
			
		||||
    expect(service).toBeDefined();
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										79
									
								
								src/users/partner/partner.service.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/users/partner/partner.service.ts
									
									
									
									
									
										Normal file
									
								
							@@ -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<Partner>,
 | 
			
		||||
    @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',
 | 
			
		||||
      },
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								src/users/supplier/supplier.service.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/users/supplier/supplier.service.spec.ts
									
									
									
									
									
										Normal file
									
								
							@@ -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>(SupplierService);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should be defined', () => {
 | 
			
		||||
    expect(service).toBeDefined();
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										116
									
								
								src/users/supplier/supplier.service.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								src/users/supplier/supplier.service.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
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<Supplier>,
 | 
			
		||||
    @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 findByCode(code: string) {
 | 
			
		||||
    try {
 | 
			
		||||
      return await this.supplierRepository.findOneOrFail({
 | 
			
		||||
        code: code,
 | 
			
		||||
      });
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      if (e instanceof EntityNotFoundError) {
 | 
			
		||||
        throw new HttpException(
 | 
			
		||||
          {
 | 
			
		||||
            statusCode: HttpStatus.NOT_FOUND,
 | 
			
		||||
            error: 'Data not found',
 | 
			
		||||
          },
 | 
			
		||||
          HttpStatus.NOT_FOUND,
 | 
			
		||||
        );
 | 
			
		||||
      } else {
 | 
			
		||||
        throw e;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -15,13 +15,21 @@ 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/supplier.service';
 | 
			
		||||
import { PartnerService } from './partner/partner.service';
 | 
			
		||||
import { CreatePartnerDto } from './dto/create-partner.dto';
 | 
			
		||||
 | 
			
		||||
@Controller({
 | 
			
		||||
  path: 'users',
 | 
			
		||||
  version: '1',
 | 
			
		||||
})
 | 
			
		||||
export class UsersController {
 | 
			
		||||
  constructor(private readonly usersService: UsersService) {}
 | 
			
		||||
  constructor(
 | 
			
		||||
    private readonly usersService: UsersService,
 | 
			
		||||
    private readonly supplierService: SupplierService,
 | 
			
		||||
    private readonly partnerService: PartnerService,
 | 
			
		||||
  ) {}
 | 
			
		||||
 | 
			
		||||
  @Post()
 | 
			
		||||
  async create(@Request() req, @Body() createUserDto: CreateUserDto) {
 | 
			
		||||
@@ -32,10 +40,58 @@ export class UsersController {
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Public()
 | 
			
		||||
  @Post('supplier')
 | 
			
		||||
  async createSupplier(@Body() createPartnerDto: CreateSupplierDto) {
 | 
			
		||||
    return {
 | 
			
		||||
      data: await this.supplierService.create(createPartnerDto),
 | 
			
		||||
      statusCode: HttpStatus.CREATED,
 | 
			
		||||
      message: 'success',
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @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,
 | 
			
		||||
@@ -51,6 +107,7 @@ export class UsersController {
 | 
			
		||||
      req.user.userId,
 | 
			
		||||
      page,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      data,
 | 
			
		||||
      count,
 | 
			
		||||
@@ -65,6 +122,7 @@ export class UsersController {
 | 
			
		||||
    @Query('page') page: number,
 | 
			
		||||
  ) {
 | 
			
		||||
    const [data, count] = await this.usersService.findByRoles(id, page);
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      data,
 | 
			
		||||
      count,
 | 
			
		||||
 
 | 
			
		||||
@@ -5,11 +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/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]), forwardRef(() => TransactionModule), ConfigurableModule],
 | 
			
		||||
  imports: [
 | 
			
		||||
    TypeOrmModule.forFeature([User, Supplier, Partner]),
 | 
			
		||||
    forwardRef(() => TransactionModule),
 | 
			
		||||
    ConfigurableModule,
 | 
			
		||||
  ],
 | 
			
		||||
  controllers: [UsersController],
 | 
			
		||||
  providers: [UsersService],
 | 
			
		||||
  exports: [UsersService],
 | 
			
		||||
  providers: [UsersService, SupplierService, PartnerService],
 | 
			
		||||
  exports: [UsersService, SupplierService],
 | 
			
		||||
})
 | 
			
		||||
export class UsersModule {}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    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)),
 | 
			
		||||
      },
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -157,7 +166,10 @@ export class UsersService {
 | 
			
		||||
  async findByUsername(username: string) {
 | 
			
		||||
    try {
 | 
			
		||||
      return await this.usersRepository.findOneOrFail({
 | 
			
		||||
        where: {
 | 
			
		||||
          username: username,
 | 
			
		||||
        },
 | 
			
		||||
        relations: ['roles'],
 | 
			
		||||
      });
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      if (e instanceof EntityNotFoundError) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user