penambahan export pada cost management dan summary detail

This commit is contained in:
Fuzi_fauzia 2024-06-28 06:42:42 +07:00
parent 8e0a1abcda
commit 99391c88bb
7 changed files with 1369 additions and 1279 deletions

File diff suppressed because it is too large Load Diff

View File

@ -84,4 +84,70 @@ export class TableexcelService {
});
this.saveAsExcelFile(excelBuffer, excelFileName);
}
public exportAsExcelFileCostManage(
json: any[],
excelFileName: string,
columns: string[]
): void {
// Filter the json data based on the columns
const filteredJson = json.map((item) => {
const filteredItem = {};
columns.forEach((column) => {
filteredItem[column] = item[column];
});
return filteredItem;
});
// Calculate totals for estimation_cost and total_use
const totalEstimationCost = filteredJson.reduce((sum, item) => sum + (item['estimation_cost'] || 0), 0);
const totalUse = filteredJson.reduce((sum, item) => sum + (item['total_use'] || 0), 0);
// Create the worksheet
const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(filteredJson);
const columnWidths = [
{ wch: 40 },
{ wch: 30 },
{ wch: 20 },
{ wch: 30 },
{ wch: 30 },
{ wch: 30 },
];
worksheet["!cols"] = columnWidths;
// Add header
const header = [
"Building",
"Room",
"Category",
"Total Use",
"Estimation Cost",
"Date",
];
XLSX.utils.sheet_add_aoa(worksheet, [header]);
// Add totals row
const totalsRow = [
"Totals",
"",
"",
`Total: ${totalUse} Kwh`,
`Total: ${totalEstimationCost}`,
""
];
XLSX.utils.sheet_add_aoa(worksheet, [totalsRow], { origin: -1 });
// Create the workbook
const workbook: XLSX.WorkBook = {
Sheets: { data: worksheet },
SheetNames: ["data"],
};
// Write the workbook and save it
const excelBuffer: any = XLSX.write(workbook, {
bookType: "xlsx",
type: "array",
});
this.saveAsExcelFile(excelBuffer, excelFileName);
}
}

View File

