- add excel export for history transaction

This commit is contained in:
Fadli 2022-12-29 13:17:38 +07:00
parent dbf7fa6af5
commit af797919fd
8 changed files with 16603 additions and 4718 deletions

11236
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -38,12 +38,13 @@
"crypto": "^1.0.1",
"csv-parser": "^3.0.0",
"decimal.js": "^10.3.1",
"exceljs": "^4.3.0",
"fs": "^0.0.1-security",
"fs-extra": "^10.0.0",
"joi": "^17.4.2",
"lodash": "^4.17.21",
"nestjs-pino": "^2.3.1",
"passport": "^0.5.0",
"passport": "^0.4.0",
"passport-jwt": "^4.0.0",
"passport-local": "^1.0.0",
"pg": "^8.7.1",
@ -52,6 +53,7 @@
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0",
"tmp": "^0.2.1",
"typeorm": "^0.2.37",
"typeorm-naming-strategies": "^2.0.0"
},

View File

@ -0,0 +1,8 @@
import { IsNotEmpty, IsOptional } from 'class-validator';
export class ExportTransactionDto {
@IsNotEmpty()
dateStart: string;
}

View File

@ -0,0 +1,36 @@
import {
Controller,
Get,
Res,
Header,
Post,
Body,
Request, Param, ParseUUIDPipe,
} from '@nestjs/common';
import { Response } from 'express';
import { TransactionService } from './transaction.service';
import { ExportTransactionDto } from './dto/export-transaction.dto';
@Controller({
path: 'excel',
version: '1',
})
export class ExcelController {
constructor(private transactionService: TransactionService) {}
@Post('history-user/export/:id')
@Header('Content-Type', 'text/xlsx')
async exportTransactionHistory(
@Param('id', ParseUUIDPipe) id: string,
@Body() exportTransactionDto: ExportTransactionDto,
@Request() req,
@Res() res: Response,
) {
const result = await this.transactionService.exportDataExcel(
exportTransactionDto.dateStart,
id,
);
res.download(`${result}`);
}
}

View File

@ -1,9 +1,22 @@
import { Body, Controller, Get, HttpStatus, Param, ParseUUIDPipe, Post, Put, Query, Request } from '@nestjs/common';
import {
Body,
Controller,
Get,
Header,
HttpStatus,
Param,
ParseUUIDPipe,
Post,
Put,
Query,
Request, Res
} from '@nestjs/common';
import { TransactionService } from './transaction.service';
import { DistributeTransactionDto } from './dto/distribute-transaction.dto';
import { OrderTransactionDto } from './dto/order-transaction.dto';
import { AddSaldoSupplier } from './dto/add-saldo-supplier.dto';
import { DepositReturnDto } from './dto/deposit_return.dto';
import { ExportTransactionDto } from './dto/export-transaction.dto';
@Controller({
path: 'transaction',

View File

@ -14,6 +14,7 @@ import { CheckBillHistory } from './entities/check-bill-history.entity';
import { CallbackPartner } from './entities/callback-partner.entity';
import { ProductHistoryPrice } from '../product/entities/product-history-price.entity';
import { ProductHistoryStatus } from '../product/entities/product-history-status.entity';
import { ExcelController } from './excel.controller';
@Module({
imports: [
@ -28,9 +29,11 @@ import { ProductHistoryStatus } from '../product/entities/product-history-status
]),
ProductModule,
ConfigurableModule,
forwardRef(() => UsersModule),
forwardRef(() => {
return UsersModule;
}),
],
controllers: [TransactionController, PpobCallbackController],
controllers: [TransactionController, PpobCallbackController, ExcelController],
providers: [TransactionService, CoaService],
exports: [CoaService],
})

View File

