Browse Source

Implemented communtiy hall revenue report

master
AJITHKUMAR12 4 weeks ago
parent
commit
adffb399b1
  1. 12
      src/main/java/com/gcc/commissionerreview/configuration/DataSourceConfig.java
  2. 7
      src/main/java/com/gcc/commissionerreview/controller/CommunityHallController.java
  3. 4
      src/main/java/com/gcc/commissionerreview/controller/MainController.java
  4. 341
      src/main/java/com/gcc/commissionerreview/service/CommunityHallService.java
  5. 916
      src/main/resources/templates/modules/communityrevenue.html

12
src/main/java/com/gcc/commissionerreview/configuration/DataSourceConfig.java

@ -17,8 +17,8 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableTransactionManagement @EnableTransactionManagement
public class DataSourceConfig { public class DataSourceConfig {
// private static String host = "localhost:3306";
// private static String dbpassword = "root";
//private static String host = "localhost:3306";
//private static String dbpassword = "root";
private static String host = "gcc-facial-db-instance-1.cf48eqcciziq.ap-south-1.rds.amazonaws.com:3306"; private static String host = "gcc-facial-db-instance-1.cf48eqcciziq.ap-south-1.rds.amazonaws.com:3306";
private static String dbpassword = "gcc-facial-password"; private static String dbpassword = "gcc-facial-password";
@ -233,8 +233,8 @@ public class DataSourceConfig {
dataSource.setPassword(dbpassword); dataSource.setPassword(dbpassword);
return dataSource; return dataSource;
} }
//////////RoadWar //////////////////////
////////// RoadWar //////////////////////
@Bean(name = "mysqlRoadWarDataSource") @Bean(name = "mysqlRoadWarDataSource")
public DataSource mysqlRoadWarDataSource() { public DataSource mysqlRoadWarDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource(); DriverManagerDataSource dataSource = new DriverManagerDataSource();
@ -289,7 +289,7 @@ public class DataSourceConfig {
dataSource.setPassword(dbpassword); dataSource.setPassword(dbpassword);
return dataSource; return dataSource;
} }
/////////////// Shelter Inspection ///////////////////// /////////////// Shelter Inspection /////////////////////
@Bean(name = "mysqlShelterinspectionDataSource") @Bean(name = "mysqlShelterinspectionDataSource")
public DataSource mysqlShelterinspectionDataSource() { public DataSource mysqlShelterinspectionDataSource() {
@ -300,7 +300,7 @@ public class DataSourceConfig {
dataSource.setPassword(dbpassword); dataSource.setPassword(dbpassword);
return dataSource; return dataSource;
} }
////////////////////////////// For Shelter //////////////////////// ////////////////////////////// For Shelter ////////////////////////
@Bean(name = "mysqlShelterDataSource") @Bean(name = "mysqlShelterDataSource")
public DataSource mysqlShelterDataSource() { public DataSource mysqlShelterDataSource() {

7
src/main/java/com/gcc/commissionerreview/controller/CommunityHallController.java

@ -104,5 +104,12 @@ public class CommunityHallController {
region, region,
status); status);
} }
@GetMapping("/refund-summary-report")
public List<Map<String, Object>> getRefundSummaryReport(
@RequestParam String reportDate) {
// System.out.println("reportDate"+reportDate);
return communityHallService.getRefundSummaryReport(reportDate);
}
} }

4
src/main/java/com/gcc/commissionerreview/controller/MainController.java

@ -419,5 +419,9 @@ public class MainController {
public String ResuceList() { public String ResuceList() {
return "modules/shelterinspection/resucelist"; return "modules/shelterinspection/resucelist";
} }
@GetMapping("/communityhallrevenue")
public String Revenue() {
return "modules/communityrevenue";
}
} }

341
src/main/java/com/gcc/commissionerreview/service/CommunityHallService.java