@ -416,3 +416,4 @@ input[type="month"]::-webkit-calendar-picker-indicator {
:host ::ng-deep .ngx-datatable.bootstrap .datatable-body-row:hover {
background-color: #1a1a1a; /* Darker black for hover effect */
}

View File

@ -6,42 +6,7 @@
<div class="content-body">
<section>
<div class="row">
<div class="col-lg-4">
<div class="card" style="background-color: #252525 !important">
<div
class="card-header"
style="background-color: #252525 !important"
>
<h4
class="card-title text-center"
style="color: #ffffff !important"
>
Comparison of Water and Electricity Costs
</h4>
<hr
style="
border-top: 4px solid #ffffff;
border-color: #ffffff !important;
"
/>
</div>
<div class="card-body">
<div class="card-block">
<div class="donut-chart2" style="height: 150px !important">
<x-chartist
*ngIf="donutChart2"
[data]="donutChart2.data"
[type]="donutChart2.type"
[options]="donutChart2.options"
[responsiveOptions]="donutChart2.responsiveOptions"
[events]="donutChart2.events"
></x-chartist>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="col-12 col-sm-6 col-md-6 col-lg-6">
<div class="card" style="background-color: #252525 !important">
<div
class="card-header"
@ -61,24 +26,16 @@
/>
</div>
<div class="card-body">
<div class="card-block">
<div class="donut-chart3" style="height: 150px !important">
<x-chartist
class="text-center"
*ngIf="barChart"
[data]="barChart.data"
[type]="barChart.type"
[options]="barChart.options"
[responsiveOptions]="barChart.responsiveOptions"
[events]="barChart.events"
>
</x-chartist>
<div
echarts
[options]="chartOption"
class="echart-container"
style="height: 150% !important"
></div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="col-12 col-sm-6 col-md-6 col-lg-6">
<div class="card" style="background-color: #252525 !important">
<div
class="card-header"
@ -88,7 +45,7 @@
class="card-title text-center"
style="color: #ffffff !important"
>
Comparison of Actual Costs and Estimated Costs
Comparison of Previous Month Actual Costs and Estimated Costs
</h4>
<hr
style="
@ -98,62 +55,23 @@
/>
</div>
<div class="card-body">
<div class="card-block">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<label style="color: #ffffff">Actual Cost</label>
<ngb-progressbar
height="35px"
type="success"
[value]="dataCompAct?.real_cost"
[max]="dataCompAct?.est_cost"
></ngb-progressbar>
</div>
<div
class="ml-2 d-flex align-items-center"
style="height: 20px"
>
<span class="text-bold-600">{{
dataCompAct?.real_cost
}}</span>
</div>
</div>
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<label style="color: #ffffff">Estimated Cost</label>
<ngb-progressbar
height="35px"
type="danger"
[value]="dataCompAct?.est_cost"
[max]="dataCompAct?.est_cost"
></ngb-progressbar>
</div>
<div
class="ml-2 d-flex align-items-center"
style="height: 20px"
>
<span class="text-bold-600">{{
dataCompAct?.est_cost
}}</span>
</div>
</div>
</div>
echarts
[options]="chartOption2"
class="echart-container"
style="height: 150% !important"
></div>
</div>
</div>
</div>
</div>
</section>
<section id="configuration">
<div class="row">
<div
class="col-12"
*blockUI="'zeroConfiguration'; message: 'Loading'"
>
<div class="card" style="background-color: #252525 !important">
<div class="card-content">
<div class="card-body">
<div class="row">
<div class="col-3">
<div class="col-6 col-sm-3 col-md-3 col-lg-3 col-xl-3">
<div class="form-group">
<ng-select
[items]="dataBuildingList"
@ -166,7 +84,7 @@
</ng-select>
</div>
</div>
<div class="col-3">
<div class="col-6 col-sm-3 col-md-3 col-lg-3 col-xl-3">
<div class="form-group">
<input
type="month"
@ -177,7 +95,7 @@
/>
</div>
</div>
<div class="col-3">
<div class="col-6 col-sm-3 col-md-3 col-lg-3 col-xl-3">
<div class="form-group">
<ng-select
[items]="dataMasterCategori"
@ -190,11 +108,11 @@
</ng-select>
</div>
</div>
<div class="col-3">
<div class="col-6 col-sm-3 col-md-3 col-lg-3 col-xl-3">
<div class="d-flex">
<button
type="button"
class="btn btn-outline-success ml-2"
class="btn btn-outline-success"
(click)="doFilter()"
style="
background-color: #252525 !important;
@ -218,7 +136,7 @@
</div>
<div class="row mb-2">
<div class="col-4">
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-3">
<div class="form-group">
<div class="input-group">
<input
@ -245,7 +163,7 @@
</div>
</div>
</div>
<div class="col-4">
<div class="col-6 col-sm-6 col-md-6 col-lg-6 col-xl-3">
<div class="form-group">
<div class="input-group">
<input
@ -275,8 +193,26 @@
</div>
</div>
<div class="col-4">
<div class="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-6">
<div class="d-flex justify-content-end">
<button
class="btn btn-secondary mr-2"
style="
width: 100%;
background-color: #bef264 !important;
border-color: #bef264 !important;
color: #000000 !important;
"
(click)="export()"
[disabled]="spinnerExportActive"
>
<i
class="la la-spinner spinner"
*ngIf="spinnerExportActive"
></i>
<i class="ri-export-line" *ngIf="!spinnerExportActive"></i>&nbsp;
<span>Export</span>
</button>
<button
class="btn btn-secondary mr-2"
style="
@ -286,13 +222,13 @@
color: #000000 !important;
"
(click)="syncData()"
[disabled]="spinnerActive"
>
<i
class="la la-spinner spinner"
*ngIf="spinnerActive"
></i>
<i class="la la-spinner" *ngIf="!spinnerActive"></i
>&nbsp;
<i class="la la-spinner" *ngIf="!spinnerActive"></i>&nbsp;
<span>Syncing Data</span>
</button>
<button
@ -344,14 +280,9 @@
[minWidth]="90"
>
<ng-template ngx-datatable-header-template>
<span style="color: #ffffff !important"
>Building</span
>
<span style="color: #ffffff !important">Building</span>
</ng-template>
<ng-template
let-value="value"
ngx-datatable-cell-template
>
<ng-template let-value="value" ngx-datatable-cell-template>
<p style="color: #ffffff !important">{{ value }}</p>
</ng-template>
</ngx-datatable-column>
@ -361,14 +292,9 @@
[minWidth]="90"
>
<ng-template ngx-datatable-header-template>
<span style="color: #ffffff !important"
>Category</span
>
<span style="color: #ffffff !important">Category</span>
</ng-template>
<ng-template
let-value="value"
ngx-datatable-cell-template
>
<ng-template let-value="value" ngx-datatable-cell-template>
<p style="color: #ffffff !important">{{ value }}</p>
</ng-template>
</ngx-datatable-column>
@ -378,14 +304,9 @@
[minWidth]="90"
>
<ng-template ngx-datatable-header-template>
<span style="color: #ffffff !important"
>Room</span
>
<span style="color: #ffffff !important">Room</span>
</ng-template>
<ng-template
let-value="value"
ngx-datatable-cell-template
>
<ng-template let-value="value" ngx-datatable-cell-template>
<p style="color: #ffffff !important">{{ value }}</p>
</ng-template>
</ngx-datatable-column>
@ -399,10 +320,7 @@
>Estimation Cost</span
>
</ng-template>
<ng-template
let-value="value"
ngx-datatable-cell-template
>
<ng-template let-value="value" ngx-datatable-cell-template>
<p style="color: #ffffff !important">
{{
value.toLocaleString("id-ID", {
@ -419,14 +337,9 @@
[minWidth]="90"
>
<ng-template ngx-datatable-header-template>
<span style="color: #ffffff !important"
>Total Use</span
>
<span style="color: #ffffff !important">Total Use</span>
</ng-template>
<ng-template
let-value="value"
ngx-datatable-cell-template
>
<ng-template let-value="value" ngx-datatable-cell-template>
<p style="color: #ffffff !important">{{ value }}</p>
kWh
</ng-template>
@ -439,10 +352,7 @@
<ng-template ngx-datatable-header-template>
<span style="color: #ffffff !important">Tanggal</span>
</ng-template>
<ng-template
let-value="value"
ngx-datatable-cell-template
>
<ng-template let-value="value" ngx-datatable-cell-template>
<p style="color: #ffffff !important">
{{ value | date : "MM/yyyy" }}
</p>
@ -456,10 +366,7 @@
<ng-template ngx-datatable-header-template>
<span style="color: #ffffff !important">Status</span>
</ng-template>
<ng-template
ngx-datatable-cell-template
let-value="value"
>
<ng-template ngx-datatable-cell-template let-value="value">
<p style="color: #ffffff !important">
{{ value === 2 ? "Aktif" : "Tidak Aktif" }}
</p>
@ -486,7 +393,10 @@
"
(click)="viewRow(row)"
>
<i class="ficon ri-export-line" style="color: #bef264 !important"></i>
<i
class="ficon ri-export-line"
style="color: #bef264 !important"
></i>
</button>
</ng-template>
</ngx-datatable-column>
@ -495,8 +405,6 @@
</div>
</div>
</div>
</div>
</div>
</section>
</div>
</div>

View File

@ -1,16 +1,11 @@
import { Component, OnInit } from "@angular/core";
import { Router } from "@angular/router";
import { TableApiService } from "src/app/_services/table-api.service";
import { BuildingService } from "../service/monitoring-api.service";
import { DatePipe } from "@angular/common";
import { CostManagementService } from "../service/cost-management.service";
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
import { ModalAddActualComponent } from "./modal-add-actual/modal-add-actual.component";
import { ChartEvent, ChartType } from "ng-chartist";
import * as Chartist from "chartist";
import "chartist-plugin-tooltips";
import { ModalExportComponent } from "./modal-export/modal-export.component";
import { TableexcelService } from "src/app/_services/tableexcel.service";
@Component({
selector: "app-cost-management",
@ -33,26 +28,25 @@ export class CostManagementComponent implements OnInit {
spinnerActive = false;
spinnerActiveActual = false;
spinnerFilterActive = false;
donutChart2: any;
barChart: any;
dateSelected: any;
buildingSelected: any;
categorySelected: any;
dataComp: any;
dataCompPrev: any;
dataCompAct: any;
storedData: any;
chartOption: any;
chartOption2: any;
spinnerExportActive = false;
constructor(
private tableApiservice: TableApiService,
private router: Router,
private monitoringApiService: BuildingService,
private costService: CostManagementService,
private datePipe: DatePipe,
private modalService: NgbModal
private modalService: NgbModal,
private tableexcelService: TableexcelService
) {}
ngOnInit() {
@ -82,7 +76,6 @@ export class CostManagementComponent implements OnInit {
this.dataListMaster();
this.dataListBuilding();
this.dataCompWaterElectCost(this.storedData.buildingId);
this.dataCompPrevMonthCost(this.storedData.buildingId);
this.dataCompActEstCost(this.storedData.buildingId);
}
@ -125,80 +118,93 @@ export class CostManagementComponent implements OnInit {
});
}
dataCompWaterElectCost(buildingId) {
this.costService.getCompWaterElectCost(buildingId).subscribe((data) => {
this.dataComp = data.data;
const dataChart2 = {
donut: {
series: [this.dataComp.elect, this.dataComp.water],
labels: ["Electricity", "Water"],
},
};
this.donutChart2 = {
type: "Pie",
data: dataChart2.donut,
options: {
chartPadding: 0,
fullwidth: true,
height: "150px",
donut: true,
showLabel: true,
startAngle: 0,
labelPosition: "outside",
labelOffset: 50,
labelInterpolationFnc: function (value) {
return value;
},
},
};
});
}
dataCompPrevMonthCost(buildingId) {
this.costService.getCompPrevMonthCost(buildingId).subscribe((data) => {
this.dataCompPrev = data.data;
const randomValue = Math.floor(Math.random() * (100 - 50 + 1)) + 50;
const dataBar = {
Bar: {
labels: [[this.dataCompPrev[0].name], [this.dataCompPrev[1].name]],
series: [[randomValue], [this.dataCompPrev[1].value]],
this.chartOption = {
grid: {
left: "25%",
right: "25%",
top: "20%",
bottom: "20%",
},
};
this.barChart = {
type: "Bar",
data: dataBar.Bar,
options: {
fullwidth: true,
width: "100px",
height: "200px",
seriesBarDistance: 200,
chartPadding: {bottom: 40 },
axisX: {
showGrid: false,
showLabel: true,
offset: 30,
},
axisY: {
showGrid: false,
showLabel: false, // Hide labels on the y-axis
scaleMinSpace: 30,
},
classNames: {
bar: "ct-bar", // Add custom class to the bar
// Add tooltip
tooltip: {
trigger: "axis",
enterable: false,
formatter: function (params) {
return `${params[0].name}<br/>${
params[0].seriesName
}: Rp. ${params[0].value.toLocaleString()}`;
},
},
responsiveOptions: [
[
"screen and (max-width: 640px)",
// Add legend
legend: false,
// Add custom colors
color: ["#BEF264"],
// Horizontal axis
xAxis: [
{
seriesBarDistance: 10,
axisX: {
labelInterpolationFnc: function (value) {
return value[0]; // Return the first character of the label
type: "category",
data: [this.dataCompPrev[0].name, this.dataCompPrev[1].name],
axisLine: {
show: true,
lineStyle: {
color: "#BEF264",
width: 4,
},
},
axisTick: {
show: false,
},
splitLine: {
show: false,
},
axisLabel: {
show: false,
},
},
],
// Vertical axis
yAxis: [
{
type: "value",
axisLine: {
show: false,
},
axisTick: {
show: false,
},
splitLine: {
show: false,
},
axisLabel: {
show: false,
},
},
],
// Add series
series: [
{
name: "Cost",
type: "bar",
data: [this.dataCompPrev[0].value, this.dataCompPrev[1].value],
label: {
show: true,
position: "top",
color: "#ffffff",
formatter: function (params) {
return `Rp. ${params.value.toLocaleString()}`;
},
},
barWidth: "50%",
},
],
};
});
@ -207,6 +213,92 @@ export class CostManagementComponent implements OnInit {
dataCompActEstCost(buildingId) {
this.costService.getCompActEstCost(buildingId).subscribe((data) => {
this.dataCompAct = data.data[0];
this.chartOption2 = {
grid: {
left: "25%",
right: "25%",
top: "20%",
bottom: "20%",
},
// Add tooltip
tooltip: {
trigger: "axis",
enterable: false,
formatter: function (params) {
return `${params[0].name}<br/>${
params[0].seriesName
}: Rp. ${params[0].value.toLocaleString()}`;
},
},
// Add legend
legend: false,
// Add custom colors
color: ["#BEF264"],
// Horizontal axis
xAxis: [
{
type: "category",
data: ["Estimation Cost", "Actual Cost"],
axisLine: {
show: true,
lineStyle: {
color: "#BEF264",
width: 4,
},
},
axisTick: {
show: false,
},
splitLine: {
show: false,
},
axisLabel: {
show: false,
},
},
],
// Vertical axis
yAxis: [
{
type: "value",
axisLine: {
show: false,
},
axisTick: {
show: false,
},
splitLine: {
show: false,
},
axisLabel: {
show: false,
},
},
],
// Add series
series: [
{
name: "Cost",
type: "bar",
data: [this.dataCompAct.est_cost, this.dataCompAct.real_cost],
label: {
show: true,
position: "top",
color: "#ffffff",
formatter: function (params) {
return `Rp. ${params.value.toLocaleString()}`;
},
},
barWidth: "50%", // Adjust bar width
},
],
};
});
}
@ -331,4 +423,24 @@ export class CostManagementComponent implements OnInit {
}
);
}
export(){
this.spinnerExportActive = true;
setTimeout(() => {
const columnsToExport = [
"name",
"room_name",
"category_name",
"total_use",
"estimation_cost",
"end_date",
];
this.tableexcelService.exportAsExcelFileCostManage(
this.filteredRows,
"Smart_building_cost_management",
columnsToExport
);
this.spinnerExportActive = false;
}, 3000);
}
}

View File

@ -18,6 +18,7 @@ import { MatchHeightModule } from '../../partials/general/match-height/match-hei
import { ModalAddActualComponent } from './modal-add-actual/modal-add-actual.component';
import { NgxMaskModule, IConfig } from 'ngx-mask';
import { ModalExportComponent } from './modal-export/modal-export.component'
import { NgxEchartsModule } from 'ngx-echarts';
export const options: Partial<null|IConfig> | (() => Partial<IConfig>) = null;
@ -41,6 +42,9 @@ export const options: Partial<null|IConfig> | (() => Partial<IConfig>) = null;
NgChartsModule,
ChartistModule,
MatchHeightModule,
NgxEchartsModule.forRoot({
echarts: () => import('echarts')
}),
NgxMaskModule.forRoot(),
BlockUIModule.forRoot({
template: BlockTemplateComponent

View File

@ -1,6 +1,5 @@
{
"sales":
[
"sales": [
{
"name": "Today",
"sales": "$250.00",
@ -31,18 +30,18 @@
"receipts": "$1200.00",
"due": "$300.00"
}
],
"TotalSales":{
"TotalSales":[
[1000, 1800, 1200, 0, 2000, 1500, 700, 900, 1600, 1400, 1550, 1800]
]},
"TotalReceipts":{
"TotalReceipts":[
[850, 1650, 1000, 0, 1850, 1350, 450, 0, 1500, 900, 1250, 1500]
]},
"TotalExpenses":{
"TotalExpenses":[
[50, 150, 100, 10, 850, 350, 0, 60, 250, 90, 120, 230]
]}
],
"TotalSales": {
"TotalSales": [
[1000, 1800, 1200, 0, 2000, 1500, 700, 900, 1600, 1400, 1550, 1800]
]
},
"TotalReceipts": {
"TotalReceipts": [
[850, 1650, 1000, 0, 1850, 1350, 450, 0, 1500, 900, 1250, 1500]
]
},
"TotalExpenses": {
"TotalExpenses": [[50, 150, 100, 10, 850, 350, 0, 60, 250, 90, 120, 230]]
}
}