@ -1,4 +1,11 @@
import { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common';
import {
BadRequestException,
HttpException,
HttpStatus,
Injectable,
Logger,
NotFoundException,
} from '@nestjs/common';
import { DistributeTransactionDto } from './dto/distribute-transaction.dto';
import { OrderTransactionDto } from './dto/order-transaction.dto';
import { InjectRepository } from '@nestjs/typeorm';
@ -38,6 +45,7 @@ import { CheckBillHistory } from './entities/check-bill-history.entity';
import { CallbackPartner } from './entities/callback-partner.entity';
import { doAuthorizeHemat } from '../helper/sihemat-authorization';
import { ProductHistoryStatusService } from '../product/history-status/history-status.service';
import { Workbook } from 'exceljs';
@Injectable()
export class TransactionService {
@ -2123,6 +2131,201 @@ export class TransactionService {
});
}
async exportDataExcel(startDate, user: any) {
const userData = await this.userService.findExist(user);
let userBySupperior = [];
if (
userData.roles.id != 'e4dfb6a3-2338-464a-8fb8-5cbc089d4209' &&
userData.roles.id != '21dceea2-416e-4b55-b74c-12605e1f8d1b'
) {
let roleNumber;
if (userData.roles.id == '3196cdf4-ae5f-4677-9bcd-98be35c72321') {
roleNumber = 3;
} else if (userData.roles.id == '3196cdf4-ae5f-4677-9bcd-98be35c72322') {
roleNumber = 2;
} else if (userData.roles.id == 'e4dfb6a3-2348-464a-8fb8-5cbc089d4209') {
roleNumber = 1;
}
const listUser = await this.userService.findAllSubordinate(
userData.id,
roleNumber,
);
if (listUser.length < 1) {
userBySupperior.push(userData.id);
} else {
userBySupperior = listUser;
}
} else {
userBySupperior.push(userData.id);
}
const baseQuery = this.transactionRepository
.createQueryBuilder('transaction')
.select('transaction.id', 'id')
.addSelect('transaction.created_at', 'created_at')
.where('transaction.user IN (:...id) and transaction.type = 1', {
id: userBySupperior,
})
.leftJoinAndMapOne(
'transaction.userData',
UserDetail,
'userData',
'userData.user = transaction.user',
).select(['userData.user'])
.leftJoin('transaction.product_price', 'product_price')
.leftJoin('product_price.product', 'product')
.leftJoin('product.supplier', 'supplier')
.addSelect('product.name', 'product_name')
.addSelect('product.code', 'product_code')
.addSelect('transaction.amount', 'price')
.addSelect('transaction.balance_remaining', 'balance_remaining')
.addSelect('userData.name', 'buyer')
.addSelect('transaction.destination', 'destination')
.addSelect('transaction.supplier_trx_id', 'transaction_code')
.addSelect(`CASE
WHEN "transaction"."status" = 1 THEN 'Success'
WHEN "transaction"."status" = 2 THEN 'Failed'
ELSE 'Pending'
END`, 'status')
.addSelect('transaction.seri_number', 'serial_number')
.addSelect('transaction.partner_trx_id', 'partner_trx_id')
.addSelect(`to_char(transaction.created_at, 'MM-dd-yyyy HH:mm:ss')`, 'transaction_date')
.addSelect('transaction.failed_reason', 'failed_reason')
.orderBy('transaction.created_at', 'DESC');
if (startDate) {
baseQuery.andWhere(
'transaction.created_at between :startDate and :enDate',
{
startDate: `${startDate} 00:00:00`,
enDate: `${startDate} 23:59:59`,
},
);
}
const data = await baseQuery.getRawMany();
// return {
// data,
// };
if (!data) {
return {
statusCode: HttpStatus.NOT_FOUND,
message: 'No data to export'
};
} else {
let rows = [];
// First create the array of keys/net_total so that we can sort it:
var sort_array = [];
for (var key in data) {
sort_array.push({key: key, product_name: data[key].product_name});
}
// Now sort it:
sort_array.sort((x, y) => {
return x.product_name - y.product_name;
});
let dataSorted = [];
// Now process that object with it:
for (var i = 0; i < sort_array.length; i++) {
var item = data[sort_array[i].key];
// now do stuff with each item
dataSorted.push({
product_name: item.product_name,
product_code: item.product_code,
price: item.price,
balance_remaining: item.balance_remaining,
buyer: item.buyer,
destination: item.destination,
transaction_code: item.transaction_code,
status: item.status,
serial_number: item.serial_number,
partner_trx_id: item.partner_trx_id,
transaction_date: item.transaction_date,
failed_reason: item.failed_reason,
});
}
dataSorted.forEach((doc) => {
rows.push(Object.values(doc));
});
//creating a workbook
let book = new Workbook();
//adding a worksheet to workbook
let sheet = book.addWorksheet('Mutasi Transaksi');
//add the header
rows.unshift(Object.keys(dataSorted[0]));
//adding multiple rows in the sheet
sheet.addRows(rows);
//customize column
sheet.columns = [
{header: 'Nama Produk', key: 'product_name'},
{header: 'Kode Produk', key: 'product_code'},
{header: 'Harga', key: 'price'},
{header: 'Sisa Saldo', key: 'balance_remaining'},
{header: 'Pembeli', key: 'buyer'},
{header: 'Tujuan', key: 'destination'},
{header: 'Kode Transaksi', key: 'transaction_code'},
{header: 'Status', key: 'status'},
{header: 'No Seri', key: 'serial_number'},
{header: 'IDTrx Mitra', key: 'partner_trx_id'},
{header: 'Tanggal Transaksi', key: 'transaction_date'},
{header: 'Alasan Gagal', key: 'failed_reason'},
];
const tmp = require('tmp');
let File = await new Promise((resolve, reject) => {
tmp.file(
{
discardDescriptor: true,
prefix: `Mutasi Transaksi ${userData?.partner.name} ${startDate}`,
postfix: '.xlsx',
mode: parseInt('0600', 8),
},
async (err, file) => {
if (err) throw new BadRequestException(err);
//writing temporary file
book.xlsx
.writeFile(file)
.then((_) => {
resolve(file);
})
.catch((err) => {
throw new BadRequestException(err);
});
},
);
});
//returning the path of file
return File;
}
}
async getTotalSell(currentUser) {
const baseQuery = this.transactionRepository
.createQueryBuilder('transactions')

9810
yarn.lock

File diff suppressed because it is too large Load Diff