@ -723,4 +723,345 @@ public class CommunityHallService {
sql.toString(), sql.toString(),
params.toArray()); params.toArray());
} }
public List<Map<String, Object>> getRefundSummaryReport(
String reportDate) {
String sql = """
SELECT
hd.hall_id,
hd.hall_name,
/* =========================================================
1. TOTAL BOOKINGS / AMOUNT RECEIVED / DEPOSIT RECEIVED
========================================================= */
COUNT(
CASE
WHEN bd.booking_status NOT IN (
'PENDING',
'GCC_UNBLOCKED',
'REFUNDED'
)
AND bd.booking_status != 'GCC_BLOCKED'
AND bd.amount_received != 0
THEN bd.booking_id
END
) AS TotalBookingCount,
ROUND(
COALESCE(
SUM(
CASE
WHEN bd.booking_status NOT IN (
'PENDING',
'GCC_UNBLOCKED',
'REFUNDED'
)
AND bd.booking_status != 'GCC_BLOCKED'
AND bd.amount_received != 0
THEN bd.amount_received
ELSE 0
END
),
0
),
2
) AS TotalAmountReceived,
ROUND(
COALESCE(
SUM(
CASE
WHEN bd.booking_status NOT IN (
'PENDING',
'GCC_UNBLOCKED',
'REFUNDED'
)
AND bd.booking_status != 'GCC_BLOCKED'
AND bd.amount_received != 0
THEN bd.deposit_amount
ELSE 0
END
),
0
),
2
) AS DepositAmountReceived,
/* =========================================================
2. REFUND DETAILS
========================================================= */
SUM(
CASE
WHEN bd.booking_status IN (
'APPROVED',
'COMPLETED',
'CANCELED',
'REJECTED'
)
AND bd.refund_status = 'COMPLETED'
THEN 1
ELSE 0
END
) AS TotalRefundedCount,
ROUND(
COALESCE(
SUM(
CASE
WHEN bd.booking_status IN (
'APPROVED',
'COMPLETED'
)
AND bd.refund_status = 'COMPLETED'
THEN COALESCE(s.refunded_amount, 0)
ELSE 0
END
),
0
),
2
) AS RefundAmount,
ROUND(
COALESCE(
SUM(
CASE
WHEN bd.booking_status = 'CANCELED'
AND bd.refund_status = 'COMPLETED'
THEN bd.deposit_amount
ELSE 0
END
),
0
),
2
) AS RefundedDepositAmount,
ROUND(
COALESCE(
SUM(
CASE
WHEN bd.booking_status = 'REJECTED'
AND bd.refund_status = 'COMPLETED'
THEN bd.amount_received
ELSE 0
END
),
0
),
2
) AS RejectedRefundAmount,
ROUND(
COALESCE(
SUM(
CASE
WHEN bd.booking_status IN (
'APPROVED',
'COMPLETED'
)
AND bd.refund_status = 'COMPLETED'
THEN COALESCE(s.refunded_amount, 0)
WHEN bd.booking_status = 'CANCELED'
AND bd.refund_status = 'COMPLETED'
THEN bd.deposit_amount
WHEN bd.booking_status = 'REJECTED'
AND bd.refund_status = 'COMPLETED'
THEN bd.amount_received
ELSE 0
END
),
0
),
2
) AS TotalRefundAmount,
/* =========================================================
3. EB READING NOT ENTERED
========================================================= */
COUNT(
CASE
WHEN bd.booking_status NOT IN (
'PENDING',
'GCC_UNBLOCKED',
'WAITING_FOR_NOC',
'WAITING_FOR_NOC_APPROVAL'
)
AND bd.booking_status != 'GCC_BLOCKED'
AND bd.amount_received != 0
AND eb.booking_details_booking_id IS NULL
THEN bd.booking_id
END
) AS EBReadingNotEnteredCount,
/* =========================================================
4. SRO PENDING
APPROVED + EB EXISTS + SETTLEMENT NOT EXISTS
========================================================= */
COUNT(
CASE
WHEN bd.booking_status = 'APPROVED'
AND bd.amount_received != 0
AND eb.booking_details_booking_id IS NOT NULL
AND st.booking_details_booking_id IS NULL
THEN bd.booking_id
END
) AS SROPendingCount,
ROUND(
COALESCE(
SUM(
CASE
WHEN bd.booking_status = 'APPROVED'
AND bd.amount_received != 0
AND eb.booking_details_booking_id IS NOT NULL
AND st.booking_details_booking_id IS NULL
THEN bd.deposit_amount - COALESCE(eb.eb_amount, 0)
ELSE 0
END
),
0
),
2
) AS SROPendingAmount,
/* =========================================================
5. USER CANCELLED - SRO PENDING
========================================================= */
COUNT(
CASE
WHEN bd.booking_status = 'CANCELED'
AND bd.amount_received != 0
AND st.booking_details_booking_id IS NULL
THEN bd.booking_id
END
) AS UserCancelledSROPendingCount,
ROUND(
COALESCE(
SUM(
CASE
WHEN bd.booking_status = 'CANCELED'
AND bd.amount_received != 0
AND st.booking_details_booking_id IS NULL
THEN bd.deposit_amount
ELSE 0
END
),
0
),
2
) AS UserCancelledSROPendingAmount,
/* =========================================================
6. GCC BLOCKED + REJECTED - SRO PENDING
========================================================= */
COUNT(
CASE
WHEN bd.booking_status IN (
'GCC_BLOCKED',
'REJECTED'
)
AND bd.amount_received != 0
AND st.booking_details_booking_id IS NULL
THEN bd.booking_id
END
) AS GCCBlockedRejectedSROPendingCount,
ROUND(
COALESCE(
SUM(
CASE
WHEN bd.booking_status IN (
'GCC_BLOCKED',
'REJECTED'
)
AND bd.amount_received != 0
AND st.booking_details_booking_id IS NULL
THEN bd.deposit_amount
ELSE 0
END
),
0
),
2
) AS GCCBlockedRejectedSROPendingAmount
FROM booking_details bd
LEFT JOIN hall_details hd
ON bd.hall_details_hall_id = hd.hall_id
/* =============================================================
EB DETAILS - ONE ROW PER BOOKING
============================================================= */
LEFT JOIN (
SELECT
booking_details_booking_id,
SUM(eb_amount) AS eb_amount
FROM eb_details
GROUP BY booking_details_booking_id
) eb
ON bd.booking_id = eb.booking_details_booking_id
/* =============================================================
SETTLEMENT - ONE ROW PER BOOKING
============================================================= */
LEFT JOIN (
SELECT
booking_details_booking_id,
SUM(refunded_amount) AS refunded_amount
FROM settlement
GROUP BY booking_details_booking_id
) s
ON bd.booking_id = s.booking_details_booking_id
/* Used only to check whether settlement exists */
LEFT JOIN (
SELECT DISTINCT
booking_details_booking_id
FROM settlement
) st
ON bd.booking_id = st.booking_details_booking_id
WHERE bd.start_date < ?
GROUP BY
hd.hall_id,
hd.hall_name
ORDER BY
CAST(hd.hall_id AS UNSIGNED);
""";
return jdbcTemplate.queryForList(
sql,
reportDate
);
}
} }

