Merge branch 'development' into 'devops-staging'

add: get product by categories

See merge request empatnusabangsa/ppob/ppob-backend!6
This commit is contained in:
ilham dwi pratama 2021-12-09 17:14:51 +00:00
commit 816365956f
4 changed files with 302 additions and 165 deletions

View File

@ -78,6 +78,21 @@ export class ProductController {
}; };
} }
@Get('by-categories')
async findByCategories(
@Query('page') page: number,
@Query('categories') categories: string,
) {
const [data, count] = await this.productService.findAll(page);
return {
data,
count,
statusCode: HttpStatus.OK,
message: 'success',
};
}
@Get('categories') @Get('categories')
async findAllCategories(@Query('page') page: number) { async findAllCategories(@Query('page') page: number) {
const [data, count] = await this.productCategoriesService.findAll(page); const [data, count] = await this.productCategoriesService.findAll(page);

View File

@ -53,6 +53,19 @@ export class ProductService {
}); });
} }
findAllByCategories(page, categories) {
return this.productRepository.findAndCount({
where: {
subCategories: categories,
},
skip: page * 10,
take: 10,
order: {
version: 'DESC',
},
});
}
async findOne(code: string) { async findOne(code: string) {
try { try {
return await this.productRepository.findOneOrFail({ code: code }); return await this.productRepository.findOneOrFail({ code: code });

View File

@ -7,7 +7,7 @@ import {
Param, Param,
Delete, Delete,
Request, Request,
HttpStatus HttpStatus,
} from '@nestjs/common'; } from '@nestjs/common';
import { TransactionService } from './transaction.service'; import { TransactionService } from './transaction.service';
import { DistributeTransactionDto } from './dto/distribute-transaction.dto'; import { DistributeTransactionDto } from './dto/distribute-transaction.dto';
@ -25,18 +25,24 @@ export class TransactionController {
@Post('distribute') @Post('distribute')
create( create(
@Body() createTransactionDto: DistributeTransactionDto, @Body() createTransactionDto: DistributeTransactionDto,
@Request() req @Request() req,
) { ) {
return this.transactionService.distributeDeposit(createTransactionDto,req.user); return this.transactionService.distributeDeposit(
createTransactionDto,
req.user,
);
} }
@Post('distribute-admin') @Post('distribute-admin')
distributeAdmin( distributeAdmin(
@Body() createTransactionDto: DistributeTransactionDto, @Body() createTransactionDto: DistributeTransactionDto,
@Request() req @Request() req,
) { ) {
return { return {
data: this.transactionService.distributeFromAdmin(createTransactionDto,req.user), data: this.transactionService.distributeFromAdmin(
createTransactionDto,
req.user,
),
statusCode: HttpStatus.CREATED, statusCode: HttpStatus.CREATED,
message: 'success', message: 'success',
}; };
@ -45,22 +51,26 @@ export class TransactionController {
@Post('add-saldo-supplier') @Post('add-saldo-supplier')
async addSaldoSupplier( async addSaldoSupplier(
@Body() addSaldoSupplier: AddSaldoSupplier, @Body() addSaldoSupplier: AddSaldoSupplier,
@Request() req @Request() req,
) { ) {
return { return {
data: await this.transactionService.addIRSWallet(addSaldoSupplier,req.user), data: await this.transactionService.addIRSWallet(
addSaldoSupplier,
req.user,
),
statusCode: HttpStatus.CREATED, statusCode: HttpStatus.CREATED,
message: 'success', message: 'success',
}; };
} }
@Post('order') @Post('order')
orderTransaction( orderTransaction(
@Body() orderTransactionDto: OrderTransactionDto, @Body() orderTransactionDto: OrderTransactionDto,
@Request() req @Request() req,
) { ) {
return this.transactionService.orderTransaction(orderTransactionDto,req.user); return this.transactionService.orderTransaction(
orderTransactionDto,
req.user,
);
} }
} }

View File

@ -8,9 +8,9 @@ import { COA } from './entities/coa.entity';
import { TransactionType } from './entities/transaction-type.entity'; import { TransactionType } from './entities/transaction-type.entity';
import { TransactionJournal } from './entities/transaction-journal.entity'; import { TransactionJournal } from './entities/transaction-journal.entity';
import { CoaService } from './coa.service'; import { CoaService } from './coa.service';
import * as uuid from "uuid"; import * as uuid from 'uuid';
import { uniq } from "lodash"; import { uniq } from 'lodash';
import {Decimal} from 'decimal.js'; import { Decimal } from 'decimal.js';
import { import {
balanceType, balanceType,
coaType, coaType,
@ -46,50 +46,58 @@ export class TransactionService {
private connection: Connection, private connection: Connection,
) {} ) {}
async addIRSWallet(addSaldoSupplier: AddSaldoSupplier,currentUser:any) { async addIRSWallet(addSaldoSupplier: AddSaldoSupplier, currentUser: any) {
// GET COA // GET COA
const coaBank = await this.coaService.findByName( const coaBank = await this.coaService.findByName(
coaType[coaType.BANK]+'-SYSTEM', `${coaType[coaType.BANK]}-SYSTEM`,
); );
const coaInventory = await this.coaService.findByName( const coaInventory = await this.coaService.findByName(
coaType[coaType.INVENTORY]+'-'+addSaldoSupplier.supplier, `${coaType[coaType.INVENTORY]}-${addSaldoSupplier.supplier}`,
); );
//GET USER //GET USER
const userData = await this.userService.findByUsername(currentUser.username); const userData = await this.userService.findByUsername(
currentUser.username,
);
await this.connection.transaction(async (manager) => { await this.connection.transaction(async (manager) => {
//INSERT TRANSACTION //INSERT TRANSACTION
let transactionData = new Transactions(); const transactionData = new Transactions();
transactionData.id = uuid.v4(); transactionData.id = uuid.v4();
transactionData.amount = addSaldoSupplier.amount, transactionData.amount = addSaldoSupplier.amount;
transactionData.user = userData.id, transactionData.user = userData.id;
transactionData.status = statusTransaction.SUCCESS, transactionData.status = statusTransaction.SUCCESS;
transactionData.type = typeTransaction.DEPOSIT_IRS, transactionData.type = typeTransaction.DEPOSIT_IRS;
await manager.insert(Transactions, transactionData); await manager.insert(Transactions, transactionData);
await this.accountingTransaction({ await this.accountingTransaction({
createTransaction: false, createTransaction: false,
transactionalEntityManager:manager, transactionalEntityManager: manager,
transaction: transactionData, transaction: transactionData,
amount: transactionData.amount, amount: transactionData.amount,
journals: [{ journals: [
{
coa_id: coaBank.id, coa_id: coaBank.id,
debit: transactionData.amount debit: transactionData.amount,
}, { },
{
coa_id: coaInventory.id, coa_id: coaInventory.id,
credit: transactionData.amount credit: transactionData.amount,
}] },
],
}); });
}); });
return true; return true;
} }
async distributeFromAdmin(distributeTransactionDto: DistributeTransactionDto,currentUser:any) { async distributeFromAdmin(
distributeTransactionDto: DistributeTransactionDto,
currentUser: any,
) {
// GET COA // GET COA
const coaAR = await this.coaService.findByUser( const coaAR = await this.coaService.findByUser(
distributeTransactionDto.destination, distributeTransactionDto.destination,
@ -101,41 +109,51 @@ export class TransactionService {
); );
//GET USER //GET USER
const userData = await this.userService.findByUsername(currentUser.username); const userData = await this.userService.findByUsername(
currentUser.username,
);
await this.connection.transaction(async (manager) => { await this.connection.transaction(async (manager) => {
//INSERT TRANSACTION //INSERT TRANSACTION
let transactionData = new Transactions(); const transactionData = new Transactions();
transactionData.id = uuid.v4(); transactionData.id = uuid.v4();
transactionData.amount = distributeTransactionDto.amount, transactionData.amount = distributeTransactionDto.amount;
transactionData.user = userData.id, transactionData.user = userData.id;
transactionData.status = statusTransaction.SUCCESS, transactionData.status = statusTransaction.SUCCESS;
transactionData.type = typeTransaction.DISTRIBUTION, transactionData.type = typeTransaction.DISTRIBUTION;
await manager.insert(Transactions, transactionData); await manager.insert(Transactions, transactionData);
await this.accountingTransaction({ await this.accountingTransaction({
createTransaction: false, createTransaction: false,
transactionalEntityManager:manager, transactionalEntityManager: manager,
transaction: transactionData, transaction: transactionData,
amount: transactionData.amount, amount: transactionData.amount,
journals: [{ journals: [
{
coa_id: coaAR.id, coa_id: coaAR.id,
debit: transactionData.amount debit: transactionData.amount,
}, { },
{
coa_id: coaWallet.id, coa_id: coaWallet.id,
credit: transactionData.amount credit: transactionData.amount,
}] },
],
}); });
}); });
return true; return true;
} }
async distributeDeposit(distributeTransactionDto: DistributeTransactionDto,currentUser:any) { async distributeDeposit(
distributeTransactionDto: DistributeTransactionDto,
currentUser: any,
) {
//GET USER //GET USER
const userData = await this.userService.findByUsername(currentUser.username); const userData = await this.userService.findByUsername(
currentUser.username,
);
// GET COA // GET COA
const coaSenderWallet = await this.coaService.findByUser( const coaSenderWallet = await this.coaService.findByUser(
@ -161,54 +179,74 @@ export class TransactionService {
); );
await this.connection.transaction(async (manager) => { await this.connection.transaction(async (manager) => {
let transactionData = new Transactions(); const transactionData = new Transactions();
transactionData.id = uuid.v4(); transactionData.id = uuid.v4();
transactionData.amount = distributeTransactionDto.amount, transactionData.amount = distributeTransactionDto.amount;
transactionData.user = userData.id, transactionData.user = userData.id;
transactionData.status = statusTransaction.SUCCESS, transactionData.status = statusTransaction.SUCCESS;
transactionData.type = typeTransaction.DISTRIBUTION, transactionData.type = typeTransaction.DISTRIBUTION;
await manager.insert(Transactions, transactionData); await manager.insert(Transactions, transactionData);
await this.accountingTransaction({ await this.accountingTransaction({
createTransaction: false, createTransaction: false,
transactionalEntityManager:manager, transactionalEntityManager: manager,
transaction: transactionData, transaction: transactionData,
amount: transactionData.amount, amount: transactionData.amount,
journals: [{ journals: [
{
coa_id: coaSenderWallet.id, coa_id: coaSenderWallet.id,
debit: transactionData.amount debit: transactionData.amount,
}, { },
{
coa_id: coaReceiverWallet.id, coa_id: coaReceiverWallet.id,
credit: transactionData.amount credit: transactionData.amount,
}, { },
{
coa_id: coaAR.id, coa_id: coaAR.id,
debit: transactionData.amount debit: transactionData.amount,
}, { },
{
coa_id: coaAP.id, coa_id: coaAP.id,
credit: transactionData.amount credit: transactionData.amount,
}] },
],
}); });
}); });
return true; return true;
} }
async orderTransaction(orderTransactionDto: OrderTransactionDto,currentUser:any) { async orderTransaction(
orderTransactionDto: OrderTransactionDto,
currentUser: any,
) {
//GET PRODUCT //GET PRODUCT
const product = await this.productService.findOne( const product = await this.productService.findOne(
orderTransactionDto.productCode, orderTransactionDto.productCode,
); );
//GET USER //GET USER
const userData = await this.userService.findByUsername(currentUser.username); const userData = await this.userService.findByUsername(
currentUser.username,
);
let supervisorData = []; let supervisorData = [];
if(userData.superior != null){
supervisorData.push(await this.userService.findByUsername(currentUser.username)); if (userData.superior != null) {
if(supervisorData[0].superior != null){ supervisorData.push(
supervisorData.push(await this.userService.findByUsername(currentUser.username)); await this.userService.findByUsername(currentUser.username),
if(supervisorData[0].superior != null){ );
supervisorData.push(await this.userService.findByUsername(currentUser.username));
if (supervisorData[0].superior != null) {
supervisorData.push(
await this.userService.findByUsername(currentUser.username),
);
if (supervisorData[0].superior != null) {
supervisorData.push(
await this.userService.findByUsername(currentUser.username),
);
} }
} }
} }
@ -220,22 +258,22 @@ export class TransactionService {
); );
const coaInventory = await this.coaService.findByName( const coaInventory = await this.coaService.findByName(
coaType[coaType.INVENTORY]+'-IRS', `${coaType[coaType.INVENTORY]}-IRS`,
); );
const coaCostOfSales = await this.coaService.findByName( const coaCostOfSales = await this.coaService.findByName(
coaType[coaType.COST_OF_SALES]+'-SYSTEM', `${coaType[coaType.COST_OF_SALES]}-SYSTEM`,
); );
const coaSales = await this.coaService.findByName( const coaSales = await this.coaService.findByName(
coaType[coaType.SALES]+'-SYSTEM', `${coaType[coaType.SALES]}-SYSTEM`,
); );
const coaExpense = await this.coaService.findByName( const coaExpense = await this.coaService.findByName(
coaType[coaType.EXPENSE]+'-SYSTEM', `${coaType[coaType.EXPENSE]}-SYSTEM`,
); );
supervisorData = supervisorData.map(async it =>{ supervisorData = supervisorData.map(async (it) => {
const coaAccount = await this.coaService.findByUser( const coaAccount = await this.coaService.findByUser(
it.id, it.id,
coaType.WALLET, coaType.WALLET,
@ -243,9 +281,9 @@ export class TransactionService {
return { return {
coa_id: coaAccount.id, coa_id: coaAccount.id,
credit: 0 credit: 0,
} };
}) });
if (coaAccount.amount <= product.price) { if (coaAccount.amount <= product.price) {
throw new HttpException( throw new HttpException(
@ -259,36 +297,42 @@ export class TransactionService {
try { try {
await this.connection.transaction(async (manager) => { await this.connection.transaction(async (manager) => {
let transactionData = new Transactions(); const transactionData = new Transactions();
transactionData.id = uuid.v4();
transactionData.amount = product.price,
transactionData.user = userData.id,
transactionData.status = statusTransaction.SUCCESS,
transactionData.type = typeTransaction.DISTRIBUTION,
transactionData.id = uuid.v4();
transactionData.amount = product.price;
transactionData.user = userData.id;
transactionData.status = statusTransaction.SUCCESS;
transactionData.type = typeTransaction.DISTRIBUTION;
await manager.insert(Transactions, transactionData); await manager.insert(Transactions, transactionData);
await this.accountingTransaction({ await this.accountingTransaction({
createTransaction: false, createTransaction: false,
transactionalEntityManager:manager, transactionalEntityManager: manager,
transaction: transactionData, transaction: transactionData,
amount: transactionData.amount, amount: transactionData.amount,
journals: [{ journals: [
{
coa_id: coaInventory.id, coa_id: coaInventory.id,
credit: product.basePrice credit: product.basePrice,
}, { },
{
coa_id: coaCostOfSales.id, coa_id: coaCostOfSales.id,
debit: product.basePrice debit: product.basePrice,
}, { },
{
coa_id: coaAccount.id, coa_id: coaAccount.id,
debit: product.price debit: product.price,
}, { },
{
coa_id: coaSales.id, coa_id: coaSales.id,
credit: product.price credit: product.price,
},{ },
{
coa_id: coaExpense.id, coa_id: coaExpense.id,
credit: 0 credit: 0,
}].concat(supervisorData) },
].concat(supervisorData),
}); });
}); });
} catch (e) { } catch (e) {
@ -298,10 +342,32 @@ export class TransactionService {
return true; return true;
} }
async accountingTransaction(createJournalDto: CreateJournalDto ) { async accountingTransaction(createJournalDto: CreateJournalDto) {
let creditSum = createJournalDto.journals.map(it => it.credit).filter(it => it).reduce((a, b) => a.plus(b), new Decimal(0)); const creditSum = createJournalDto.journals
let debitSum = createJournalDto.journals.map(it => it.debit).filter(it => it).reduce((a, b) => a.plus(b), new Decimal(0)); .map((it) => {
let coaIds = uniq(createJournalDto.journals.map(it => it.coa_id)); return it.credit;
})
.filter((it) => {
return it;
})
.reduce((a, b) => {
return a.plus(b);
}, new Decimal(0));
const debitSum = createJournalDto.journals
.map((it) => {
return it.debit;
})
.filter((it) => {
return it;
})
.reduce((a, b) => {
return a.plus(b);
}, new Decimal(0));
const coaIds = uniq(
createJournalDto.journals.map((it) => {
return it.coa_id;
}),
);
if (!creditSum.equals(debitSum)) { if (!creditSum.equals(debitSum)) {
throw new Error(`credit and debit doesn't match`); throw new Error(`credit and debit doesn't match`);
@ -309,33 +375,63 @@ export class TransactionService {
const coas = await this.coaRepository.findByIds(coaIds); const coas = await this.coaRepository.findByIds(coaIds);
console.log("berhasil") const transaction = createJournalDto.transaction;
const transaction = createJournalDto.transaction await Promise.all(
createJournalDto.journals.map((journal) => {
await Promise.all(createJournalDto.journals.map(journal => { const coa = coas.find((it) => {
const coa = coas.find(it => it.id === journal.coa_id); return it.id === journal.coa_id;
});
if (!coa) { if (!coa) {
throw new Error(`coa ${journal.coa_id} not found`); throw new Error(`coa ${journal.coa_id} not found`);
} }
const journalEntry = new TransactionJournal(); const journalEntry = new TransactionJournal();
journalEntry.coa = coa; journalEntry.coa = coa;
journalEntry.type = journal.debit ? balanceType.DEBIT : balanceType.CREDIT; journalEntry.type = journal.debit
journalEntry.amount = (journal.debit) ? journal.debit : journal.credit; ? balanceType.DEBIT
: balanceType.CREDIT;
journalEntry.amount = journal.debit ? journal.debit : journal.credit;
journalEntry.transaction = transaction; journalEntry.transaction = transaction;
return this.transactionJournalRepository.save(journalEntry); return this.transactionJournalRepository.save(journalEntry);
})); }),
);
await Promise.all(coaIds.map(coaId => { await Promise.all(
let journalPerCoa = createJournalDto.journals.filter(journal => journal.coa_id == coaId); coaIds.map((coaId) => {
const journalPerCoa = createJournalDto.journals.filter((journal) => {
return journal.coa_id == coaId;
});
let creditSum = journalPerCoa.map(it => it.credit).filter(it => it).reduce((a, b) => a.plus(b), new Decimal(0)); const creditSum = journalPerCoa
let debitSum = journalPerCoa.map(it => it.debit).filter(it => it).reduce((a, b) => a.plus(b), new Decimal(0)); .map((it) => {
return it.credit;
})
.filter((it) => {
return it;
})
.reduce((a, b) => {
return a.plus(b);
}, new Decimal(0));
const debitSum = journalPerCoa
.map((it) => {
return it.debit;
})
.filter((it) => {
return it;
})
.reduce((a, b) => {
return a.plus(b);
}, new Decimal(0));
let coa = coas.find(it => it.id.toLowerCase() === coaId.toLowerCase()); const coa = coas.find((it) => {
(it) => {
return it.id.toLowerCase() === coaId.toLowerCase();
};
});
let balance = new Decimal(coa.amount); let balance = new Decimal(coa.amount);
@ -351,11 +447,14 @@ export class TransactionService {
.createQueryBuilder() .createQueryBuilder()
.update(COA) .update(COA)
.set({ .set({
amount: () => "amount + " + diff.toString() amount: () => {
return `amount + ${diff.toString()}`;
},
}) })
.where("id = :id", { id: coa.id }) .where('id = :id', { id: coa.id })
.execute(); .execute();
})); }),
);
return transaction; return transaction;
} }