From 09c84f2cf54882c52d6bebc3cdf83684abf15557 Mon Sep 17 00:00:00 2001 From: ilham Date: Fri, 10 Dec 2021 00:14:05 +0700 Subject: [PATCH] add: get product by categories --- src/product/product.controller.ts | 15 + src/product/product.service.ts | 13 + src/transaction/transaction.controller.ts | 36 +- src/transaction/transaction.service.ts | 403 ++++++++++++++-------- 4 files changed, 302 insertions(+), 165 deletions(-) diff --git a/src/product/product.controller.ts b/src/product/product.controller.ts index 2b20bde..691f3e1 100644 --- a/src/product/product.controller.ts +++ b/src/product/product.controller.ts @@ -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') async findAllCategories(@Query('page') page: number) { const [data, count] = await this.productCategoriesService.findAll(page); diff --git a/src/product/product.service.ts b/src/product/product.service.ts index cf45007..9238e7b 100644 --- a/src/product/product.service.ts +++ b/src/product/product.service.ts @@ -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) { try { return await this.productRepository.findOneOrFail({ code: code }); diff --git a/src/transaction/transaction.controller.ts b/src/transaction/transaction.controller.ts index af080c3..1d60c85 100644 --- a/src/transaction/transaction.controller.ts +++ b/src/transaction/transaction.controller.ts @@ -7,7 +7,7 @@ import { Param, Delete, Request, - HttpStatus + HttpStatus, } from '@nestjs/common'; import { TransactionService } from './transaction.service'; import { DistributeTransactionDto } from './dto/distribute-transaction.dto'; @@ -25,42 +25,52 @@ export class TransactionController { @Post('distribute') create( @Body() createTransactionDto: DistributeTransactionDto, - @Request() req + @Request() req, ) { - return this.transactionService.distributeDeposit(createTransactionDto,req.user); + return this.transactionService.distributeDeposit( + createTransactionDto, + req.user, + ); } @Post('distribute-admin') distributeAdmin( @Body() createTransactionDto: DistributeTransactionDto, - @Request() req + @Request() req, ) { return { - data: this.transactionService.distributeFromAdmin(createTransactionDto,req.user), + data: this.transactionService.distributeFromAdmin( + createTransactionDto, + req.user, + ), statusCode: HttpStatus.CREATED, message: 'success', - }; + }; } @Post('add-saldo-supplier') async addSaldoSupplier( @Body() addSaldoSupplier: AddSaldoSupplier, - @Request() req + @Request() req, ) { - return { - data: await this.transactionService.addIRSWallet(addSaldoSupplier,req.user), + data: await this.transactionService.addIRSWallet( + addSaldoSupplier, + req.user, + ), statusCode: HttpStatus.CREATED, message: 'success', - }; + }; } - @Post('order') orderTransaction( @Body() orderTransactionDto: OrderTransactionDto, - @Request() req + @Request() req, ) { - return this.transactionService.orderTransaction(orderTransactionDto,req.user); + return this.transactionService.orderTransaction( + orderTransactionDto, + req.user, + ); } } diff --git a/src/transaction/transaction.service.ts b/src/transaction/transaction.service.ts index e5b211b..e4d07a2 100644 --- a/src/transaction/transaction.service.ts +++ b/src/transaction/transaction.service.ts @@ -8,9 +8,9 @@ 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"; -import { uniq } from "lodash"; -import {Decimal} from 'decimal.js'; +import * as uuid from 'uuid'; +import { uniq } from 'lodash'; +import { Decimal } from 'decimal.js'; import { balanceType, coaType, @@ -46,50 +46,58 @@ export class TransactionService { private connection: Connection, ) {} - async addIRSWallet(addSaldoSupplier: AddSaldoSupplier,currentUser:any) { + async addIRSWallet(addSaldoSupplier: AddSaldoSupplier, currentUser: any) { // GET COA const coaBank = await this.coaService.findByName( - coaType[coaType.BANK]+'-SYSTEM', + `${coaType[coaType.BANK]}-SYSTEM`, ); const coaInventory = await this.coaService.findByName( - coaType[coaType.INVENTORY]+'-'+addSaldoSupplier.supplier, + `${coaType[coaType.INVENTORY]}-${addSaldoSupplier.supplier}`, ); //GET USER - const userData = await this.userService.findByUsername(currentUser.username); + const userData = await this.userService.findByUsername( + currentUser.username, + ); - await this.connection.transaction(async (manager) => { //INSERT TRANSACTION - let transactionData = new Transactions(); + const transactionData = new Transactions(); + transactionData.id = uuid.v4(); - transactionData.amount = addSaldoSupplier.amount, - transactionData.user = userData.id, - transactionData.status = statusTransaction.SUCCESS, - transactionData.type = typeTransaction.DEPOSIT_IRS, - + transactionData.amount = addSaldoSupplier.amount; + transactionData.user = userData.id; + transactionData.status = statusTransaction.SUCCESS; + transactionData.type = typeTransaction.DEPOSIT_IRS; + await manager.insert(Transactions, transactionData); - + await this.accountingTransaction({ - createTransaction: false, - transactionalEntityManager:manager, - transaction: transactionData, - amount: transactionData.amount, - journals: [{ - coa_id: coaBank.id, - debit: transactionData.amount - }, { - coa_id: coaInventory.id, - credit: transactionData.amount - }] + createTransaction: false, + transactionalEntityManager: manager, + transaction: transactionData, + amount: transactionData.amount, + journals: [ + { + coa_id: coaBank.id, + debit: transactionData.amount, + }, + { + coa_id: coaInventory.id, + credit: transactionData.amount, + }, + ], }); }); return true; } - async distributeFromAdmin(distributeTransactionDto: DistributeTransactionDto,currentUser:any) { + async distributeFromAdmin( + distributeTransactionDto: DistributeTransactionDto, + currentUser: any, + ) { // GET COA const coaAR = await this.coaService.findByUser( distributeTransactionDto.destination, @@ -101,42 +109,52 @@ export class TransactionService { ); //GET USER - const userData = await this.userService.findByUsername(currentUser.username); + const userData = await this.userService.findByUsername( + currentUser.username, + ); await this.connection.transaction(async (manager) => { //INSERT TRANSACTION - let transactionData = new Transactions(); - transactionData.id = uuid.v4(); - transactionData.amount = distributeTransactionDto.amount, - transactionData.user = userData.id, - transactionData.status = statusTransaction.SUCCESS, - transactionData.type = typeTransaction.DISTRIBUTION, - - await manager.insert(Transactions, transactionData); - - await this.accountingTransaction({ - createTransaction: false, - transactionalEntityManager:manager, - transaction: transactionData, - amount: transactionData.amount, - journals: [{ - coa_id: coaAR.id, - debit: transactionData.amount - }, { - coa_id: coaWallet.id, - credit: transactionData.amount - }] - }); + const transactionData = new Transactions(); + transactionData.id = uuid.v4(); + transactionData.amount = distributeTransactionDto.amount; + transactionData.user = userData.id; + transactionData.status = statusTransaction.SUCCESS; + transactionData.type = typeTransaction.DISTRIBUTION; + + await manager.insert(Transactions, transactionData); + + await this.accountingTransaction({ + createTransaction: false, + transactionalEntityManager: manager, + transaction: transactionData, + amount: transactionData.amount, + journals: [ + { + coa_id: coaAR.id, + debit: transactionData.amount, + }, + { + coa_id: coaWallet.id, + credit: transactionData.amount, + }, + ], + }); }); return true; } - async distributeDeposit(distributeTransactionDto: DistributeTransactionDto,currentUser:any) { + async distributeDeposit( + distributeTransactionDto: DistributeTransactionDto, + currentUser: any, + ) { //GET USER - const userData = await this.userService.findByUsername(currentUser.username); - + const userData = await this.userService.findByUsername( + currentUser.username, + ); + // GET COA const coaSenderWallet = await this.coaService.findByUser( userData.id, @@ -161,54 +179,74 @@ export class TransactionService { ); await this.connection.transaction(async (manager) => { - let transactionData = new Transactions(); + const transactionData = new Transactions(); + transactionData.id = uuid.v4(); - transactionData.amount = distributeTransactionDto.amount, - transactionData.user = userData.id, - transactionData.status = statusTransaction.SUCCESS, - transactionData.type = typeTransaction.DISTRIBUTION, - + transactionData.amount = distributeTransactionDto.amount; + transactionData.user = userData.id; + transactionData.status = statusTransaction.SUCCESS; + transactionData.type = typeTransaction.DISTRIBUTION; + await manager.insert(Transactions, transactionData); - + await this.accountingTransaction({ - createTransaction: false, - transactionalEntityManager:manager, - transaction: transactionData, - amount: transactionData.amount, - journals: [{ - coa_id: coaSenderWallet.id, - debit: transactionData.amount - }, { - coa_id: coaReceiverWallet.id, - credit: transactionData.amount - }, { + createTransaction: false, + transactionalEntityManager: manager, + transaction: transactionData, + amount: transactionData.amount, + journals: [ + { + coa_id: coaSenderWallet.id, + debit: transactionData.amount, + }, + { + coa_id: coaReceiverWallet.id, + credit: transactionData.amount, + }, + { coa_id: coaAR.id, - debit: transactionData.amount - }, { - coa_id: coaAP.id, - credit: transactionData.amount - }] + debit: transactionData.amount, + }, + { + coa_id: coaAP.id, + credit: transactionData.amount, + }, + ], }); }); return true; } - async orderTransaction(orderTransactionDto: OrderTransactionDto,currentUser:any) { + async orderTransaction( + orderTransactionDto: OrderTransactionDto, + currentUser: any, + ) { //GET PRODUCT const product = await this.productService.findOne( orderTransactionDto.productCode, ); - + //GET USER - const userData = await this.userService.findByUsername(currentUser.username); + const userData = await this.userService.findByUsername( + currentUser.username, + ); let supervisorData = []; - if(userData.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)); + + if (userData.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( - coaType[coaType.INVENTORY]+'-IRS', + `${coaType[coaType.INVENTORY]}-IRS`, ); const coaCostOfSales = await this.coaService.findByName( - coaType[coaType.COST_OF_SALES]+'-SYSTEM', + `${coaType[coaType.COST_OF_SALES]}-SYSTEM`, ); const coaSales = await this.coaService.findByName( - coaType[coaType.SALES]+'-SYSTEM', + `${coaType[coaType.SALES]}-SYSTEM`, ); 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( it.id, coaType.WALLET, @@ -243,9 +281,9 @@ export class TransactionService { return { coa_id: coaAccount.id, - credit: 0 - } - }) + credit: 0, + }; + }); if (coaAccount.amount <= product.price) { throw new HttpException( @@ -259,103 +297,164 @@ export class TransactionService { try { 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.amount = product.price; + transactionData.user = userData.id; + transactionData.status = statusTransaction.SUCCESS; + transactionData.type = typeTransaction.DISTRIBUTION; await manager.insert(Transactions, transactionData); - + await this.accountingTransaction({ - createTransaction: false, - transactionalEntityManager:manager, - transaction: transactionData, - amount: transactionData.amount, - journals: [{ - coa_id: coaInventory.id, - credit: product.basePrice - }, { - coa_id: coaCostOfSales.id, - debit: product.basePrice - }, { - coa_id: coaAccount.id, - debit: product.price - }, { - coa_id: coaSales.id, - credit: product.price - },{ - coa_id: coaExpense.id, - credit: 0 - }].concat(supervisorData) + createTransaction: false, + transactionalEntityManager: manager, + transaction: transactionData, + amount: transactionData.amount, + journals: [ + { + coa_id: coaInventory.id, + credit: product.basePrice, + }, + { + coa_id: coaCostOfSales.id, + debit: product.basePrice, + }, + { + coa_id: coaAccount.id, + debit: product.price, + }, + { + coa_id: coaSales.id, + credit: product.price, + }, + { + coa_id: coaExpense.id, + credit: 0, + }, + ].concat(supervisorData), }); }); } catch (e) { throw e; } - + return true; } - async accountingTransaction(createJournalDto: CreateJournalDto ) { - let creditSum = createJournalDto.journals.map(it => it.credit).filter(it => it).reduce((a, b) => a.plus(b), new Decimal(0)); - let debitSum = createJournalDto.journals.map(it => it.debit).filter(it => it).reduce((a, b) => a.plus(b), new Decimal(0)); - let coaIds = uniq(createJournalDto.journals.map(it => it.coa_id)); - + async accountingTransaction(createJournalDto: CreateJournalDto) { + const creditSum = createJournalDto.journals + .map((it) => { + 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)) { - throw new Error(`credit and debit doesn't match`); + throw new Error(`credit and debit doesn't match`); } 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 => { - const coa = coas.find(it => it.id === journal.coa_id); + await Promise.all( + createJournalDto.journals.map((journal) => { + const coa = coas.find((it) => { + return it.id === journal.coa_id; + }); if (!coa) { - throw new Error(`coa ${journal.coa_id} not found`); + throw new Error(`coa ${journal.coa_id} not found`); } const journalEntry = new TransactionJournal(); + journalEntry.coa = coa; - journalEntry.type = journal.debit ? balanceType.DEBIT : balanceType.CREDIT; - journalEntry.amount = (journal.debit) ? journal.debit : journal.credit; + journalEntry.type = journal.debit + ? balanceType.DEBIT + : balanceType.CREDIT; + journalEntry.amount = journal.debit ? journal.debit : journal.credit; journalEntry.transaction = transaction; return this.transactionJournalRepository.save(journalEntry); - })); + }), + ); - await Promise.all(coaIds.map(coaId => { - let journalPerCoa = createJournalDto.journals.filter(journal => journal.coa_id == coaId); + await Promise.all( + 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)); - let debitSum = journalPerCoa.map(it => it.debit).filter(it => it).reduce((a, b) => a.plus(b), new Decimal(0)); + const creditSum = journalPerCoa + .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); if (coa.balanceType === balanceType.DEBIT) { - balance = balance.plus(debitSum.minus(creditSum)); + balance = balance.plus(debitSum.minus(creditSum)); } else if (coa.balanceType === balanceType.CREDIT) { - balance = balance.plus(creditSum.minus(debitSum)); + balance = balance.plus(creditSum.minus(debitSum)); } const diff = balance.minus(new Decimal(coa.amount)); return createJournalDto.transactionalEntityManager - .createQueryBuilder() - .update(COA) - .set({ - amount: () => "amount + " + diff.toString() - }) - .where("id = :id", { id: coa.id }) - .execute(); - })); + .createQueryBuilder() + .update(COA) + .set({ + amount: () => { + return `amount + ${diff.toString()}`; + }, + }) + .where('id = :id', { id: coa.id }) + .execute(); + }), + ); return transaction; }