916
src/main/resources/templates/modules/communityrevenue.html

@ -0,0 +1,916 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Community Hall Revenue Summary Report</title>
<!-- Bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- FontAwesome -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<!-- DataTables -->
<link href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css" rel="stylesheet">
<link href="https://cdn.datatables.net/buttons/2.3.6/css/buttons.dataTables.min.css" rel="stylesheet">
<style>
body {
background-color: #f8f9fa;
}
.page-header-title h4 {
margin: 20px 0;
text-align: center;
font-weight: bold;
color: #003366;
text-transform: uppercase;
}
.filter-section {
background: #ffffff;
padding: 18px;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
margin-bottom: 20px;
}
.report-container {
background: #ffffff;
padding: 15px;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
overflow-x: auto;
}
table.dataTable th,
table.dataTable td {
text-align: center;
vertical-align: middle;
border: 1px solid #dee2e6 !important;
white-space: nowrap;
}
table.dataTable thead th {
background-color: #003366 !important;
color: white !important;
}
.section-header {
background-color: #005b96 !important;
color: white !important;
font-weight: bold;
}
.hall-name {
white-space: normal !important;
min-width: 220px;
max-width: 220px;
word-break: break-word;
}
.amount {
text-align: right !important;
min-width: 130px;
}
.count-column {
min-width: 100px;
}
.dataTables_scrollBody {
overflow-x: auto !important;
overflow-y: auto !important;
}
.dataTables_scrollBody::-webkit-scrollbar {
height: 8px;
}
.dataTables_scrollBody::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 4px;
}
.dataTables_scrollBody::-webkit-scrollbar-track {
background: #f1f1f1;
}
.filter-label {
font-weight: 600;
margin-bottom: 5px;
}
.btn-search {
min-width: 100px;
}
.btn-reset {
min-width: 100px;
}
.report-date-display {
font-weight: bold;
color: #003366;
}
</style>
</head>
<body>
<div class="container-fluid py-4">
<!-- =====================================================
PAGE HEADER
===================================================== -->
<div class="page-header-title">
<h4>
Community Hall Revenue Summary Report
</h4>
</div>
<!-- =====================================================
FILTER SECTION
===================================================== -->
<div class="filter-section">
<div class="row align-items-end">
<div class="col-md-3">
<label for="reportDate" class="filter-label">
Report Date
</label>
<input type="date" id="reportDate" class="form-control">
</div>
<div class="col-md-9 d-flex justify-content-start gap-2">
<button type="button" id="searchBtn" class="btn btn-primary btn-search">
<i class="fa fa-search"></i>
Search
</button>
<button type="button" id="resetBtn" class="btn btn-secondary btn-reset">
<i class="fa fa-refresh"></i>
Reset
</button>
</div>
</div>
</div>
<!-- =====================================================
REPORT NOTE
===================================================== -->
<div class="report-note">
<i class="fa fa-info-circle"></i>
<strong>Note:</strong>
The booking count may differ from the total number of bookings
due to various booking statuses, such as
<strong>Waiting for NOC</strong>,
<strong>Waiting for NOC Approval</strong> etc.
</div>
<!-- =====================================================
REPORT
===================================================== -->
<div class="report-container">
<table id="refundReportTable" class="table table-bordered table-striped nowrap" style="width:100%">
<thead>
<!-- =================================================
HEADER ROW 1
================================================= -->
<tr>
<th rowspan="2">
S.No
</th>
<th rowspan="2">
Hall ID
</th>
<th rowspan="2" class="hall-name">
Hall Name
</th>
<!-- BOOKING -->
<th colspan="3" class="section-header">
Booking Details
</th>
<!-- REFUND -->
<th colspan="2" class="section-header">
Refund Details
</th>
<!-- EB -->
<th rowspan="2">
Caretaker EB Reading<br>
Not Entered
</th>
<!-- SRO -->
<th colspan="2" class="section-header">
SRO Pending
</th>
<!-- CANCELLED -->
<th colspan="2" class="section-header">
User Cancelled - SRO Pending
</th>
<!-- GCC -->
<th colspan="2" class="section-header">
GCC Blocked / Rejected - SRO Pending
</th>
</tr>
<!-- =================================================
HEADER ROW 2
================================================= -->
<tr>
<!-- Booking -->
<th class="count-column">
Total<br>
Booking Count
</th>
<th class="amount">
Total Amount<br>
Received
</th>
<th class="amount">
Deposit Amount<br>
Received
</th>
<!-- Refund -->
<th class="count-column">
Total Refunded<br>
Count
</th>
<!--<th class="amount">
Refund<br>
Amount
</th>
<th class="amount">
Refunded<br>
Deposit Amount
</th>
<th class="amount">
Rejected<br>
Refund Amount
</th>-->
<th class="amount">
Total<br>
Refund Amount
</th>
<!-- SRO -->
<th class="count-column">
Pending<br>
Count
</th>
<th class="amount">
Pending<br>
Amount
</th>
<!-- Cancelled -->
<th class="count-column">
Pending<br>
Count
</th>
<th class="amount">
Pending<br>
Amount
</th>
<!-- GCC -->
<th class="count-column">
Pending<br>
Count
</th>
<th class="amount">
Pending<br>
Amount
</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
<!-- =========================================================
JAVASCRIPT LIBRARIES
========================================================= -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js">
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js">
</script>
<!-- DataTables -->
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js">
</script>
<script src="https://cdn.datatables.net/buttons/2.3.6/js/dataTables.buttons.min.js">
</script>
<script src="https://cdn.datatables.net/buttons/2.3.6/js/buttons.html5.min.js">
</script>
<script src="https://cdn.datatables.net/buttons/2.3.6/js/buttons.print.min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/pdfmake.min.js">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/vfs_fonts.js">
</script>
<!-- SweetAlert -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11">
</script>
<!-- =========================================================
APPLICATION JAVASCRIPT
========================================================= -->
<script th:inline="none">
let table;
/* =========================================================
FORMAT NUMBER
========================================================= */
function formatNumber(value) {
if (value === null || value === undefined || value === '') {
return '0';
}
return Number(value).toLocaleString('en-IN');
}
/* =========================================================
FORMAT AMOUNT
========================================================= */
function formatAmount(value) {
if (value === null || value === undefined || value === '') {
return '0.00';
}
return Number(value).toLocaleString('en-IN', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
/* =========================================================
INITIALIZE DATATABLE
========================================================= */
function initializeTable() {
table = $('#refundReportTable').DataTable({
dom: 'Bfrtip',
buttons: [
{
extend: 'excelHtml5',
text: 'Excel',
title: 'Community Hall Revenue Summary Report',
filename: 'community_hall_revenue_summary_report',
exportOptions: {
columns: ':visible',
format: {
header: function (data, columnIdx) {
const headers = [
'S.No',
'Hall ID',
'Hall Name',
'Total Bookings',
'Amount Received',
'Deposit Received',
'Refunded Count',
//'Refund Amount',
//'Refunded Deposit',
// 'Rejected Refund',
'Total Refund',
'Caretaker EB Reading Not Entered',
'SRO Pending Count',
'SRO Pending Amount',
'User Cancelled SRO Pending Count',
'User Cancelled SRO Pending Amount',
'GCC Blocked / Rejected SRO Pending Count',
'GCC Blocked / Rejected SRO Pending Amount'
];
return headers[columnIdx];
}
}
}
},
{
extend: 'pdfHtml5',
text: 'PDF',
title: 'Community Hall revenue Summary Report',
filename: 'community_hall_revenue_summary_report',
orientation: 'landscape',
pageSize: 'A3',
customize: function (doc) {
doc.pageMargins = [10, 10, 10, 10];
doc.defaultStyle.fontSize = 7;
doc.styles.tableHeader.fontSize = 7;
doc.styles.tableHeader.alignment = 'center';
doc.defaultStyle.alignment = 'center';
}
}
],
scrollX: true,
scrollCollapse: true,
autoWidth: false,
paging: true,
pageLength: 10,
lengthMenu: [
[10, 25, 50, 100],
[10, 25, 50, 100]
],
ordering: false,
searching: true,
columns: [
{
data: 'sno'
},
{
data: 'hall_id'
},
{
data: 'hall_name',
className: 'hall-name'
},
/* ============================
BOOKING
============================ */
{
data: 'TotalBookingCount',
className: 'count-column',
render: function (data) {
return formatNumber(data);
}
},
{
data: 'TotalAmountReceived',
className: 'amount',
render: function (data) {
return formatAmount(data);
}
},
{
data: 'DepositAmountReceived',
className: 'amount',
render: function (data) {
return formatAmount(data);
}
},
/* ============================
REFUND
============================ */
{
data: 'TotalRefundedCount',
className: 'count-column',
render: function (data) {
return formatNumber(data);
}
},
/* {
data: 'RefundAmount',
className: 'amount',
render: function (data) {
return formatAmount(data);
}
},
{
data: 'RefundedDepositAmount',
className: 'amount',
render: function (data) {
return formatAmount(data);
}
},
{
data: 'RejectedRefundAmount',
className: 'amount',
render: function (data) {
return formatAmount(data);
}
},*/
{
data: 'TotalRefundAmount',
className: 'amount',
render: function (data) {
return formatAmount(data);
}
},
/* ============================
EB
============================ */
{
data: 'EBReadingNotEnteredCount',
className: 'count-column',
render: function (data) {
return formatNumber(data);
}
},
/* ============================
SRO
============================ */
{
data: 'SRoPendingCount',
className: 'count-column',
render: function (data) {
return formatNumber(data);
}
},
{
data: 'SRoPendingAmount',
className: 'amount',
render: function (data) {
return formatAmount(data);
}
},
/* ============================
USER CANCELLED
============================ */
{
data: 'UserCancelledSroPendingCount',
className: 'count-column',
render: function (data) {
return formatNumber(data);
}
},
{
data: 'UserCancelledSroPendingAmount',
className: 'amount',
render: function (data) {
return formatAmount(data);
}
},
/* ============================
GCC BLOCKED / REJECTED
============================ */
{
data: 'GCCBlockedRejectedSROPendingCount',
className: 'count-column',
render: function (data) {
return formatNumber(data);
}
},
{
data: 'GCCBlockedRejectedSROPendingAmount',
className: 'amount',
render: function (data) {
return formatAmount(data);
}
}
]
});
}
/* =========================================================
LOAD REPORT
========================================================= */
function loadReport() {
let reportDate = $('#reportDate').val();
/* ==============================================
VALIDATE DATE
============================================== */
if (!reportDate) {
Swal.fire({
icon: 'warning',
title: 'Warning',
text: 'Please select a report date.',
confirmButtonColor: '#3085d6'
});
return;
}
/* ==============================================
SHOW LOADING
============================================== */
Swal.fire({
title: 'Loading Report...',
text: 'Please wait',
allowOutsideClick: false,
didOpen: function () {
Swal.showLoading();
}
});
/* ==============================================
API CALL
============================================== */
$.ajax({
url: '/commissionerreview/api/communityhall/refund-summary-report',
type: 'GET',
data: {
reportDate: reportDate
},
success: function (response) {
console.log(response);
Swal.close();
table.clear();
/* ==========================================
ADD SERIAL NUMBER
========================================== */
response.forEach(function (row, index) {
row.sno = index + 1;
});
/* ==========================================
ADD DATA
========================================== */
table.rows.add(response);
table.draw();
/* ==========================================
ADJUST COLUMNS
========================================== */
setTimeout(function () {
table.columns.adjust();
}, 200);
},
error: function (xhr) {
Swal.close();
console.error(xhr);
let message = 'Unable to load report.';
if (xhr.responseJSON && xhr.responseJSON.message) {
message = xhr.responseJSON.message;
}
Swal.fire({
icon: 'error',
title: 'Error',
text: message,
confirmButtonColor: '#d33'
});
}
});
}
/* =========================================================
SEARCH BUTTON
========================================================= */
$('#searchBtn').click(function () {
loadReport();
});
/* =========================================================
RESET BUTTON
========================================================= */
$('#resetBtn').click(function () {
$('#reportDate').val('');
table.clear();
table.draw();
});
/* =========================================================
PAGE LOAD
========================================================= */
$(document).ready(function () {
initializeTable();
/*
* Do not automatically load the report.
* User must select a date and click Search.
*/
});
</script>
</body>
</html>
Loading…
Cancel
Save