-
+
Employee Login
{" | "}
@@ -64,4 +64,4 @@ export default function Header() {
)
-}
\ No newline at end of file
+}
diff --git a/web/egov-common-screen/src/components/propertyQRData/api.jsx b/web/egov-common-screen/src/components/propertyQRData/api.jsx
new file mode 100644
index 0000000000..25ce72398c
--- /dev/null
+++ b/web/egov-common-screen/src/components/propertyQRData/api.jsx
@@ -0,0 +1,44 @@
+import axios from "axios";
+const isDev = import.meta.env.DEV;
+const API = axios.create({
+ baseURL: isDev ? "" : import.meta.env.VITE_API_HOST,
+ headers: {
+ "Content-Type": "application/json",
+ },
+});
+
+// Function to generate RequestInfo
+const generateRequestInfo = () => {
+ return {
+ apiId: "Rainmaker",
+ ver: ".01",
+ ts: Date.now(),
+ action: "token",
+ did: "1",
+ key: "",
+ msgId: `${Date.now()}|en_IN`,
+ authToken: localStorage.getItem("authToken") || "",
+ };
+};
+
+// Request Interceptor
+API.interceptors.request.use(
+ (config) => {
+ // Only attach for POST / PUT / PATCH
+ if (
+ config.method === "post" ||
+ config.method === "put" ||
+ config.method === "patch"
+ ) {
+ config.data = {
+ RequestInfo: generateRequestInfo(),
+ ...config.data,
+ };
+ }
+
+ return config;
+ },
+ (error) => Promise.reject(error)
+);
+
+export default API;
\ No newline at end of file
diff --git a/web/egov-common-screen/src/components/propertyQRData/constant.jsx b/web/egov-common-screen/src/components/propertyQRData/constant.jsx
new file mode 100644
index 0000000000..94870c30b3
--- /dev/null
+++ b/web/egov-common-screen/src/components/propertyQRData/constant.jsx
@@ -0,0 +1,2 @@
+export const statetenantId = 'pb'
+export const AUTHORIZATION_TOKEN = "Basic ZWdvdi11c2VyLWNsaWVudDplZ292LXVzZXItc2VjcmV0";
diff --git a/web/egov-common-screen/src/components/propertyQRData/displayPropertyRecord.jsx b/web/egov-common-screen/src/components/propertyQRData/displayPropertyRecord.jsx
new file mode 100644
index 0000000000..138d086ade
--- /dev/null
+++ b/web/egov-common-screen/src/components/propertyQRData/displayPropertyRecord.jsx
@@ -0,0 +1,92 @@
+import { useSearchParams } from 'react-router-dom';
+import { useEffect, useState } from 'react';
+import { searchPropertyBySurvey, getAddressArray } from "./function"
+const DisplayPropertyRecord = () => {
+ const [missingParams, setMissingParams] = useState(false);
+ const [searchParams] = useSearchParams();
+ const [propertyData, setPropertyData] = useState([]);
+ // Extract date from query parameters
+ const surveyID = searchParams.get('surveyid');
+ const tenantId = searchParams.get('tenantid');
+ const mobileNumber = searchParams.get('mobileno');
+ useEffect(() => {
+ if (!surveyID || !tenantId || !mobileNumber) {
+ if (!errorShown.current) { // Show error only once
+ showError("Please scan the QR code again");
+ errorShown.current = true;
+ }
+ setMissingParams(true);
+ return;
+ }
+
+ const fetchProp = async () => {
+ try {
+ const data = await searchPropertyBySurvey({ tenantId, surveyId: surveyID });
+ //console.log("data",data)
+ setPropertyData(data?.Properties || []);
+
+ } catch (err) {
+ console.error("API Failed:", err);
+ }
+ };
+
+ fetchProp();
+ }, [surveyID, tenantId, mobileNumber]);
+ // console.log("propertyData", propertyData)
+ const editPropertyurl = (propertyID, tenantid)=>{
+ debugger
+ let url = `/citizen/property-tax/assessment-form?assessmentId=0&purpose=update&propertyId=${propertyID}&tenantId=${tenantid}`;
+ window.location.replace(url);
+ }
+ return (
+
+ {missingParams ? (
+
+
Invalid QR Code
+
Please scan a valid QR code to proceed
+
+ ) : (
+
+ {propertyData.length === 0 ? (
+
No properties found
+ ) : (
+ propertyData.map((prop, idx) => (
+
+
+ Property ID: {prop?.propertyId}
+
+
+
+ Owner:
+ {prop?.owners[0]?.name || 'NA'}
+
+
+
+ Guardian:
+ {prop?.owners[0]?.fatherOrHusbandName || 'NA'}
+
+
+
+ {getAddressArray(prop.address)}
+
+
+
+ {prop?.status}
+
+
+
+
+ ))
+ )}
+
+ )}
+
+ );
+}
+
+export default DisplayPropertyRecord;
\ No newline at end of file
diff --git a/web/egov-common-screen/src/components/propertyQRData/function.jsx b/web/egov-common-screen/src/components/propertyQRData/function.jsx
index e3ffbe918f..0e4d070a84 100644
--- a/web/egov-common-screen/src/components/propertyQRData/function.jsx
+++ b/web/egov-common-screen/src/components/propertyQRData/function.jsx
@@ -1,11 +1,165 @@
-const checkMobileNumber = (number) => {
+import API from "./api";
+import { statetenantId, AUTHORIZATION_TOKEN} from "./constant";
+import { showSuccess, showError } from "../../utils/toast";
+import { storage } from "../../utils/localstorage";
+import { use } from "react";
+import axios from "axios";
+export const checkMobileNumber = async (number) => {
const mobileNumberPattern = /^[6-9]\d{9}$/;
const isMobileValid = mobileNumberPattern.test(number);
if(isMobileValid){
- // return number;
+ const data = await sendOtp(number);
+ //console.log("data",data)
}
}
+export const sendOtp = async (mobileNumber) => {
+ try {
+ const payload = createOtpPayload(mobileNumber,statetenantId);
+ const response = await API.post(
+ "/user-otp/v1/_send?tenantId=pb",
+ payload
+ );
+ // console.log("response",response.data)
+ showSuccess("Enter OTP");
-export default checkMobileNumber;
\ No newline at end of file
+ } catch (error) {
+ showError(
+ error?.response?.data?.Errors?.[0]?.message ||
+ "Failed to send OTP"
+ );
+ // return {
+ // success: false,
+ // message:
+ // error?.response?.data?.Errors?.[0]?.message ||
+ // "Failed to send OTP. Please try again.",
+ // };
+ }
+};
+
+const createOtpPayload = (mobileNumber, tenantId, userType='CITIZEN') => ({
+ otp: {
+ mobileNumber,
+ type: "login",
+ tenantId: tenantId,
+ userType: userType,
+ },
+});
+
+export const loginWithOtp = async (mobileNumber, otp, userType='CITIZEN') => {
+ try {
+ //debugger
+ // Create form-urlencoded body
+ const params = new URLSearchParams();
+ params.append("username", mobileNumber);
+ params.append("password", otp);
+ params.append("grant_type", "password");
+ params.append("scope", "read");
+ params.append("tenantId", statetenantId);
+ params.append("userType", userType);
+
+ const response = await axios.post(
+ "/user/oauth/token",
+ params,
+ {
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ Authorization: AUTHORIZATION_TOKEN,
+ },
+ }
+ );
+
+ if (response?.status === 200) {
+ return {
+ success: true,
+ message: "Login Successful",
+ data: response.data,
+ };
+ }
+
+ return {
+ success: false,
+ message: "Unexpected server response",
+ };
+
+ } catch (error) {
+ showError(error?.response?.data?.error_description ||
+ "Invalid OTP or login failed")
+ // return {
+ // success: false,
+ // message:
+ // error?.response?.data?.error_description ||
+ // "Invalid OTP or login failed",
+ // };
+ //
+ }
+};
+
+
+export const searchPropertyBySurvey = async ({ tenantId, surveyId }) => {
+ try {
+ const query = new URLSearchParams({
+ tenantId,
+ surveyId,
+ }).toString();
+
+ const response = await API.post(
+ `/property-services/property/_search?${query}`
+ );
+
+ return response?.data;
+ } catch (error) {
+ console.error(
+ "Property Search API Error:",
+ error?.response?.data || error.message
+ );
+ throw error;
+ }
+};
+
+export const getAddressArray = (propertyaddress) => {
+ if (!propertyaddress) return [];
+
+ const addressParts = [
+ propertyaddress.buildingName,
+ propertyaddress.doorNo !== propertyaddress.buildingName ? propertyaddress.doorNo : null,
+ propertyaddress.street,
+ propertyaddress.locality?.name,
+ propertyaddress.city,
+ propertyaddress.district,
+ propertyaddress.state,
+ propertyaddress.country,
+ propertyaddress.pincode,
+ ];
+
+ // Remove null, undefined, empty string
+ return addressParts.filter(Boolean);
+};
+
+export const setUserDetails = (userData, statetenantId)=>{
+ storage.set("user-info", userData.UserRequest);
+ storage.set("token", userData.access_token);
+ storage.set("tenant-id",statetenantId);
+ storage.set("refresh-token", userData.refresh_token);
+ storage.set("module", "rainmaker-common");
+ storage.set("locale", "en_IN");
+ storage.set("isNative",false);
+ storage.set("expires-in",userData.expires_in);
+ storage.set("CITIZEN.CITY",userData.UserRequest.permanentCity);
+ storage.set("path","");
+ storage.set("menuPath","");
+ storage.set("menuName","");
+ storage.set("Citizen.user-info", userData.UserRequest);
+ storage.set("Citizen.token", userData.access_token);
+ storage.set("Citizen.tenant-id",statetenantId);
+ storage.set("Citizen.refresh-token", userData.refresh_token);
+ storage.set("Citizen.module", "rainmaker-common");
+ storage.set("Citizen.locale", "en_IN");
+ storage.set("Citizen.isNative",false);
+ storage.set("Citizen.expires-in",userData.expires_in);
+ storage.set("Citizen.CITIZEN.CITY",userData.UserRequest.permanentCity);
+ storage.set("Citizen.path","");
+ storage.set("Citizen.menuPath","");
+ storage.set("Citizen.menuName","");
+}
\ No newline at end of file
diff --git a/web/egov-common-screen/src/components/propertyQRData/index.css b/web/egov-common-screen/src/components/propertyQRData/index.css
new file mode 100644
index 0000000000..2269f479b6
--- /dev/null
+++ b/web/egov-common-screen/src/components/propertyQRData/index.css
@@ -0,0 +1,213 @@
+.otp-container {
+ display: flex;
+ gap: 10px;
+ justify-content: center;
+}
+
+.otp-input {
+ width: 48px;
+ height: 48px;
+ border: 2px solid #ccc;
+ border-radius: 8px;
+ text-align: center;
+ font-size: 22px;
+ font-weight: 600;
+ outline: none;
+ transition: 0.2s;
+}
+
+.otp-input:focus {
+ border-color: #4f46e5;
+ box-shadow: 0 0 0 2px rgba(79, 70, 229, 0.2);
+}
+.otp-page {
+ min-height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: linear-gradient(135deg, #4f46e5, #06b6d4);
+ padding: 14px;
+}
+
+.otp-card {
+ background: white;
+ width: 100%;
+ max-width: 420px;
+ padding: 24px 20px;
+ border-radius: 14px;
+ box-shadow: 0 8px 28px rgba(0, 0, 0, 0.15);
+ text-align: center;
+}
+
+/* Typography */
+
+.otp-title {
+ font-size: 22px;
+ margin-bottom: 10px;
+}
+
+.otp-subtext {
+ font-size: 13px;
+ margin-bottom: 14px;
+}
+
+/* Info Box */
+
+.info-box {
+ font-size: 14px;
+ padding: 10px;
+ margin-bottom: 14px;
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: center;
+}
+
+/* Button */
+
+.verify-btn {
+ margin-top: 18px;
+ width: 100%;
+ padding: 12px;
+ border-radius: 10px;
+ font-size: 15px;
+}
+
+/* OTP Input Boxes */
+
+.otp-container {
+ gap: 8px;
+}
+
+.otp-input {
+ width: 42px;
+ height: 42px;
+ font-size: 18px;
+}
+
+/* Tablet */
+
+@media (min-width: 640px) {
+ .otp-card {
+ padding: 28px 24px;
+ }
+
+ .otp-title {
+ font-size: 24px;
+ }
+
+ .otp-input {
+ width: 48px;
+ height: 48px;
+ font-size: 20px;
+ }
+}
+
+/* Desktop */
+
+@media (min-width: 1024px) {
+ .otp-card {
+ max-width: 440px;
+ }
+}
+/* Container styling */
+.property_card-container {
+ display: flex;
+ flex-wrap: wrap; /* Allows wrapping */
+ gap: 20px;
+ padding: 20px;
+ justify-content: flex-start;
+}
+
+
+.property-card {
+ background: #ffffff;
+ border-radius: 16px;
+ padding: 20px;
+ width: 100%;
+ max-width: 320px;
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.08);
+ transition: all 0.3s ease;
+ border: 1px solid #f0f0f0;
+}
+
+.property-card:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 16px 35px rgba(0, 0, 0, 0.12);
+}
+
+/* Property ID */
+.property-id {
+ font-size: 18px;
+ font-weight: 700;
+ color: #2b2d42;
+ margin-bottom: 12px;
+}
+
+/* Label + Value row */
+.property-row {
+ margin-bottom: 8px;
+ font-size: 14px;
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.property-label {
+ font-weight: 600;
+ color: #6c757d;
+ margin-right: 6px;
+}
+
+.property-value {
+ color: #212529;
+ font-weight: 500;
+}
+
+/* Address */
+.property-address {
+ margin-top: 10px;
+ font-size: 14px;
+ color: #495057;
+ line-height: 1.5;
+}
+
+/* Status Badge */
+.status-badge {
+ display: inline-block;
+ padding: 4px 10px;
+ border-radius: 20px;
+ font-size: 12px;
+ font-weight: 600;
+ margin-top: 10px;
+}
+
+/* Status Colors */
+.status-active {
+ background: #e6f7ee;
+ color: #1b8a5a;
+}
+
+.status-inworkflow {
+ background: #fff4e5;
+ color: #d97706;
+}
+
+/* Button */
+.property-btn {
+ margin-top: 16px;
+ width: 100%;
+ padding: 10px 0;
+ border: none;
+ border-radius: 10px;
+ background: linear-gradient(135deg, #4f46e5, #6366f1);
+ color: #fff;
+ font-weight: 600;
+ font-size: 14px;
+ cursor: pointer;
+ transition: all 0.3s ease;
+}
+
+.property-btn:hover {
+ opacity: 0.9;
+ transform: translateY(-1px);
+}
\ No newline at end of file
diff --git a/web/egov-common-screen/src/components/propertyQRData/index.jsx b/web/egov-common-screen/src/components/propertyQRData/index.jsx
index 0a239b6ef5..143939029b 100644
--- a/web/egov-common-screen/src/components/propertyQRData/index.jsx
+++ b/web/egov-common-screen/src/components/propertyQRData/index.jsx
@@ -1,57 +1,112 @@
-import { useEffect, useState } from 'react';
+import { useEffect, useState, useRef } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import './index.css'
+import { useNavigate } from 'react-router-dom';
import OtpInput from './otpInput';
import { useSearchParams } from 'react-router-dom';
-import checkMobileNumber from './function.jsx'
+import { checkMobileNumber, loginWithOtp, setUserDetails } from './function.jsx'
+import { statetenantId } from "./constant.jsx"
//URL : propertyQRData?surveyid=123&tenantid=pb.amritsar&mobileno=9335130557
+import { showLoading, showError } from "../../utils/toast.jsx"
+import { storage } from '../../utils/localstorage.jsx';
const ProppertyQRData = () => {
- const [displaypage, setDisplaypage] = useState(true);
+ const Navigate = useNavigate();
+ const [displaypage, setDisplaypage] = useState(false);
const [loader, setLoader] = useState(false);
const [searchParams] = useSearchParams();
+ const [missingParams, setMissingParams] = useState(false);
+ const sentFor = useRef(null);
+ const errorShown = useRef(false);
// Extract date from query parameters
- const surveyID = searchParams.get('surveyid');
- const tenantId = searchParams.get('tenantid');
- const mobileNumber = searchParams.get('mobileno');
+ const surveyID = searchParams.get('surveyid');
+ const tenantId = searchParams.get('tenantid');
+ const mobileNumber = searchParams.get('mobileno');
+ useEffect(() => {
+ storage.clear();
+ }, [])
+ useEffect(() => {
+ if (!surveyID || !tenantId || !mobileNumber) {
+ if (!errorShown.current) { // Show error only once
+ showError("Please scan the QR code again");
+ errorShown.current = true;
+ }
+ setMissingParams(true);
+ return;
+ }
+ setMissingParams(false);
+ }, [surveyID, tenantId, mobileNumber]);
+ useEffect(() => {
+ if (loader) {
+ showLoading("Loading...");
+ }
+ }, [loader]);
+ useEffect(() => {
+ if (!mobileNumber) return;
+ if (sentFor.current === mobileNumber) return;
+ sentFor.current = mobileNumber
- useEffect(()=>{
- checkMobileNumber(mobileNumber)
- setDisplaypage(true)
- setLoader(false)
- }),[mobileNumber]
+ checkMobileNumber(mobileNumber).finally(() => setLoader(false))
+ setDisplaypage(true)
- const handleOtpComplete = (otp) => {
+ }), [mobileNumber]
+
+ const handleOtpComplete = async (otp) => {
console.log("OTP Entered:", otp);
+ const result = await loginWithOtp(mobileNumber, otp);
+ if (result.success) {
+ console.log("Access Token:", result);
+ // storage.set("user-info", result.data.UserRequest);
+ // storage.set("token", result.data.access_token);
+ // storage.set("tenant-id", statetenantId);
+ setUserDetails(result.data, statetenantId)
+ const qs = new URLSearchParams({
+ surveyid: surveyID,
+ tenantid: tenantId,
+ mobileno: mobileNumber,
+ }).toString();
+ Navigate(`/displayPropertyRecord?${qs}`, { replace: true });
+ // try {
+ // const data = await searchPropertyBySurvey({ tenantId: tenantId, surveyId: surveyID });
+
+ // console.log(data);
+ // } catch (err) {
+ // console.error("API Failed:", err);
+ // }
+ } else {
+ console.error(result.message);
+ }
};
- if(loader){
-//show loader
- }
return (
- {displaypage && (
-
-
-
OTP Verification
-
-
-
Survey ID: {surveyID}
-
Tenant ID: {tenantId}
-
Mobile: {mobileNumber}
-
-
-
- Enter the 6-digit OTP sent to your mobile
-
-
-
-
-
- )}
-
+ {missingParams ? (
+
+
Invalid QR Code
+
Please scan a valid QR code to proceed
+
+ ) : (
+ <>
+ {displaypage && !loader && (
+
+
OTP Verification
+
+
Survey ID: {surveyID}
+
Tenant ID: {tenantId}
+
Mobile: {mobileNumber}
+
+
+ Enter the 6-digit OTP sent to your mobile
+
+
+
+
+ )}
+ >
+ )}
+
)
}
export default ProppertyQRData;
\ No newline at end of file
diff --git a/web/egov-common-screen/src/utils/localstorage.jsx b/web/egov-common-screen/src/utils/localstorage.jsx
new file mode 100644
index 0000000000..00340b1cc2
--- /dev/null
+++ b/web/egov-common-screen/src/utils/localstorage.jsx
@@ -0,0 +1,43 @@
+export const storage = {
+ set: (key, value) => {
+ try {
+ const stringValue =
+ typeof value === "string" ? value : JSON.stringify(value);
+ localStorage.setItem(key, stringValue);
+ } catch (error) {
+ console.error("LocalStorage Set Error:", error);
+ }
+ },
+
+ get: (key) => {
+ try {
+ const value = localStorage.getItem(key);
+ if (!value) return null;
+
+ try {
+ return JSON.parse(value); // if object
+ } catch {
+ return value; // if normal string
+ }
+ } catch (error) {
+ console.error("LocalStorage Get Error:", error);
+ return null;
+ }
+ },
+
+ remove: (key) => {
+ try {
+ localStorage.removeItem(key);
+ } catch (error) {
+ console.error("LocalStorage Remove Error:", error);
+ }
+ },
+
+ clear: () => {
+ try {
+ localStorage.clear();
+ } catch (error) {
+ console.error("LocalStorage Clear Error:", error);
+ }
+ },
+};
\ No newline at end of file
diff --git a/web/egov-common-screen/src/utils/privateRoute.jsx b/web/egov-common-screen/src/utils/privateRoute.jsx
new file mode 100644
index 0000000000..14e0e85d99
--- /dev/null
+++ b/web/egov-common-screen/src/utils/privateRoute.jsx
@@ -0,0 +1,13 @@
+import { Navigate } from "react-router-dom";
+import { storage } from "./localstorage";
+
+const PrivateRoute = ({ children }) => {
+ const user = storage.get("user-info");
+ if (!user) {
+ return
;
+ }
+
+ return children;
+};
+
+export default PrivateRoute;
\ No newline at end of file
diff --git a/web/egov-common-screen/src/utils/toast.jsx b/web/egov-common-screen/src/utils/toast.jsx
new file mode 100644
index 0000000000..abbe54d8f2
--- /dev/null
+++ b/web/egov-common-screen/src/utils/toast.jsx
@@ -0,0 +1,13 @@
+import toast from "react-hot-toast";
+
+export const showSuccess = (message) => {
+ toast.success(message);
+};
+
+export const showError = (message) => {
+ toast.error(message);
+};
+
+export const showLoading = (message) => {
+ return toast.loading(message);
+};
\ No newline at end of file
diff --git a/web/egov-common-screen/vite.config.js b/web/egov-common-screen/vite.config.js
index 5714f8d393..8a3f795da9 100644
--- a/web/egov-common-screen/vite.config.js
+++ b/web/egov-common-screen/vite.config.js
@@ -1,12 +1,38 @@
-import { defineConfig } from 'vite'
-import react from '@vitejs/plugin-react'
-
-// https://vite.dev/config/
-export default defineConfig({
- plugins: [react()],
- base: '/common',
- server: {
- host: 'localhost',
- port: 3000,
- },
-})
+import { defineConfig, loadEnv } from "vite";
+import react from "@vitejs/plugin-react";
+
+export default defineConfig(({ mode }) => {
+ // Load environment variables
+ const env = loadEnv(mode, process.cwd());
+
+ return {
+ plugins: [react()],
+ base: "/common",
+
+ server: {
+ host: "localhost",
+ port: 3000,
+
+ proxy: {
+ "/user-otp": {
+ target: env.VITE_API_HOST,
+ changeOrigin: true,
+ secure: false,
+ rewrite: (path) => path.replace(/^\/api/, ""),
+ },
+ "/user": {
+ target: env.VITE_API_HOST,
+ changeOrigin: true,
+ secure: false,
+ rewrite: (path) => path.replace(/^\/api/, ""),
+ },
+ "/property-services": {
+ target: env.VITE_API_HOST,
+ changeOrigin: true,
+ secure: false,
+ rewrite: (path) => path.replace(/^\/api/, ""),
+ },
+ },
+ },
+ };
+});
\ No newline at end of file
diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/bulkmeterreading.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/bulkmeterreading.js
new file mode 100644
index 0000000000..f165bd0ca1
--- /dev/null
+++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/bulkmeterreading.js
@@ -0,0 +1,187 @@
+import {
+ getBreak, getCommonHeader, getLabel, getCommonCard,
+ getCommonContainer,
+ getTextField, getSelectField
+} from "egov-ui-framework/ui-config/screens/specs/utils";
+import { prepareFinalObject } from "egov-ui-framework/ui-redux/screen-configuration/actions";
+import { getTenantId } from "egov-ui-kit/utils/localStorageUtils";
+import { httpRequest } from "../../../../ui-utils";
+import { getBoundaryData } from "../../../../ui-utils/commons";
+import {
+ abgSearchCard,
+ //mergeDownloadButton,
+ resetFields
+} from "./gBmr/groupBillSearch";
+
+// import { updateAllReadings } from "./gBmr/functions";
+import { searchResults, updateAllReadings } from "./gBmr/searchResults";
+import "./index.css";
+
+const tenantId = getTenantId();
+
+const header = getCommonHeader({
+ labelName: "Bulk Meter Reading",
+ labelKey: "Bulk Meter Reading"
+});
+
+const getMDMSData = async (action, state, dispatch) => {
+ const tenantId = getTenantId();
+ let mdmsBody = {
+ MdmsCriteria: {
+ tenantId: tenantId,
+ moduleDetails: [
+ {
+ moduleName: "egf-master",
+ masterDetails: [
+ { name: "FinancialYear", filter: "[?(@.module=='PT')]" } //FY Filter hardcoded for PT
+ ]
+ },
+ {
+ moduleName: "BillingService",
+ masterDetails: [
+ {
+ name: "BusinessService"
+ // filter: "[?(@.type=='Adhoc')]"
+ },
+ {
+ name: "TaxHeadMaster"
+ },
+ {
+ name: "TaxPeriod"
+ }
+ ]
+ },
+ {
+ moduleName: "common-masters",
+ masterDetails: [
+ {
+ name: "uiCommonPay"
+ }
+ ]
+ },
+ {
+ moduleName: "tenant",
+ masterDetails: [
+ {
+ name: "tenants"
+ }
+ ]
+ }
+ ]
+ }
+ };
+ try {
+ const payload = await httpRequest(
+ "post",
+ "/egov-mdms-service/v1/_search",
+ "_search",
+ [],
+ mdmsBody
+ );
+ payload.MdmsRes.BillingService.BusinessService = payload.MdmsRes.BillingService.BusinessService.filter(service => service.billGineiURL);
+ dispatch(prepareFinalObject("searchScreenMdmsData", payload.MdmsRes));
+ } catch (e) {
+ console.log(e);
+ }
+};
+
+const getData = async (action, state, dispatch) => {
+ await getMDMSData(action, state, dispatch);
+};
+
+const abgSearchAndResult = {
+ uiFramework: "material-ui",
+ name: "bulkmeterreading",
+ beforeInitScreen: (action, state, dispatch) => {
+ resetFields(state, dispatch);
+ getData(action, state, dispatch).then(responseAction => {
+ const queryObj = [{ key: "tenantId", value: tenantId }];
+ getBoundaryData(action, state, dispatch, queryObj, tenantId);
+ });
+ return action;
+ },
+ components: {
+ div: {
+ uiFramework: "custom-atoms",
+ componentPath: "Form",
+ props: {
+ className: "common-div-css",
+ id: "bulkmeterreading"
+ },
+ children: {
+ headerDiv: {
+ uiFramework: "custom-atoms",
+ componentPath: "Container",
+
+ children: {
+ header: {
+ gridDefination: {
+ xs: 12,
+ sm: 6
+ },
+ ...header
+ }
+ }
+ },
+ abgSearchCard,
+ breakAfterSearch: getBreak(),
+ // progressStatus,
+ searchResults,
+ breakAfterSearchResults: getBreak(),
+
+ button: getCommonContainer({
+ buttonContainer: getCommonContainer({
+ firstCont: {
+ uiFramework: "custom-atoms",
+ componentPath: "Div",
+ gridDefination: {
+ xs: 12,
+ sm: 3
+ }
+ },
+
+ updateAllButton: {
+ componentPath: "Button",
+ gridDefination: {
+ xs: 12,
+ sm: 3
+ },
+ props: {
+ variant: "contained",
+ style: {
+ color: "white",
+ backgroundColor: "#FE7A51",
+ borderRadius: "2px",
+ width: window.innerWidth > 480 ? "80%" : "100%",
+ height: "48px"
+ }
+ },
+ children: {
+ buttonLabel: getLabel({
+ labelName: "Update All Readings",
+ labelKey: "Update All Readings"
+ })
+ },
+ onClickDefination: {
+ action: "condition",
+ callBack: updateAllReadings
+ }
+ },
+ lastCont: {
+ uiFramework: "custom-atoms",
+ componentPath: "Div",
+ gridDefination: {
+ xs: 12,
+ sm: 3
+ }
+ }
+ })
+ })
+
+ }
+ },
+ //mergeDownloadButton
+ }
+};
+
+export default abgSearchAndResult;
diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/functions.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/functions.js
new file mode 100644
index 0000000000..90c428682a
--- /dev/null
+++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/functions.js
@@ -0,0 +1,232 @@
+import get from "lodash/get";
+//import { getGroupBillSearch } from "../../../../../ui-utils/commons";
+import {
+ handleScreenConfigurationFieldChange as handleField,
+ prepareFinalObject,
+ toggleSpinner,
+ toggleSnackbar
+} from "egov-ui-framework/ui-redux/screen-configuration/actions";
+import { httpRequest } from "egov-ui-framework/ui-utils/api";
+import {
+ convertEpochToDate,
+ validateFields,
+ getTextToLocalMapping
+} from "../../utils/index";
+import { getTenantId, getUserInfo } from "egov-ui-kit/utils/localStorageUtils";
+import isEmpty from "lodash/isEmpty"
+import { loadUlbLogo } from "../../utils/receiptTransformer";
+
+// const tenantId = getTenantId();
+const tenantId = getTenantId();
+export const updatesingleReading = async (consumerId, lastReading, currentReadingRaw, currentReading, billingPeriod, status, readingDate, lastReadingDate, tenantId) => {
+
+ const payload = {
+ meterReadingslist: [
+ {
+ currentReadingDate: readingDate,
+ currentReading: currentReading,
+ billingPeriod: billingPeriod,
+ meterStatus: status,
+ connectionNo: consumerId,
+ lastReading: lastReading,
+ lastReadingDate: lastReadingDate,
+ tenantId: tenantId,
+ generateDemand: true
+ }
+ ]
+
+
+ };
+ try {
+ const url = "/ws-calculator/meterConnection/_createmultiple";
+
+
+ const response = await httpRequest("post", url, "_update", [], payload);
+
+
+ return response;
+ } catch (e) {
+ console.error("API error:", e);
+ throw e;
+ }
+};
+
+export const searchApiCall = async (state, dispatch) => {
+
+ showHideTable(false, dispatch);
+ //showHideMergeButton(false, dispatch);
+ let searchScreenObject = get(
+ state.screenConfiguration.preparedFinalObject,
+ "searchCriteria",
+ {}
+ );
+ const isSearchBoxFirstRowValid = validateFields(
+ "components.div.children.abgSearchCard.children.cardContent.children.searchContainer.children",
+ state,
+ dispatch,
+ "bulkmeterreading"
+ );
+
+ const isSearchBoxSecondRowValid = validateFields(
+ "components.div.children.abgSearchCard.children.cardContent.children.searchContainer.children",
+ state,
+ dispatch,
+ "bulkmeterreading"
+ );
+
+ if (!(isSearchBoxFirstRowValid && isSearchBoxSecondRowValid)) {
+ dispatch(
+ toggleSnackbar(
+ true,
+ {
+ labelName: "Please fill at least one field to start search",
+ labelKey: "ABG_SEARCH_SELECT_AT_LEAST_ONE_TOAST_MESSAGE"
+ },
+ "warning"
+ )
+ );
+ } else if (
+ Object.keys(searchScreenObject).length == 0 ||
+ Object.values(searchScreenObject).every(x => x === "")
+ ) {
+ dispatch(
+ toggleSnackbar(
+ true,
+ {
+ labelName: "Please fill at least one field to start search",
+ labelKey: "ABG_SEARCH_SELECT_AT_LEAST_ONE_TOAST_MESSAGE"
+ },
+ "warning"
+ )
+ );
+ } else {
+ for (var key in searchScreenObject) {
+ if (
+ searchScreenObject.hasOwnProperty(key) &&
+ searchScreenObject[key] === ""
+ ) {
+ delete searchScreenObject[key];
+ }
+ }
+ let serviceObject = get(
+ state.screenConfiguration.preparedFinalObject,
+ "searchScreenMdmsData.BillingService.BusinessService"
+ ).filter(item => item.code === searchScreenObject.businesService);
+
+ searchScreenObject.url = serviceObject && serviceObject[0] && serviceObject[0].billGineiURL;
+ searchScreenObject.tenantId = process.env.REACT_APP_NAME === "Employee" ? getTenantId() : JSON.parse(getUserInfo()).permanentCity;
+ const getGroupBillSearch = async (dispatch, searchScreenObject) => {
+
+ try {
+ dispatch(toggleSpinner(true));
+ const requestBody = {
+ tenantId: searchScreenObject.tenantId || tenantId,
+ locality: searchScreenObject.locality || "",
+ offset: searchScreenObject.offset !== undefined ? searchScreenObject.offset : 0
+ };
+ const url = `ws-calculator/meterConnection/_searchV2?tenantId=${encodeURIComponent(requestBody.tenantId)}&locality=${encodeURIComponent(requestBody.locality)}&offset=${encodeURIComponent(requestBody.offset)}`;
+ const response = await httpRequest("post", url, "_searchV2", []);
+ // dispatch(toggleSpinner(false));
+ // return response;
+
+ const bills = (response && response.meterReadings) || [];
+ dispatch(
+ prepareFinalObject("searchScreenMdmsData.meterReadings", bills)
+ );
+ dispatch(toggleSpinner(false));
+ return response;
+ } catch (error) {
+ dispatch(toggleSpinner(false));
+ dispatch(
+ toggleSnackbar(
+ true,
+ { labelName: error.message || "Something went wrong", labelKey: error.message || "ERROR" },
+ "error"
+ )
+ );
+ return {};
+ }
+
+
+ };
+ const responseFromAPI = await getGroupBillSearch(dispatch, searchScreenObject);
+
+
+ const bills = (responseFromAPI && responseFromAPI.meterReadings) || [];
+ dispatch(
+ prepareFinalObject("searchScreenMdmsData.billSearchResponse", bills)
+ );
+ const response = [];
+ for (let i = 0; i < bills.length; i++) {
+
+ response.push({
+ connectionNo: get(bills[i], "connectionNo"),
+
+ lastReading: get(bills[i], "currentReading"),
+ // currentReading may come from API (per consumer). Use existing field if present.
+ currentReading: get(bills[i], "currentReading") || "",
+ currentReadingDate: get(bills[i], "currentReadingDate"),
+ billingPeriod: get(bills[i], "billingPeriod"),
+ meterStatus: get(bills[i], "meterStatus"),
+ tenantId: tenantId
+ })
+
+ }
+ try {
+ let data = response.map(item => ({
+ ["Consumer ID"]: item.connectionNo || "-",
+
+ // last confirmed reading from system
+ ["Last Reading"]: item.currentReading || "-",
+
+ // user will enter these for bulk update; keep empty initially
+ ["New Reading(in KL)"]: "",
+ ["New Reading Date"]: "",
+
+ // existing reading date from system
+ ["Current Reading Date"]:
+ convertEpochToDate(item.currentReadingDate) || "-",
+ ["Billing Period"]: item.billingPeriod || "-",
+ ["Status"]: item.meterStatus || "-",
+ ["TENANT_ID"]: item.tenantId
+ }));
+ dispatch(
+ handleField(
+ "bulkmeterreading",
+ "components.div.children.searchResults",
+ "props.data",
+ data
+ )
+ );
+ dispatch(
+ handleField(
+ "bulkmeterreading",
+ "components.div.children.searchResults",
+ "props.rows",
+ data.length
+ )
+ );
+ showHideTable(true, dispatch);
+ if (!isEmpty(response)) {
+
+ loadUlbLogo(tenantId);
+ };
+ } catch (error) {
+ dispatch(toggleSnackbar(true, error.message, "error"));
+ console.log(error);
+ }
+ }
+};
+
+const showHideTable = (booleanHideOrShow, dispatch) => {
+ dispatch(
+ handleField(
+ "bulkmeterreading",
+ "components.div.children.searchResults",
+ "visible",
+ booleanHideOrShow
+ )
+ );
+};
+
+
diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/groupBillSearch.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/groupBillSearch.js
new file mode 100644
index 0000000000..a8bc0a1ca8
--- /dev/null
+++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/groupBillSearch.js
@@ -0,0 +1,249 @@
+import {
+ getCommonCard,
+ getCommonContainer,
+ getLabel, getTextField, getSelectField
+} from "egov-ui-framework/ui-config/screens/specs/utils";
+import { handleScreenConfigurationFieldChange as handleField } from "egov-ui-framework/ui-redux/screen-configuration/actions";
+import { getTenantId, getUserInfo } from "egov-ui-kit/utils/localStorageUtils";
+import { generateMultipleBill } from "../../utils/receiptPdf";
+import { searchApiCall, updatesingleReading } from "./functions";
+
+
+const tenantId = process.env.REACT_APP_NAME === "Employee" ? getTenantId() : JSON.parse(getUserInfo()).permanentCity;
+export const resetFields = (state, dispatch) => {
+
+ dispatch(
+ handleField(
+ "bulkmeterreading",
+ "components.div.children.abgSearchCard.children.cardContent.children.searchContainer.children.ulb",
+ "props.value",
+ tenantId
+ )
+ );
+ dispatch(
+ handleField(
+ "bulkmeterreading",
+ "components.div.children.abgSearchCard.children.cardContent.children.searchContainer.children.consumerId",
+ "props.value",
+ ""
+ )
+ );
+ dispatch(
+ handleField(
+ "bulkmeterreading",
+ "components.div.children.abgSearchCard.children.cardContent.children.searchContainer.children.locMohalla",
+ "props.value",
+ ""
+ )
+ );
+ dispatch(
+ handleField(
+ "bulkmeterreading",
+ "components.div.children.abgSearchCard.children.cardContent.children.searchContainer.children.locMohalla",
+ "props.error",
+ false
+ )
+ );
+ dispatch(
+ handleField(
+ "bulkmeterreading",
+ "components.div.children.abgSearchCard.children.cardContent.children.searchContainer.children.locMohalla",
+ "props.helperText",
+ ""
+ )
+ );
+ dispatch(
+ handleField(
+ "bulkmeterreading",
+ "components.div.children.abgSearchCard.children.cardContent.children.searchContainer.children.serviceCategory",
+ "props.value",
+ ""
+ )
+ );
+ dispatch(
+ handleField(
+ "bulkmeterreading",
+ "components.div.children.abgSearchCard.children.cardContent.children.searchContainer.children.serviceCategory",
+ "props.error",
+ false
+ )
+ );
+ dispatch(
+ handleField(
+ "bulkmeterreading",
+ "components.div.children.abgSearchCard.children.cardContent.children.searchContainer.children.serviceCategory",
+ "props.helperText",
+ ""
+ )
+ );
+};
+
+export const abgSearchCard = getCommonCard({
+ searchContainer: getCommonContainer(
+ {
+ ulb: {
+ uiFramework: "custom-containers-local",
+ moduleName: "egov-abg",
+ componentPath: "AutosuggestContainer",
+ props: {
+ label: {
+ labelName: "ULB",
+ labelKey: "ABG_ULB_LABEL"
+ },
+ localePrefix: {
+ moduleName: "TENANT",
+ masterName: "TENANTS"
+ },
+ optionLabel: "name",
+ placeholder: {
+ labelName: "Select ULB",
+ labelKey: "ABG_ULB_PLACEHOLDER"
+ },
+ required: true,
+ value: tenantId,
+ disabled: true,
+ isClearable: true,
+ labelsFromLocalisation: true,
+ className: "autocomplete-dropdown",
+ jsonPath: "searchCriteria.tenantId",
+ sourceJsonPath: "searchScreenMdmsData.tenant.tenants",
+ },
+ required: true,
+ jsonPath: "searchCriteria.tenantId",
+ disabled: false,
+ gridDefination: {
+ xs: 12,
+ sm: 4
+ }
+ },
+
+ locMohalla: {
+ uiFramework: "custom-containers-local",
+ moduleName: "egov-abg",
+ componentPath: "AutosuggestContainer",
+ gridDefination: {
+ xs: 12,
+ sm: 4
+ },
+ jsonPath: "searchCriteria.locality",
+ required: true,
+ props: {
+ className: "autocomplete-dropdown",
+ label: {
+ labelName: "Location/Mohalla",
+ labelKey: "ABG_LOCMOHALLA_LABEL"
+ },
+ placeholder: {
+ labelName: "Select Location/Mohalla",
+ labelKey: "ABG_LOCMOHALLA_PLACEHOLDER"
+ },
+ jsonPath: "searchCriteria.locality",
+ sourceJsonPath: "searchScreenMdmsData.localities",
+ labelsFromLocalisation: true,
+ required: true,
+ isClearable: true,
+ }
+ },
+ // consumerId: getTextField({
+ // label: {
+ // labelName: "Consumer ID",
+ // labelKey: "ABG_CONSUMER_ID_LABEL"
+ // },
+ // placeholder: {
+ // labelName: "Enter Consumer ID",
+ // labelKey: "ABG_CONSUMER_ID_PLACEHOLDER"
+ // },
+ // gridDefination: {
+ // xs: 12,
+ // sm: 4
+ // },
+ // required: false,
+ // jsonPath: "searchCriteria.consumerCode"
+ // })
+
+ },
+ {
+ style: {
+ overflow: "visible"
+ }
+ }
+ ),
+
+ button: getCommonContainer({
+ buttonContainer: getCommonContainer({
+ firstCont: {
+ uiFramework: "custom-atoms",
+ componentPath: "Div",
+ gridDefination: {
+ xs: 12,
+ sm: 3
+ }
+ },
+ resetButton: {
+ componentPath: "Button",
+ gridDefination: {
+ xs: 12,
+ sm: 3
+ },
+ props: {
+ variant: "outlined",
+ style: {
+ color: "#FE7A51",
+ border: "#FE7A51 solid 1px",
+ borderRadius: "2px",
+ width: window.innerWidth > 480 ? "80%" : "100%",
+ height: "48px"
+ }
+ },
+ children: {
+ buttonLabel: getLabel({
+ labelName: "RESET",
+ labelKey: "ABG_RESET_BUTTON"
+ })
+ },
+ onClickDefination: {
+ action: "condition",
+ callBack: resetFields
+ }
+ },
+ searchButton: {
+ componentPath: "Button",
+ gridDefination: {
+ xs: 12,
+ sm: 3
+ // align: "center"
+ },
+ props: {
+ variant: "contained",
+ style: {
+ color: "white",
+ backgroundColor: "#FE7A51",
+ borderRadius: "2px",
+ width: window.innerWidth > 480 ? "80%" : "100%",
+ height: "48px"
+ }
+ },
+ children: {
+ buttonLabel: getLabel({
+ labelName: "Search",
+ labelKey: "ABG_GROUP_BILL_SEARCH_BUTTON"
+ })
+ },
+ onClickDefination: {
+ action: "condition",
+ callBack: searchApiCall
+ }
+ },
+ lastCont: {
+ uiFramework: "custom-atoms",
+ componentPath: "Div",
+ gridDefination: {
+ xs: 12,
+ sm: 3
+ }
+ }
+ })
+ })
+});
+
+
diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/searchResults.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/searchResults.js
new file mode 100644
index 0000000000..da0b33f93d
--- /dev/null
+++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/searchResults.js
@@ -0,0 +1,343 @@
+import React from "react";
+import get from "lodash/get";
+import { sortByEpoch, getEpochForDate } from "../../utils";
+import { generateSingleBill } from "../../utils/receiptPdf";
+import { httpRequest } from "egov-ui-framework/ui-utils/api.js";
+import { localStorageGet } from "egov-ui-kit/utils/localStorageUtils";
+import { download, downloadBill } from "egov-common/ui-utils/commons";
+import { updatesingleReading } from "./functions";
+
+
+export const searchResults = {
+ uiFramework: "custom-molecules",
+ componentPath: "Table",
+ visible: false,
+ props: {
+ columns: [
+ { labelName: "Consumer ID", labelKey: "Consumer ID" },
+
+ { labelName: "Last Reading", labelKey: "Last Reading" },
+ { labelName: "Current Reading Date", labelKey: "Current Reading Date" },
+ {
+ labelName: "New Reading(in KL)",
+ labelKey: "New Reading(in KL)",
+ options: {
+ filter: false,
+ customBodyRender: (value, tableMeta, updateValue) => {
+ // Last Reading is the second column (index 1)
+ const lastReading = tableMeta.rowData && tableMeta.rowData[1];
+ const status = tableMeta.rowData && tableMeta.rowData[6];
+ const isEditable = ["Working", "Breakdown", "Locked"].includes(status);
+ return (
+
{
+ e.target.value = e.target.value.replace(/[^0-9]/g, "");
+ }}
+ onBlur={e => {
+ if (!isEditable) return;
+ const v = e.target.value.trim();
+ if (v === "") { updateValue(""); return; }
+ const numeric = Number(v);
+ const min = Number(lastReading || 0);
+ if (!Number.isFinite(numeric) || numeric < min) {
+ // reset and notify user
+ e.target.value = "";
+ updateValue("");
+ alert("Please enter a numeric value greater than or equal to Last Reading");
+ } else {
+ updateValue(v);
+ }
+ }}
+ />
+ );
+ }
+ }
+ },
+ {
+ labelName: "New Reading Date",
+ labelKey: "New Reading Date",
+ options: {
+ filter: false,
+ customBodyRender: (value, tableMeta, updateValue) => {
+ // Disable dates earlier than Current Reading Date for that row
+ const currentReadingDateDisplay =
+ tableMeta.rowData && tableMeta.rowData[2]; // e.g. "05/02/2026"
+ const status = tableMeta.rowData && tableMeta.rowData[6];
+ const isEditable = ["Working", "Breakdown", "Locked"].includes(status);
+
+ let minDate = "";
+ if (
+ currentReadingDateDisplay &&
+ currentReadingDateDisplay !== "-" &&
+ currentReadingDateDisplay.indexOf("/") > -1
+ ) {
+ const [dd, mm, yyyy] = currentReadingDateDisplay.split("/");
+ if (dd && mm && yyyy) {
+ minDate = `${yyyy}-${mm.padStart(2, "0")}-${dd.padStart(2, "0")}`;
+ }
+ }
+ return (
+
{
+ if (!isEditable) return;
+ updateValue(e.target.value);
+ }}
+ />
+ );
+ }
+ }
+ },
+
+ { labelName: "Billing Period", labelKey: "Billing Period" },
+ {
+ labelName: "Status",
+ labelKey: "Status",
+ options: {
+ filter: false,
+ customBodyRender: (value, tableMeta, updateValue) => {
+ const statusOptions = [
+ "Working",
+ "Locked",
+ "No-meter",
+ "Breakdown",
+ "No_Meter",
+ "Reset",
+ "NULL",
+ "Replacement"
+ ];
+ const currentStatus = value || "";
+ return (
+
+ );
+ }
+ }
+ },
+ {
+ labelName: "Tenant Id",
+ labelKey: "TENANT_ID",
+ options: {
+ display: false
+ }
+ },
+ {
+ labelName: "Action",
+ labelKey: "ABG_COMMON_TABLE_COL_ACTION",
+ options: {
+ filter: false,
+ customBodyRender: (value, tableMeta, updateValue) => {
+ let readingDatenew = tableMeta.rowData && tableMeta.rowData[4] ? tableMeta.rowData[4] : null;
+ readingDatenew = readingDatenew ? readingDatenew.split("-").reverse().join("/") : null;
+ const handleUpdate = async () => {
+ const consumerId = tableMeta.rowData && tableMeta.rowData[0];
+ const lastReading = Number(tableMeta.rowData && tableMeta.rowData[1]) || 0;
+ const currentReadingDate = tableMeta.rowData && tableMeta.rowData[2] ? getEpochForDate(tableMeta.rowData[2]) : null;
+ const lastReadingDate = currentReadingDate;
+ const currentReadingRaw = Number(tableMeta.rowData && tableMeta.rowData[3]) || 0;
+ const currentReading = Number(currentReadingRaw) || 0;
+ const billingPeriod = readingDatenew ? `${tableMeta.rowData[2]} - ${readingDatenew}` : "";
+ const readingDate = readingDatenew ? getEpochForDate(readingDatenew) : null;
+ const statusSelects = document.querySelectorAll("select.bulk-status-select");
+ const statusFromSelect = statusSelects[tableMeta.rowIndex] && statusSelects[tableMeta.rowIndex].value;
+ const status = statusFromSelect || (tableMeta.rowData && tableMeta.rowData[6]) || "";
+ const tenantId = tableMeta.rowData && tableMeta.rowData[7];
+ if (!currentReadingRaw || !Number.isFinite(currentReading)) {
+ alert("Please enter a numeric Current Reading greater than or equal to Last Reading before updating");
+ return;
+ }
+
+ if (currentReading < lastReading) {
+ alert("Please enter a numeric Current Reading greater than or equal to Last Reading before updating");
+ return;
+ }
+
+ // New Reading Date must not be earlier than Current Reading Date
+ if (readingDate && currentReadingDate && readingDate < currentReadingDate) {
+ alert("New Reading Date cannot be earlier than Current Reading Date");
+ return;
+ }
+
+ try {
+ const resp = await updatesingleReading(consumerId, lastReading, currentReadingRaw, currentReading, billingPeriod, status, readingDate, lastReadingDate, tenantId);
+ // updatesingleReading may return response or throw on error
+ alert("Update successful for Consumer ID: " + (consumerId || ""));
+ } catch (err) {
+ console.error(err);
+ alert("Update failed: " + (err && err.message ? err.message : "Unknown error"));
+ }
+ };
+
+ return (
+
+ );
+ }
+ }
+ },
+ ],
+ title: { labelName: "Search Results for Group Bills", labelKey: "BILL_GENIE_GROUP_SEARCH_HEADER" },
+ rows: "",
+ options: {
+ filter: false,
+ download: false,
+ responsive: "stacked",
+ pagination: false,
+ selectableRows: false,
+ hover: true,
+ rowsPerPageOptions: [10, 15, 20],
+ },
+ customSortColumn: {
+ column: "Date Created",
+ sortingFn: (data, i, sortDateOrder) => {
+ const epochDates = data.reduce((acc, curr) => {
+ acc.push([...curr, getEpochForDate(curr[2], "dayend")]);
+ return acc;
+ }, []);
+ const order = sortDateOrder === "asc" ? true : false;
+ const finalData = sortByEpoch(epochDates, !order).map(item => {
+ item.pop();
+ return item;
+ });
+ return { data: finalData, currentOrder: !order ? "asc" : "desc" };
+ }
+ }
+ }
+};
+export const updateAllReadings = async (state, dispatch) => {
+
+ let allarray = [];
+
+ // get table data from screen config
+ const rows = get(
+ state,
+ "screenConfiguration.screenConfig.bulkmeterreading.components.div.children.searchResults.props.data",
+ []
+ );
+
+ // read the live values typed in the table inputs
+ const readingInputs = document.querySelectorAll("input.bulk-new-reading");
+ const dateInputs = document.querySelectorAll("input.bulk-new-reading-date");
+ const statusSelects = document.querySelectorAll("select.bulk-status-select");
+
+ for (let i = 0; i < rows.length; i++) {
+ const row = rows[i];
+
+ // Support both object-style rows and array-style rows
+ const isArrayRow = Array.isArray(row);
+
+ const consumerId = isArrayRow ? row[0] : row["Consumer ID"];
+ const lastReading = Number(isArrayRow ? row[1] : row["Last Reading"]) || 0;
+
+ // New reading / date: always take what user typed in the row inputs
+ const currentReadingRawEl = readingInputs[i];
+ const newReadingDateEl = dateInputs[i];
+ const currentReadingRaw = currentReadingRawEl ? currentReadingRawEl.value : "";
+ const newReadingDate = newReadingDateEl ? newReadingDateEl.value : "";
+
+ const currentReadingDateDisplay = isArrayRow ? row[2] : row["Current Reading Date"];
+ const lastReadingDate = getEpochForDate(currentReadingDateDisplay);
+ const statusFromRow = isArrayRow ? row[6] : row["Status"];
+ const status = statusSelects[i] && statusSelects[i].value ? statusSelects[i].value : statusFromRow;
+ const tenantId = isArrayRow ? row[7] : row["TENANT_ID"];
+
+ // only allow bulk update for selected meter statuses
+ const isEditableStatus = ["Working", "Breakdown", "Locked"].includes(status);
+ if (!isEditableStatus) {
+ continue;
+ }
+
+ // only take complete rows (both value and date filled)
+ if (!currentReadingRaw || !newReadingDate) {
+ continue;
+ }
+
+ const currentReading = Number(currentReadingRaw) || 0;
+
+ // skip invalid readings
+ if (!Number.isFinite(currentReading) || currentReading < lastReading) {
+ continue;
+ }
+
+ const readingDatenew = newReadingDate
+ ? newReadingDate.split("-").reverse().join("/")
+ : null;
+ const billingPeriod =
+ readingDatenew && currentReadingDateDisplay
+ ? `${currentReadingDateDisplay} - ${readingDatenew}`
+ : "";
+ const readingDate = readingDatenew ? getEpochForDate(readingDatenew) : null;
+
+ // New Reading Date must not be earlier than Current Reading Date
+ const currentReadingDateEpoch = currentReadingDateDisplay
+ ? getEpochForDate(currentReadingDateDisplay)
+ : null;
+ if (readingDate && currentReadingDateEpoch && readingDate < currentReadingDateEpoch) {
+ // skip this row if date is invalid
+ continue;
+ }
+
+ // push only complete row into array
+ allarray.push({
+ consumerId,
+ lastReading,
+ newReading: currentReadingRaw,
+ newReadingDate,
+ currentReadingDate: currentReadingDateDisplay,
+ lastReadingDate,
+ billingPeriod,
+ status,
+ tenantId,
+ readingDate
+ });
+
+ // call single update API
+ try {
+ await updatesingleReading(
+ consumerId,
+ lastReading,
+ currentReadingRaw,
+ currentReading,
+ billingPeriod,
+ status,
+ readingDate,
+ lastReadingDate,
+ tenantId
+ );
+ } catch (err) {
+ console.error(`Failed to update Consumer ${consumerId}:`, err);
+ }
+ }
+
+
+ return allarray;
+};
\ No newline at end of file
diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/groupBills.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/groupBills.js
index 59b2196714..15cd8e4161 100644
--- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/groupBills.js
+++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/groupBills.js
@@ -145,8 +145,8 @@ const abgSearchAndResult = {
? `/egov-ui-framework/abg/groupBillDownloads`
: `/abg/groupBillDownloads`
},
- //visible: (process.env.REACT_APP_NAME === "Citizen") ? false : true
- visible: false
+ visible: (process.env.REACT_APP_NAME === "Citizen") ? false : true
+ //visible: false
}
}
},
diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/propertyMapped/functions.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/propertyMapped/functions.js
index ccd3dff1ee..e5e75324f8 100644
--- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/propertyMapped/functions.js
+++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/propertyMapped/functions.js
@@ -40,7 +40,7 @@ export const updatesingleReading = async (consumerId, tenantId, currentReading,
process.env.NODE_ENV === "development"
? "/ws-calculator/meterReading/_update"
: "/ws-calculator/meterReading/_update";
-
+
return Promise.resolve({ success: true, data: payload });
} catch (e) {
console.error(e);
@@ -151,7 +151,7 @@ export const showViewPopup = (state, dispatch, rowObject = {}) => {
}
};
export const searchApiCall = async (state, dispatch) => {
- debugger;
+
showHideTable(false, dispatch);
//showHideMergeButton(false, dispatch);
let searchScreenObject = get(
@@ -232,10 +232,10 @@ export const searchApiCall = async (state, dispatch) => {
if (serviceObject[0] && serviceObject[0].billGineiURL) {
searchScreenObject.url = serviceObject[0].billGineiURL;
}
- searchScreenObject.tenantId = process.env.REACT_APP_NAME === "Employee" ? getTenantId() : JSON.parse(getUserInfo()).permanentCity;
+ if (getTenantId() != "pb.punjab") {
+ searchScreenObject.tenantId = process.env.REACT_APP_NAME === "Employee" ? getTenantId() : JSON.parse(getUserInfo()).permanentCity;
+ }
const getGroupBillSearch = async (dispatch, searchScreenObject) => {
- debugger;
-
try {
dispatch(toggleSpinner(true));
const requestBody = {
@@ -256,9 +256,6 @@ export const searchApiCall = async (state, dispatch) => {
}
const response = await httpRequest("post", url, "_search", []);
- // dispatch(toggleSpinner(false));
- // return response;
- debugger;
const ptreveresponce = (response && response) || [];
dispatch(
prepareFinalObject("searchScreenMdmsData.ptreveresponce", ptreveresponce)
@@ -456,7 +453,7 @@ export const searchApiCall = async (state, dispatch) => {
["TENANT_ID"]: item.tenantId
}));
-
+
dispatch(
handleField(
"ptmapped",
@@ -474,12 +471,12 @@ export const searchApiCall = async (state, dispatch) => {
)
);
showHideTable(true, dispatch);
-
+
try {
const store = require("egov-ui-framework/ui-redux/store").default;
const current = store.getState();
const cfg = (current && current.screenConfiguration && current.screenConfiguration.screenConfig && current.screenConfiguration.screenConfig.ptmapped && current.screenConfiguration.screenConfig.ptmapped.components && current.screenConfiguration.screenConfig.ptmapped.components.div && current.screenConfiguration.screenConfig.ptmapped.components.div.children && current.screenConfiguration.screenConfig.ptmapped.components.div.children.searchResults) || {};
-
+
} catch (e) {
console.warn("searchApiCall: could not read store for debug:", e);
}
diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/propertyMapped/groupBillSearch.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/propertyMapped/groupBillSearch.js
index 14209d4b23..9a2e30168b 100644
--- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/propertyMapped/groupBillSearch.js
+++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/propertyMapped/groupBillSearch.js
@@ -3,11 +3,12 @@ import {
getCommonContainer,
getLabel, getTextField, getSelectField
} from "egov-ui-framework/ui-config/screens/specs/utils";
-import { handleScreenConfigurationFieldChange as handleField } from "egov-ui-framework/ui-redux/screen-configuration/actions";
+import { handleScreenConfigurationFieldChange as handleField, prepareFinalObject } from "egov-ui-framework/ui-redux/screen-configuration/actions";
import { getTenantId, getUserInfo } from "egov-ui-kit/utils/localStorageUtils";
import { generateMultipleBill } from "../../utils/receiptPdf";
import { searchApiCall, updatesingleReading } from "./functions";
-
+import get from "lodash/get";
+import { httpRequest } from "../../../../../ui-utils";
const tenantvalueid = [{ name: getTenantId(), code: getTenantId() }];
const tenantId = process.env.REACT_APP_NAME === "Employee" ? getTenantId() : JSON.parse(getUserInfo()).permanentCity;
export const resetFields = (state, dispatch) => {
@@ -109,12 +110,45 @@ export const abgSearchCard = getCommonCard({
},
required: true,
value: tenantId,
- disabled: true,
+ isDisabled: getTenantId() === "pb.punjab" ? false : true,
+ readOnly: getTenantId() === "pb.punjab" ? false : true,
isClearable: false,
- labelsFromLocalisation: true,
+ labelsFromLocalisation: getTenantId() === "pb.punjab" ? false : true,
className: "autocomplete-dropdown",
jsonPath: "searchCriteria.tenantId",
- data: tenantvalueid,
+ sourceJsonPath: "searchScreenMdmsData.tenant.tenants",
+
+ },
+ afterFieldChange: async (action, state, dispatch) => {
+ let selecttetentid = await get(state, "screenConfiguration.preparedFinalObject.searchCriteria.tenantId");
+
+ if (true) {
+ try {
+ let response = await httpRequest(
+ "post",
+ "/egov-location/location/v11/boundarys/_search?hierarchyTypeCode=REVENUE&boundaryType=Locality",
+ "_search",
+ [{ key: "tenantId", value: selecttetentid }],
+ {}
+ );
+ let mohallaDataArray = [];
+ let localitysar = [];
+ let mohallaDataRow = null;
+ let name, code;
+ response.TenantBoundary[0].boundary.map((element, index) => {
+
+ mohallaDataRow = { "code": element.code, "name": element.name };
+ mohallaDataArray.push(mohallaDataRow);
+
+ });
+
+ dispatch(prepareFinalObject("searchScreenMdmsData.localities", mohallaDataArray));
+
+ } catch (e) {
+ console.log(e);
+ }
+ }
+
},
required: true,
@@ -148,7 +182,8 @@ export const abgSearchCard = getCommonCard({
},
jsonPath: "searchCriteria.locality",
sourceJsonPath: "searchScreenMdmsData.localities",
- labelsFromLocalisation: true,
+ labelsFromLocalisation: getTenantId() === "pb.punjab" ? false : true,
+
required: false,
isClearable: true,
}
diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/propertyMapped/ptmapedPopup.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/propertyMapped/ptmapedPopup.js
index e3de6687ca..b75ffc1cf8 100644
--- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/propertyMapped/ptmapedPopup.js
+++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/propertyMapped/ptmapedPopup.js
@@ -123,7 +123,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
// Map usageCategory to category code
const raw = String(usageCategory || "").trim().toUpperCase();
if (raw.includes("RESIDENTIAL") && !raw.includes("NONRESIDENTIAL")) return "110";
- if (raw.includes("COMMERCIAL") || raw.includes("NONRESIDENTIAL")) return "111";
+ if (raw.includes("COMMERCIAL") || raw.includes("NONRESIDENTIAL") || raw.includes("INSTITUTIONAL")) return "111";
if (raw.includes("INDUSTRIAL")) return "112";
if (raw.includes("OTHERS")) return "113";
if (raw.includes("AGRICULTURE")) return "109";
@@ -204,7 +204,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
(x) => String(x.name).trim().toUpperCase() === "RESIDENTIAL"
);
setUsageCategoryState((residential && residential.code) || "110");
- } else if (raw.includes("COMMERCIAL") || raw.includes("NONRESIDENTIAL")) {
+ } else if (raw.includes("COMMERCIAL") || raw.includes("NONRESIDENTIAL") || raw.includes("INSTITUTIONAL")) {
const commercial = USAGE_CATEGORY_OPTIONS.find(
(x) => String(x.name).trim().toUpperCase() === "COMMERCIAL"
);
@@ -243,7 +243,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
const fetchRevenueData = async () => {
try {
setIsSubmitting(true);
-
+
console.log("Prepared object:", prepared);
// Try multiple paths to get tenantId
@@ -271,7 +271,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
requestBody
);
-
+
setRevenueData(response);
const propertydisits = (response && response.districts) || [];
@@ -281,7 +281,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
if (Array.isArray(propertydisits) && propertydisits.length > 0) {
setDistricts(propertydisits);
-
+
// If no persisted district, auto-select based on login/tenant (first available)
const persistedDistrict = localStorage.getItem("ptmap_district") || "";
@@ -296,7 +296,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
}
}
} else {
-
+
setDistricts([]);
}
@@ -626,7 +626,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
requestBody
);
-
+
// Extract tehsils from response
const tehsilsData = (response && response.tehsils) || [];
@@ -662,7 +662,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
if (selectedTehsil) {
try {
setIsSubmitting(true);
-
+
const requestBody = {
searchCriteria: {
@@ -689,11 +689,11 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
response.data
)) || [];
-
+
if (Array.isArray(villagesData) && villagesData.length > 0) {
setVillages(villagesData);
-
+
} else {
console.warn('No villages found for tehsil');
setVillages([]);
@@ -720,7 +720,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
if (selectedVillage) {
try {
setIsSubmitting(true);
-
+
const requestBody = {
searchCriteria: {
villageId: selectedVillage,
@@ -745,7 +745,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
response.segmentList ||
response.data
)) || [];
-
+
if (Array.isArray(segmentsData) && segmentsData.length > 0) {
setSegments(segmentsData);
@@ -779,7 +779,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
// Fetch sub-segments for selected segment
try {
setIsSubmitting(true);
-
+
const subSegRequestBody = {
searchCriteria: {
segmentId: selectedSegment,
@@ -788,7 +788,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
}
};
-
+
const subSegResponse = await httpRequest(
"post",
@@ -798,7 +798,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
subSegRequestBody
);
-
+
const subSegmentsData = (subSegResponse && (
subSegResponse.subSegments ||
@@ -812,7 +812,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
code: String(s.code || s.subSegmentId || s.id || s.value || idx + 1),
name: s.name || s.label || s.display || s.subSegmentName || (s.code || `Sub-Segment ${idx + 1}`)
}));
-
+
setSubSegments(subSegmentOptions);
} else {
console.warn('No sub-segments found for segment');
@@ -846,7 +846,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
try {
setIsSubmitting(true);
-
+
const requestBody = {
searchCriteria: {
@@ -863,7 +863,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
}
};
-
+
const url = "/egov-property-rate/property-rate/_search";
@@ -892,7 +892,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
setIsSubmitting(false);
} catch (error) {
-
+
setIsSubmitting(false);
setMappedRate(0);
setMappedRateId(0);
@@ -919,7 +919,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
try {
setIsSubmitting(true);
-
+
const requestBody = {
searchCriteria: {
@@ -940,7 +940,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
requestBody
);
-
+
const usageData = (response && (
response.usageCategories ||
@@ -1116,7 +1116,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
try {
setIsSubmitting(true);
-
+
const requestBody = {
PropertyRates: [{
id: rowdatacomplete.integration_id,
@@ -1137,7 +1137,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
}]
};
-
+
const url = "/egov-property-rate/property-rate/_update";
@@ -1149,7 +1149,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
requestBody
);
-
+
// Close all popups first, then show success message
if (response) {
diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/functions.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/functions.js
index 7467fb6430..b027ad5a59 100644
--- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/functions.js
+++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/functions.js
@@ -45,7 +45,7 @@ export const updatesingleReading = async (consumerId, tenantId, currentReading,
// return response;
// Fallback: no-op resolve so UI can proceed
- console.log("Mock update for", payload);
+
return Promise.resolve({ success: true, data: payload });
} catch (e) {
console.error(e);
@@ -143,7 +143,7 @@ export const showViewPopup = (state, dispatch, rowObject = {}) => {
}
};
export const searchApiCall = async (state, dispatch) => {
- debugger;
+
showHideTable(false, dispatch);
//showHideMergeButton(false, dispatch);
let searchScreenObject = get(
@@ -190,12 +190,16 @@ export const searchApiCall = async (state, dispatch) => {
if (serviceObject[0] && serviceObject[0].billGineiURL) {
searchScreenObject.url = serviceObject[0].billGineiURL;
}
- searchScreenObject.tenantId = process.env.REACT_APP_NAME === "Employee" ? getTenantId() : JSON.parse(getUserInfo()).permanentCity;
+ if (getTenantId() != "pb.punjab") {
+ searchScreenObject.tenantId = process.env.REACT_APP_NAME === "Employee" ? getTenantId() : JSON.parse(getUserInfo()).permanentCity;
+ }
+
const getGroupBillSearch = async (dispatch, searchScreenObject) => {
try {
dispatch(toggleSpinner(true));
+
const requestBody = {
tenantId: searchScreenObject.tenantId || tenantId,
locality: searchScreenObject.locality || "",
@@ -301,7 +305,7 @@ export const searchApiCall = async (state, dispatch) => {
const item = ptreveresponce[i];
// Log to see actual structure
- console.log("Property item:", item);
+
// Handle both camelCase and lowercase field names
const propertyId = item.propertyId || item.propertyid;
@@ -314,6 +318,7 @@ export const searchApiCall = async (state, dispatch) => {
const landArea = item.landArea || item.landarea;
const superbuiltuparea = item.superbuiltuparea || item.superbuiltuparea;
const noOfFloors = item.noOfFloors || item.nooffloors || "";
+ const surveyId = item.surveyId || item.surveyid || "";
const buildingName = item.buildingName || item.buildingname;
const usageCategory = item.usageCategory || item.usagecategory;
const propertyTypeCode =
@@ -359,7 +364,7 @@ export const searchApiCall = async (state, dispatch) => {
get(item, "propertyAddress") ||
get(item, "propertyDetails.address") || {};
- console.log("Address object:", addressObj);
+
// Resolve locality display name using MDMS + localisation, falling back to code
const localityMdms =
@@ -387,7 +392,7 @@ export const searchApiCall = async (state, dispatch) => {
city || addressObj.city || addressObj.cityName
].filter(Boolean).join(", ") || "-";
- console.log("Full address:", fullAddress);
+
response.push({
propertyId: propertyId,
@@ -400,6 +405,7 @@ export const searchApiCall = async (state, dispatch) => {
usageCategory: usageCategory,
propertyType: propertyType,
noOfFloors: noOfFloors,
+ surveyId: surveyId,
locality: localityCode,
address: fullAddress,
tenantId: tenantId
@@ -415,14 +421,14 @@ export const searchApiCall = async (state, dispatch) => {
["Property Type"]: item.propertyType || "-",
["Usage Category"]: item.usageCategory || "-",
["No of Floors"]: item.noOfFloors || "-",
+ ["Survey ID"]: item.surveyId || "-",
["Locality"]: item.locality || "-",
["Address"]: item.address || "-",
["TENANT_ID"]: item.tenantId,
["OWNERS_DATA"]: JSON.stringify(item.owners || [])
}));
- console.log("searchApiCall: prepared table data length:", data.length);
- console.log("searchApiCall: sample row:", data[0]);
+
dispatch(
handleField(
"ptreve",
@@ -445,8 +451,8 @@ export const searchApiCall = async (state, dispatch) => {
const store = require("egov-ui-framework/ui-redux/store").default;
const current = store.getState();
const cfg = (current && current.screenConfiguration && current.screenConfiguration.screenConfig && current.screenConfiguration.screenConfig.ptreve && current.screenConfiguration.screenConfig.ptreve.components && current.screenConfiguration.screenConfig.ptreve.components.div && current.screenConfiguration.screenConfig.ptreve.components.div.children && current.screenConfiguration.screenConfig.ptreve.components.div.children.searchResults) || {};
- console.log("searchApiCall: store.searchResults.props.data length:", (cfg.props && cfg.props.data && cfg.props.data.length) || 0);
- console.log("searchApiCall: store.searchResults.visible:", cfg.visible);
+
+
} catch (e) {
console.warn("searchApiCall: could not read store for debug:", e);
}
@@ -472,4 +478,69 @@ const showHideTable = (booleanHideOrShow, dispatch) => {
);
};
+// Function to remove a row from search results table by property ID (Thunk action)
+export const removeTableRowByPropertyId = (propertyId) => {
+ return (dispatch, getState) => {
+ try {
+ const state = getState();
+ const tableData = get(
+ state,
+ "screenConfiguration.screenConfig.ptreve.components.div.children.searchResults.props.data",
+ []
+ );
+
+ if (!tableData || tableData.length === 0) {
+ console.warn("No table data found to remove row from");
+ return;
+ }
+
+ // Filter out the row with matching property ID
+ const updatedTableData = tableData.filter(row => {
+ const rowPropertyId = row["Property ID"];
+ return rowPropertyId !== propertyId;
+ });
+
+
+ // Update the table data in Redux state
+ dispatch(
+ handleField(
+ "ptreve",
+ "components.div.children.searchResults",
+ "props.data",
+ updatedTableData
+ )
+ );
+
+ // Update the row count
+ dispatch(
+ handleField(
+ "ptreve",
+ "components.div.children.searchResults",
+ "props.rows",
+ updatedTableData.length
+ )
+ );
+
+ // If no rows left, hide the table
+ if (updatedTableData.length === 0) {
+ showHideTable(false, dispatch);
+ }
+
+ // Show success message
+ dispatch(
+ toggleSnackbar(
+ true,
+ {
+ labelName: "Property rate mapping submitted successfully!",
+ labelKey: "ABG_PROPERTY_RATE_MAPPING_SUBMITTED_SUCCESSFULLY"
+ },
+ "success"
+ )
+ );
+ } catch (error) {
+ console.error("Error removing table row:", error);
+ }
+ };
+};
+
diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/groupBillSearch.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/groupBillSearch.js
index d4fdddaf41..42a3faa067 100644
--- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/groupBillSearch.js
+++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/groupBillSearch.js
@@ -1,13 +1,14 @@
+import get from "lodash/get";
import {
getCommonCard,
getCommonContainer,
getLabel, getTextField, getSelectField
} from "egov-ui-framework/ui-config/screens/specs/utils";
-import { handleScreenConfigurationFieldChange as handleField } from "egov-ui-framework/ui-redux/screen-configuration/actions";
+import { handleScreenConfigurationFieldChange as handleField, prepareFinalObject } from "egov-ui-framework/ui-redux/screen-configuration/actions";
import { getTenantId, getUserInfo } from "egov-ui-kit/utils/localStorageUtils";
import { generateMultipleBill } from "../../utils/receiptPdf";
import { searchApiCall, updatesingleReading } from "./functions";
-
+import { httpRequest } from "../../../../../ui-utils";
const tenantId = process.env.REACT_APP_NAME === "Employee" ? getTenantId() : JSON.parse(getUserInfo()).permanentCity;
const tenantvalueid = [{ name: getTenantId(), code: getTenantId() }];
export const resetFields = (state, dispatch) => {
@@ -106,15 +107,94 @@ export const abgSearchCard = getCommonCard({
},
required: true,
value: tenantId,
- disabled: true,
+ isDisabled: getTenantId() === "pb.punjab" ? false : true,
+ readOnly: getTenantId() === "pb.punjab" ? false : true,
isClearable: false,
- labelsFromLocalisation: true,
+ labelsFromLocalisation: getTenantId() === "pb.punjab" ? false : true,
className: "autocomplete-dropdown",
+ sourceJsonPath: "searchScreenMdmsData.tenant.tenants",
jsonPath: "searchCriteria.tenantId",
- data: tenantvalueid,
-
},
jsonPath: "searchCriteria.tenantId",
+ afterFieldChange: async (action, state, dispatch) => {
+ let selecttetentid = await get(state, "screenConfiguration.preparedFinalObject.searchCriteria.tenantId");
+
+ if (true) {
+ try {
+ let response = await httpRequest(
+ "post",
+ "/egov-location/location/v11/boundarys/_search?hierarchyTypeCode=REVENUE&boundaryType=Locality",
+ "_search",
+ [{ key: "tenantId", value: selecttetentid }],
+ {}
+ );
+ let mohallaDataArray = [];
+ let localitysar = [];
+ let mohallaDataRow = null;
+ let name, code;
+ response.TenantBoundary[0].boundary.map((element, index) => {
+ // name = element.name + "( "+element.code+" )";
+ // code=element.code;
+ mohallaDataRow = { "code": element.code, "name": element.name };
+ mohallaDataArray.push(mohallaDataRow);
+
+ });
+ // mohallaDataArray =
+ // response &&
+ // response.TenantBoundary[0].boundary.filter((item) => {
+ // localitysar.push({ item });
+ // return localitysar;
+ // }, []);
+ dispatch(prepareFinalObject("searchScreenMdmsData.localities", mohallaDataArray));
+
+ } catch (e) {
+ console.log(e);
+ }
+ }
+
+ else {
+ //locality
+
+ let response = await httpRequest(
+ "post",
+ "/egov-location/location/v11/boundarys/_search?hierarchyTypeCode=REVENUE&boundaryType=Locality",
+ "_search",
+ [{ key: "tenantId", value: getTenantIdCommon() }],
+ {}
+ );
+ let mohallaDataArray = [];
+ let localitysar = [];
+ let mohallaDataRow = null;
+ let name, code;
+ // response.TenantBoundary[0].boundary.map((element,index) => {
+ // // name = element.name + "( "+element.code+" )";
+ // // code=element.code;
+ // mohallaDataRow={"code":element.code};
+ // mohallaDataArray.push(mohallaDataRow);
+
+ // });
+ mohallaDataArray =
+ response &&
+ response.TenantBoundary[0].boundary.filter((item) => {
+ localitysar.push({ item });
+ return localitysar;
+ }, []);
+ dispatch(prepareFinalObject("applyScreenMdmsData.tenant.mohaladata", mohallaDataArray));
+ dispatch(
+ prepareFinalObject(
+ "applyScreenMdmsData.tenant.batchs",
+ ""
+ )
+
+ );
+ dispatch(
+ prepareFinalObject(
+ "applyScreenMdmsData.tenant.groups",
+ ""
+ )
+ );
+ }
+ },
gridDefination: {
xs: 12,
sm: 4
@@ -140,9 +220,10 @@ export const abgSearchCard = getCommonCard({
labelName: "Select Location/Mohalla",
labelKey: "ABG_LOCMOHALLA_PLACEHOLDER"
},
+ //optionLabel: "name",
jsonPath: "searchCriteria.locality",
sourceJsonPath: "searchScreenMdmsData.localities",
- labelsFromLocalisation: true,
+ labelsFromLocalisation: getTenantId() === "pb.punjab" ? false : true,
required: false,
isClearable: true,
}
diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/mapptpopup.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/mapptpopup.js
index 5a41bc6547..fa69c9a730 100644
--- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/mapptpopup.js
+++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/mapptpopup.js
@@ -2,7 +2,7 @@ import React from "react";
import { connect } from "react-redux";
import get from "lodash/get";
-const MapPTPopup = ({ propertiesId, ownerName, ownerMobile, landArea, noOfFloors, locality,
+const MapPTPopup = ({ propertiesId, ownerName, ownerMobile, landArea, noOfFloors, locality, surveyId,
usageCategory, subSegmentValue, district, tehsil, village, segment, address, rate, unit, rateId, segmentName, onClose, onSubmit }) => {
return (
No of Floors
{noOfFloors || "N/A"}
-
+
Collect Rate
diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/ptmapPopup.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/ptmapPopup.js
index 160e323eee..82b728612c 100644
--- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/ptmapPopup.js
+++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/ptmapPopup.js
@@ -5,12 +5,12 @@ import {
getTextField
} from "egov-ui-framework/ui-config/screens/specs/utils";
import { handleScreenConfigurationFieldChange } from "egov-ui-framework/ui-redux/screen-configuration/actions";
-import { store } from "egov-ui-framework/ui-redux/store";
import React from "react";
import { connect } from "react-redux";
import { httpRequest } from "egov-ui-framework/ui-utils/api";
import { Dialog } from "components";
import MapPTPopup from "./mapptpopup";
+import { removeTableRowByPropertyId } from "./functions";
// Define usage categories as a constant outside the component to prevent recreation on every render
const USAGE_CATEGORY_OPTIONS = [
@@ -102,7 +102,7 @@ const onContinue = () => {
// React wrapper component
-const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea, propertyType, usageCategory, noOfFloors, address, onClose, prepared, dispatch }) => {
+const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea, propertyType, usageCategory, noOfFloors, surveyId, address, onClose, prepared, dispatch }) => {
const [isSubmitting, setIsSubmitting] = React.useState(false);
const [revenueData, setRevenueData] = React.useState(null);
@@ -128,7 +128,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
const raw = String(rawUsageCategory || "").trim().toUpperCase();
// exact-only match
if (raw === "RESIDENTIAL" || raw === "110") return "110";
- if (raw === "NONRESIDENTIAL.COMMERCIAL" || raw === "NONRESIDENTIAL.OTHERS" || raw === "111") return "111";
+ if (raw === "NONRESIDENTIAL.COMMERCIAL" || raw === "NONRESIDENTIAL.OTHERS" || raw === "NONRESIDENTIAL.INSTITUTIONAL" || raw === "111") return "111";
if (raw === "NONRESIDENTIAL.INDUSTRIAL" || raw === "112") return "112";
return "";
};
@@ -149,7 +149,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
// exact match for RESIDENTIAL, COMMERCIAL, INDUSTRIAL, or OTHERS
const isResidentialExact = raw === "RESIDENTIAL" || raw === "110";
- const isCommercialExact = raw === "NONRESIDENTIAL.COMMERCIAL" || raw === "NONRESIDENTIAL.OTHERS" || raw === "NONRESIDENTIAL" || raw === "111";
+ const isCommercialExact = raw === "NONRESIDENTIAL.COMMERCIAL" || raw === "NONRESIDENTIAL.OTHERS" || raw === "NONRESIDENTIAL.INSTITUTIONAL" || raw === "NONRESIDENTIAL" || raw === "111";
const isIndustrialExact = raw === "NONRESIDENTIAL.INDUSTRIAL" || raw === "112";
if (isResidentialExact) {
@@ -787,7 +787,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
"categoryId": usageCategoryState,
"locality": locality || "",
"rate": mappedRate || -1,
- "unit": mappedunit || "",
+ "unit": mappedunit || -1,
"rateId": mappedRateId || -1,
"isActive": true,
"isProrataCal": false,
@@ -810,7 +810,11 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
console.log("Submit response:", response);
- alert("Property rate mapping submitted successfully!");
+ // alert("Property rate mapping submitted successfully!");
+
+ // Remove the row from the table after successful submission
+ dispatch(removeTableRowByPropertyId(propertiesId));
+
setDialogOpen(false);
onClose();
setIsSubmitting(false);
@@ -987,6 +991,12 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
No of Floors
{noOfFloors || "N/A"}
+
+
Survey Id
+
{surveyId || "N/A"}
+
@@ -1300,6 +1310,7 @@ const PTmapPopup = ({ propertiesId, ownerName, ownerMobile, locality, landArea,
ownerMobile={ownerMobile}
landArea={landArea}
noOfFloors={noOfFloors}
+ surveyId={surveyId}
locality={locality}
usageCategory={(USAGE_CATEGORY_OPTIONS.find(u => u.code === usageCategoryState) || {}).name || usageCategoryState}
address={address}
diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/searchResults.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/searchResults.js
index 6994dd3994..ec6b95f1e1 100644
--- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/searchResults.js
+++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/ptMaps/searchResults.js
@@ -36,6 +36,15 @@ export const searchResults = {
{ labelName: "Usage Category", labelKey: "Usage Category" },
{ labelName: "No of Floors", labelKey: "No of Floors" },
+ {
+ labelName: "Survey ID",
+ labelKey: "Survey ID",
+ options: {
+ display: false,
+ viewColumns: false,
+ filter: false
+ }
+ },
{
labelName: "Locality",
labelKey: "Locality",
@@ -64,8 +73,9 @@ export const searchResults = {
const propertyType = row[4] || "";
const usageCategory = row[5] || "";
const noOfFloors = row[6] || "";
- const locality = row[7] || "";
- const address = row[8] || "";
+ const surveyId = row[7] || "";
+ const locality = row[8] || "";
+ const address = row[9] || "";
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
@@ -105,6 +115,7 @@ export const searchResults = {
propertyType={propertyType}
usageCategory={usageCategory}
noOfFloors={noOfFloors}
+ surveyId={surveyId}
locality={locality}
address={address}
onClose={handleClose}
diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/utils/receiptPdf.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/utils/receiptPdf.js
index 3c8f4ed808..eaa243ba44 100644
--- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/utils/receiptPdf.js
+++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/utils/receiptPdf.js
@@ -1,4 +1,3 @@
-// import { downloadMultipleBill } from "egov-common/ui-utils/commons";
import { toggleSpinner, toggleSnackbar } from "egov-ui-framework/ui-redux/screen-configuration/actions";
import get from "lodash/get";
import isEmpty from "lodash/isEmpty";
@@ -199,74 +198,71 @@ export const generateMultipleBill = async (state, dispatch, type) => {
"preparedFinalObject.searchCriteria.tenantId",
''
);
- let batchtype = get(
- state.screenConfiguration,
- "preparedFinalObject.generateBillScreen.batchtype",
- ''
- );
+ let batchtype = get(
+ state.screenConfiguration,
+ "preparedFinalObject.generateBillScreen.batchtype",
+ ''
+ );
let billkey = ''
const index = commonPayDetails && commonPayDetails.findIndex((item) => {
return item.code == businessService;
});
- if(batchtype === "Integrated Bill"){
+ if (batchtype === "Integrated Bill") {
billkey = 'wsn-integrated'
- }else{
- if (index > -1) {
- billkey = get(commonPayDetails[index], 'billKey', '');
+ } else {
+ if (index > -1) {
+ billkey = get(commonPayDetails[index], 'billKey', '');
} else {
const details = commonPayDetails && commonPayDetails.filter(item => item.code === "DEFAULT");
billkey = get(details, 'billKey', '');
}
}
- if(batchtype === "Integrated Bill"){
- allBills = allBills.filter(bill => bill.connection.propertyTotalAmount >0);
- }else{
- allBills = allBills.filter(bill => bill.status === 'ACTIVE' && bill.totalAmount >0 && bill.connection.status=="Active");
+ if (batchtype === "Integrated Bill") {
+ allBills = allBills.filter(bill => bill.connection.propertyTotalAmount > 0);
+ } else {
+ allBills = allBills.filter(bill => bill.status === 'ACTIVE' && bill.totalAmount > 0 && bill.connection.status == "Active");
}
-
-
-
- //allBills = allBills.filter(bill => bill.status === 'ACTIVE' && bill.totalAmount > 0);
- // if (
- // batchtype == 'Locality' && locality &&
- // !Array.isArray(locality) &&
- // typeof locality === "string" &&
- // locality.trim() !== ""
- // ) {
- // try {
- // const egovPdfResponse = await batchMergeAndDownload(
- // billkey,
- // locality,
- // businessService,
- // tenantId
- // );
- // let labelKey = egovPdfResponse.message+" Job ID :"+egovPdfResponse.jobId
- // dispatch(
- // toggleSnackbar(
- // true,
- // {
- // labelName: labelKey,
- // labelKey: labelKey
- // },
- // "warning"
- // )
- // );
- // } catch (error) {
- // console.error("Error while batch merge and download:", error);
- // dispatch(
- // toggleSnackbar(
- // true,
- // {
- // labelName: error,
- // labelKey: error
- // },
- // "warning"
- // )
- // );
- // }
- // } else {
+ allBills = allBills.filter(bill => bill.status === 'ACTIVE' && bill.totalAmount > 0);
+ if (
+ batchtype == 'Locality' && locality &&
+ !Array.isArray(locality) &&
+ typeof locality === "string" &&
+ locality.trim() !== ""
+ ) {
+ try {
+ const egovPdfResponse = await batchMergeAndDownload(
+ billkey,
+ locality,
+ businessService,
+ tenantId
+ );
+ let labelKey = egovPdfResponse.message + " Job ID :" + egovPdfResponse.jobId
+ dispatch(
+ toggleSnackbar(
+ true,
+ {
+ labelName: labelKey,
+ labelKey: labelKey
+ },
+ "warning"
+ )
+ );
+ } catch (error) {
+ console.error("Error while batch merge and download:", error);
+ dispatch(
+ toggleSnackbar(
+ true,
+ {
+ labelName: error,
+ labelKey: error
+ },
+ "warning"
+ )
+ );
+ }
+ } else {
allBills && allBills.length > 0 && await downloadMultipleBill(allBills, billkey, businessService);
- // }
+ }
/*
To Download Files based on Filestoreid logic
@@ -284,7 +280,7 @@ allBills.map(bill=>{
bills&&bills.length>0&&await downloadMultipleBill(bills,billkey);
filestoreids&&filestoreids.length>0&&downloadMultipleFileFromFilestoreIds(filestoreids,'download'); */
dispatch(toggleSpinner());
-
+
};
/* await loadMdmsData(tenant);
// data1 is for ULB logo from loadUlbLogo
diff --git a/web/rainmaker/dev-packages/egov-pt-dev/src/ui-config/screens/specs/pt-mutation/mutation-methods.js b/web/rainmaker/dev-packages/egov-pt-dev/src/ui-config/screens/specs/pt-mutation/mutation-methods.js
index 2cdcc79b90..d0b320d878 100644
--- a/web/rainmaker/dev-packages/egov-pt-dev/src/ui-config/screens/specs/pt-mutation/mutation-methods.js
+++ b/web/rainmaker/dev-packages/egov-pt-dev/src/ui-config/screens/specs/pt-mutation/mutation-methods.js
@@ -48,7 +48,7 @@ export const resetFields = (state, dispatch) => {
false
)
);
- }else{
+ } else {
dispatch(
handleField(
"propertySearch",
@@ -170,118 +170,118 @@ export const searchPropertyDetails = getCommonCard({
subParagraph: getCommonParagraph({
labelName: "Provide at least one non-mandatory parameter to search for an application (In case of Search by locality and name . please select city name again)",
- //labelKey: "PT_HOME_SEARCH_RESULTS_DESC"
+ //labelKey: "PT_HOME_SEARCH_RESULTS_DESC"
labelKey: "Provide at least one non-mandatory parameter to search for an application (In case of search by locality and name . please select city name again)",
-
+
}
),
ulbCityContainer: getCommonContainer({
ulbCity: {
...getSelectField({
- uiFramework: "custom-containers-local",
- moduleName: "egov-pt",
- componentPath: "AutosuggestContainer",
- props: {
- className: "autocomplete-dropdown",
- suggestions: [],
- label: {
- labelName: "ULB",
- labelKey: "PT_ULB_CITY"
- },
- placeholder: {
- labelName: "Select ULB",
- labelKey: "PT_ULB_CITY_PLACEHOLDER"
- },
- localePrefix: {
- moduleName: "TENANT",
- masterName: "TENANTS"
+ uiFramework: "custom-containers-local",
+ moduleName: "egov-pt",
+ componentPath: "AutosuggestContainer",
+ props: {
+ className: "autocomplete-dropdown",
+ suggestions: [],
+ label: {
+ labelName: "ULB",
+ labelKey: "PT_ULB_CITY"
+ },
+ placeholder: {
+ labelName: "Select ULB",
+ labelKey: "PT_ULB_CITY_PLACEHOLDER"
+ },
+ localePrefix: {
+ moduleName: "TENANT",
+ masterName: "TENANTS"
+ },
+ jsonPath: "ptSearchScreen.tenantId",
+ sourceJsonPath: "searchScreenMdmsData.tenant.tenants",
+ labelsFromLocalisation: true,
+ required: true,
+ isClearable: true,
+ disabled: process.env.REACT_APP_NAME === "Citizen" ? false : true,
+ inputLabelProps: {
+ shrink: true
+ }
},
+ required: true,
jsonPath: "ptSearchScreen.tenantId",
sourceJsonPath: "searchScreenMdmsData.tenant.tenants",
- labelsFromLocalisation: true,
- required: true,
- isClearable: true,
- disabled: process.env.REACT_APP_NAME === "Citizen" ? false : true,
- inputLabelProps: {
- shrink: true
- }
- },
- required: true,
- jsonPath: "ptSearchScreen.tenantId",
- sourceJsonPath: "searchScreenMdmsData.tenant.tenants",
- }),
- beforeFieldChange: async (action, state, dispatch) => {
- //Below only runs for citizen - not required here in employee
-
- try {
- let payload = await httpRequest(
- "post",
- "/egov-location/location/v11/boundarys/_search?hierarchyTypeCode=REVENUE&boundaryType=Locality",
- "_search",
- [{ key: "tenantId", value: action.value }],
- {}
- );
- console.log("payload", payload)
- const mohallaData =
- payload &&
- payload.TenantBoundary[0] &&
- payload.TenantBoundary[0].boundary &&
- payload.TenantBoundary[0].boundary.reduce((result, item) => {
- result.push({
- ...item,
- name: `${action.value
- .toUpperCase()
- .replace(
- /[.]/g,
- "_"
- )}_REVENUE_${item.code
+ }),
+ beforeFieldChange: async (action, state, dispatch) => {
+ //Below only runs for citizen - not required here in employee
+
+ try {
+ let payload = await httpRequest(
+ "post",
+ "/egov-location/location/v11/boundarys/_search?hierarchyTypeCode=REVENUE&boundaryType=Locality",
+ "_search",
+ [{ key: "tenantId", value: action.value }],
+ {}
+ );
+ console.log("payload", payload)
+ const mohallaData =
+ payload &&
+ payload.TenantBoundary[0] &&
+ payload.TenantBoundary[0].boundary &&
+ payload.TenantBoundary[0].boundary.reduce((result, item) => {
+ result.push({
+ ...item,
+ name: `${action.value
.toUpperCase()
- .replace(/[._:-\s\/]/g, "_")}`
- });
- return result;
- }, []);
-
- console.log(mohallaData, "mohallaData")
-
-
-
- dispatch(
- prepareFinalObject(
- "applyScreenMdmsData.tenant.localities",
- mohallaData
- )
- );
- dispatch(
- handleField(
- "apply",
- "components.div.children.formwizardSecondStep.children.propertyLocationDetails.children.cardContent.children.propertyDetailsConatiner.children.propertyMohalla",
- "props.suggestions",
- mohallaData
- )
- );
- const mohallaLocalePrefix = {
- moduleName: action.value,
- masterName: "REVENUE"
- };
- dispatch(
- handleField(
- "apply",
- "components.div.children.formwizardSecondStep.children.propertyLocationDetails.children.cardContent.children.propertyDetailsConatiner.children.propertyMohalla",
- "props.localePrefix",
- mohallaLocalePrefix
- )
- );
-
- dispatch(
- fetchLocalizationLabel(getLocale(), action.value, action.value)
- );
-
- } catch (e) {
- console.log(e);
- }
+ .replace(
+ /[.]/g,
+ "_"
+ )}_REVENUE_${item.code
+ .toUpperCase()
+ .replace(/[._:-\s\/]/g, "_")}`
+ });
+ return result;
+ }, []);
+
+ console.log(mohallaData, "mohallaData")
+
+
+
+ dispatch(
+ prepareFinalObject(
+ "applyScreenMdmsData.tenant.localities",
+ mohallaData
+ )
+ );
+ dispatch(
+ handleField(
+ "apply",
+ "components.div.children.formwizardSecondStep.children.propertyLocationDetails.children.cardContent.children.propertyDetailsConatiner.children.propertyMohalla",
+ "props.suggestions",
+ mohallaData
+ )
+ );
+ const mohallaLocalePrefix = {
+ moduleName: action.value,
+ masterName: "REVENUE"
+ };
+ dispatch(
+ handleField(
+ "apply",
+ "components.div.children.formwizardSecondStep.children.propertyLocationDetails.children.cardContent.children.propertyDetailsConatiner.children.propertyMohalla",
+ "props.localePrefix",
+ mohallaLocalePrefix
+ )
+ );
+
+ dispatch(
+ fetchLocalizationLabel(getLocale(), action.value, action.value)
+ );
+
+ } catch (e) {
+ console.log(e);
+ }
- },
+ },
gridDefination: {
xs: 12,
sm: 4
@@ -309,7 +309,7 @@ export const searchPropertyDetails = getCommonCard({
required: false,
pattern: getPattern("MobileNo"),
jsonPath: "ptSearchScreen.mobileNumber",
- // disabled: process.env.REACT_APP_NAME === "Citizen" ? true : false,
+ disabled: process.env.REACT_APP_NAME === "Citizen" ? true : false,
errorMessage: "ERR_INVALID_MOBILE_NUMBER"
}),
propertyTaxUniqueId: getTextField({
@@ -350,101 +350,101 @@ export const searchPropertyDetails = getCommonCard({
errorMessage: "ERR_INVALID_PROPERTY_ID",
jsonPath: "ptSearchScreen.oldpropertyids"
}),
-
- //-------------locality--------------
- propertyMohalla: {
- uiFramework: "custom-containers",
- componentPath: "AutosuggestContainer",
- jsonPath:"ptSearchScreen.locality",
- required: true,
- props: {
- style: {
- width: "100%",
- cursor: "pointer"
+
+ //-------------locality--------------
+ propertyMohalla: {
+ uiFramework: "custom-containers",
+ componentPath: "AutosuggestContainer",
+ jsonPath: "ptSearchScreen.locality",
+ required: true,
+ props: {
+ style: {
+ width: "100%",
+ cursor: "pointer"
+ },
+ label: {
+ labelName: "Locality/Mohalla",
+ // labelKey: "NOC_PROPERTY_DETAILS_MOHALLA_LABEL"
+ },
+ placeholder: {
+ labelName: "Select Locality/Mohalla",
+ //labelKey: "NOC_PROPERTY_DETAILS_MOHALLA_PLACEHOLDER"
+ },
+ jsonPath: "ptSearchScreen.locality",
+ sourceJsonPath: "applyScreenMdmsData.tenant.localities",
+ labelsFromLocalisation: true,
+ errorMessage: "ERR_DEFAULT_INPUT_FIELD_MSG",
+ suggestions: [],
+ fullwidth: true,
+ required: false,
+ // disabled: process.env.REACT_APP_NAME === "Citizen" ? true : false,
+ // type:hidden,
+ inputLabelProps: {
+ shrink: true
+ }
+ // className: "tradelicense-mohalla-apply"
+ },
+ beforeFieldChange: async (action, state, dispatch) => {
+ // dispatch(
+ // prepareFinalObject(
+ // "Licenses[0].tradeLicenseDetail.address.locality.name",
+ // action.value && action.value.label
+ // )
+ // );
},
+ gridDefination: {
+ xs: 12,
+ sm: 4
+ }
+ },
+ //---------------locality-end--------------
+ //-------------------Owner Name----------------------
+ ownerName: getTextField({
label: {
- labelName: "Locality/Mohalla",
- // labelKey: "NOC_PROPERTY_DETAILS_MOHALLA_LABEL"
+ labelName: "Owner Name",
+ labelKey: "Owner Name"
},
placeholder: {
- labelName: "Select Locality/Mohalla",
- //labelKey: "NOC_PROPERTY_DETAILS_MOHALLA_PLACEHOLDER"
+ labelName: "Enter Owner Name",
+ labelKey: "Owner Name"
+ },
+ gridDefination: {
+ xs: 12,
+ sm: 4,
+
},
- jsonPath:"ptSearchScreen.locality",
- sourceJsonPath: "applyScreenMdmsData.tenant.localities",
- labelsFromLocalisation: true,
- errorMessage: "ERR_DEFAULT_INPUT_FIELD_MSG",
- suggestions: [],
- fullwidth: true,
required: false,
+ // pattern: /^[^\$\"'<>?\\\\~`!@$%^()+={}\[\]*:;“”‘’]{1,64}$/i,
+ errorMessage: "ERR_INVALID_PROPERTY_ID",
+ jsonPath: "ptSearchScreen.name",
// disabled: process.env.REACT_APP_NAME === "Citizen" ? true : false,
- // type:hidden,
- inputLabelProps: {
- shrink: true
- }
- // className: "tradelicense-mohalla-apply"
- },
- beforeFieldChange: async (action, state, dispatch) => {
- // dispatch(
- // prepareFinalObject(
- // "Licenses[0].tradeLicenseDetail.address.locality.name",
- // action.value && action.value.label
- // )
- // );
- },
- gridDefination: {
- xs: 12,
- sm: 4
- }
- },
- //---------------locality-end--------------
- //-------------------Owner Name----------------------
- ownerName: getTextField({
- label: {
- labelName: "Owner Name",
- labelKey: "Owner Name"
- },
- placeholder: {
- labelName: "Enter Owner Name",
- labelKey: "Owner Name"
- },
- gridDefination: {
- xs: 12,
- sm: 4,
+ }),
- },
- required: false,
- // pattern: /^[^\$\"'<>?\\\\~`!@$%^()+={}\[\]*:;“”‘’]{1,64}$/i,
- errorMessage: "ERR_INVALID_PROPERTY_ID",
- jsonPath: "ptSearchScreen.name",
- // disabled: process.env.REACT_APP_NAME === "Citizen" ? true : false,
- }),
+ surveyId: getTextField({
+ label: {
+ labelName: "Survey Id",
+ labelKey: "Survey Id"
+ },
+ placeholder: {
+ labelName: "Enter Survey Id",
+ labelKey: "Survey Id"
+ },
+ gridDefination: {
+ xs: 12,
+ sm: 4,
- surveyId: getTextField({
- label: {
- labelName: "Survey Id",
- labelKey: "Survey Id"
- },
- placeholder: {
- labelName: "Enter Survey Id",
- labelKey: "Survey Id"
- },
- gridDefination: {
- xs: 12,
- sm: 4,
+ },
+ required: false,
+ // pattern: /^[^\$\"'<>?\\\\~`!@$%^()+={}\[\]*:;“”‘’]{1,64}$/i,
+ errorMessage: "ERR_INVALID_SURVEY_ID",
+ jsonPath: "ptSearchScreen.surveyId",
+ disabled: process.env.REACT_APP_NAME === "Citizen" ? true : false,
+ }),
- },
- required: false,
- // pattern: /^[^\$\"'<>?\\\\~`!@$%^()+={}\[\]*:;“”‘’]{1,64}$/i,
- errorMessage: "ERR_INVALID_SURVEY_ID",
- jsonPath: "ptSearchScreen.surveyId",
- disabled: process.env.REACT_APP_NAME === "Citizen" ? true : false,
- }),
-
- //-------------------End SurveyId --------------------------------
+ //-------------------End SurveyId --------------------------------
}),
-
+
button: getCommonContainer({
buttonContainer: getCommonContainer({
resetButton: {
@@ -560,7 +560,7 @@ export const searchApplicationDetails = getCommonCard({
position: "start"
},
required: false,
- // disabled: process.env.REACT_APP_NAME === "Citizen" ? true : false,
+ disabled: process.env.REACT_APP_NAME === "Citizen" ? true : false,
pattern: getPattern("MobileNo"),
jsonPath: "ptSearchScreen.mobileNumber",
errorMessage: "ERR_INVALID_MOBILE_NUMBER"
@@ -580,7 +580,7 @@ export const searchApplicationDetails = getCommonCard({
},
required: false,
- // disabled: process.env.REACT_APP_NAME === "Citizen" ? true : false,
+ // disabled: process.env.REACT_APP_NAME === "Citizen" ? true : false,
pattern: /^[a-zA-Z0-9-]*$/i,
errorMessage: "ERR_INVALID_PROPERTY_ID",
jsonPath: "ptSearchScreen.ids"
diff --git a/web/rainmaker/dev-packages/egov-ui-kit-dev/src/common/propertyTax/Property/index.js b/web/rainmaker/dev-packages/egov-ui-kit-dev/src/common/propertyTax/Property/index.js
index 4b19fdde71..c53b097509 100644
--- a/web/rainmaker/dev-packages/egov-ui-kit-dev/src/common/propertyTax/Property/index.js
+++ b/web/rainmaker/dev-packages/egov-ui-kit-dev/src/common/propertyTax/Property/index.js
@@ -208,9 +208,9 @@ class Property extends Component {
dialogueOpen: true,
urlToAppend: getPropertyLink(propertyId, tenantId, PROPERTY_FORM_PURPOSE.ASSESS, -1, assessmentNo),
});
- if (process.env.REACT_APP_NAME === "Citizen") {
- alert("One-Time Settlement for Property Tax has been enabled in mSeva. Please review and re-assess your property details before proceeding with payment.");
- }
+ // if (process.env.REACT_APP_NAME === "Citizen") {
+ // alert("One-Time Settlement for Property Tax has been enabled in mSeva. Please review and re-assess your property details before proceeding with payment.");
+ // }
}
};
onEditPropertyClick = () => {
diff --git a/web/rainmaker/dev-packages/egov-ui-kit-dev/src/hocs/index.css b/web/rainmaker/dev-packages/egov-ui-kit-dev/src/hocs/index.css
index ee3012690c..a167efba4b 100644
--- a/web/rainmaker/dev-packages/egov-ui-kit-dev/src/hocs/index.css
+++ b/web/rainmaker/dev-packages/egov-ui-kit-dev/src/hocs/index.css
@@ -203,3 +203,50 @@
.rainmaker-action-menu::-webkit-scrollbar-resizer {
background-color: transparent;
}
+.language-plugin{
+ position: fixed;
+ bottom: 8rem;
+ right: 20px;
+ z-index: 99999;
+ background: linear-gradient(135deg, rgb(37, 99, 235), rgb(124, 58, 237));
+ padding: 6px 10px;
+ border-radius:8px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
+ display: flex;
+ align-items: center;
+}
+.language-plugin svg path{
+ fill: #FFF;
+}
+.language-plugin:hover{
+ transform: translateY(-3px) scale(1.03);
+ box-shadow:
+ 0 10px 20px rgba(0, 0, 0, 0.25),
+ 0 0 20px rgba(59, 130, 246, 0.5),
+ 0 0 35px rgba(14, 165, 233, 0.4);
+}
+.language-plugin-landing{
+ position: fixed;
+ top: 16px;
+ right: 20px;
+ z-index: 99999;
+ background: #FFF;
+ padding: 6px 10px;
+ border-radius:8px;
+ display: flex;
+ align-items: center;
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
+ box-shadow:0 8px 32px rgba(0, 0, 0, 0.2);
+ transition: all 0.3s ease;
+}
+.language-plugin-landing:hover{
+ transform: translateY(-3px) scale(1.03);
+ box-shadow:
+ 0 10px 20px rgba(0, 0, 0, 0.25),
+ 0 0 20px rgba(59, 130, 246, 0.5),
+ 0 0 35px rgba(14, 165, 233, 0.4);
+}
+.margin-right-50{
+ margin-right: 50px;
+}
diff --git a/web/rainmaker/dev-packages/egov-ui-kit-dev/src/hocs/withAuthorization.js b/web/rainmaker/dev-packages/egov-ui-kit-dev/src/hocs/withAuthorization.js
index a41e0bd3d9..0d92873585 100644
--- a/web/rainmaker/dev-packages/egov-ui-kit-dev/src/hocs/withAuthorization.js
+++ b/web/rainmaker/dev-packages/egov-ui-kit-dev/src/hocs/withAuthorization.js
@@ -49,6 +49,11 @@ const withAuthorization = (options = {}) => (Component) => {
// This component is wrapped by multiple HOCs and would cause duplicate API calls
// Only fetch on navigation via componentDidUpdate
console.log('[withAuthorization] componentDidMount - Skipping initial fetch (handled by App.js)');
+ const script = document.createElement("script");
+ script.id = "bhashini-translation-script";
+ script.src = "https://translation-plugin.bhashini.co.in/v3/website_translation_utility.js";
+ script.async = true;
+ document.body.appendChild(script);
}
citizenTenantId = () => {
@@ -102,7 +107,7 @@ const withAuthorization = (options = {}) => (Component) => {
// FIX: Use componentDidUpdate instead of deprecated componentWillReceiveProps
// Only fetch locale if the route actually changed (not on every prop change)
if (this.props.location && prevProps.location &&
- this.props.location.pathname !== prevProps.location.pathname) {
+ this.props.location.pathname !== prevProps.location.pathname) {
this.fetchLocale();
}
}
@@ -198,119 +203,124 @@ const withAuthorization = (options = {}) => (Component) => {
let drawerClsName = menuDrawerOpen ? "full-menu-drawer" : "icon-menu-drawer";
let screencls = menuDrawerOpen ? "with-full-menu" : "with-icon-menu";
return (
-
- {!hideHeader && authenticated ? (
-
- ) : null}
-
- {!hideActionMenu && authenticated && (
-
-