Merge branch 'development' into 'devops-staging'

Development

See merge request empatnusabangsa/ppob/ppob-backend!16
This commit is contained in:
ilham dwi pratama 2021-12-13 04:43:06 +00:00
commit 02be8ac43e
35 changed files with 696 additions and 108 deletions

View File

@ -28,6 +28,7 @@ export class AuthService {
username: user.username,
sub: user.id,
role: user.roles.name,
partner: user.partner.id,
};
return {

View 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);
}
}

View File

@ -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',
};
}
}

View File

@ -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 {}

View 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;
}

View File

@ -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,
);

View File

@ -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,
}

View File

@ -18,4 +18,7 @@ export class CreateProductDto {
@IsUUID()
subCategoriesId: string;
@IsUUID()
supplierId: string;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
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(

View File

@ -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;
@IsNotEmpty()
supplier: string;
@IsNotEmpty()
amount?: number;
@IsNotEmpty()
amount: number;
}

View File

@ -6,4 +6,7 @@ export class DistributeTransactionDto {
@IsNotEmpty()
destination: string;
@IsNotEmpty()
supplier: string;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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(
() => {

View File

@ -1,11 +0,0 @@
import {
Entity,
Column,
} from 'typeorm';
import { BaseModel } from '../../config/basemodel.entity';
@Entity()
export class TransactionType extends BaseModel {
@Column()
name: string;
}

View File

@ -54,7 +54,7 @@ export class TransactionController {
@Request() req,
) {
return {
data: await this.transactionService.addIRSWallet(
data: await this.transactionService.addPartnerSaldo(
addSaldoSupplier,
req.user,
),

View File

@ -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 {}

View File

@ -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)

View 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;
}

View File

@ -0,0 +1,9 @@
import { IsNotEmpty } from 'class-validator';
export class CreateSupplierDto {
@IsNotEmpty()
name: string;
@IsNotEmpty()
code: string;
}

View File

@ -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;
// })

View 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;
}

View 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;
}

View File

@ -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;
}

View File

@ -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;
}

View 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;
}

View 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();
});
});

View 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',
},
});
}
}

View 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();
});
});

View 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;
}
}
}
}

View File

@ -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,

View File

@ -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 {}

View File

@ -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)),
},
});
}
@ -157,7 +166,10 @@ export class UsersService {
async findByUsername(username: string) {
try {
return await this.usersRepository.findOneOrFail({
username: username,
where: {
username: username,
},
relations: ['roles'],
});
} catch (e) {
if (e instanceof EntityNotFoundError) {