From ee2b1a2d708cfb6495a26135fd9b18735eec5adc Mon Sep 17 00:00:00 2001 From: anujkit Date: Tue, 3 Mar 2026 17:50:49 +0530 Subject: [PATCH 01/64] PI-20750 Put a msg in employee login for both mono-ui and digit-ui --- .../src/modules/employee/User/Login/index.js | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/web/rainmaker/packages/employee/src/modules/employee/User/Login/index.js b/web/rainmaker/packages/employee/src/modules/employee/User/Login/index.js index 96e94c5899..d69300906f 100644 --- a/web/rainmaker/packages/employee/src/modules/employee/User/Login/index.js +++ b/web/rainmaker/packages/employee/src/modules/employee/User/Login/index.js @@ -10,9 +10,29 @@ const LoginFormHOC = formHoc({ formKey: "employeeLogin" })(LoginForm); const Login = ({ bannerUrl, logoUrl }) => { return ( - {/* - Planned Downtime Notice: The mSeva Punjab application will be unavailable from 15th August 2025 to 18th August 2025 due to scheduled maintenance. We regret the inconvenience and appreciate your understanding. - */} + {
+ 🔐 + + Effective March 05, 2026, extra login security has been enabled. Please make sure your mobile number is updated to receive OTP verification. + + 05 ਮਾਰਚ, 2026 ਤੋਂ, ਵਾਧੂ ਲੌਗਇਨ ਸੁਰੱਖਿਆ ਨੂੰ ਸਮਰੱਥ ਬਣਾਇਆ ਗਿਆ ਹੈ। ਕਿਰਪਾ ਕਰਕੇ ਇਹ ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਤੁਹਾਡਾ ਮੋਬਾਈਲ ਨੰਬਰ OTP ਪੁਸ਼ਟੀਕਰਨ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਅੱਪਡੇਟ ਕੀਤਾ ਗਿਆ ਹੈ। +
}
); From 5b8677133f8bb6c428e76142aeaf7f6809d9131a Mon Sep 17 00:00:00 2001 From: anujkit Date: Tue, 10 Mar 2026 17:27:25 +0530 Subject: [PATCH 02/64] egov-pdf code --- .../ui-config/screens/specs/abg/groupBills.js | 4 +- .../screens/specs/utils/receiptPdf.js | 83 +++++++++---------- 2 files changed, 42 insertions(+), 45 deletions(-) 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/utils/receiptPdf.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/utils/receiptPdf.js index 3c8f4ed808..d212afa99a 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 @@ -223,50 +223,47 @@ export const generateMultipleBill = async (state, dispatch, type) => { }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 From 53a9a3143851d3fbdee6a375fce0883323ce45f1 Mon Sep 17 00:00:00 2001 From: anujkit Date: Mon, 30 Mar 2026 17:04:41 +0530 Subject: [PATCH 03/64] PI-21038 change the URL of Ticketing in Raise the Ticket page --- .../egov-wns-dev/src/ui-config/screens/specs/wns/ticket.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/screens/specs/wns/ticket.js b/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/screens/specs/wns/ticket.js index 678ed25a3f..b0e0f2f38f 100644 --- a/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/screens/specs/wns/ticket.js +++ b/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/screens/specs/wns/ticket.js @@ -148,5 +148,6 @@ const ticket = { export default ticket const openTicketTool = (state, dispatch) => { - window.open("https://stvending.punjab.gov.in/ticket/", "_blank") + //window.open("https://stvending.punjab.gov.in/ticket/", "_blank") + window.open("https://mseva.lgpunjab.gov.in/ticket/", "_blank") }; From 590f0d0a34baa839fa2b56e8c4a8cf4e458be54f Mon Sep 17 00:00:00 2001 From: anujkit Date: Wed, 1 Apr 2026 16:17:17 +0530 Subject: [PATCH 04/64] PI-21046 PT-1012-3024433 ASSESSMENT YEAR 2026-27 --- .../src/common/propertyTax/YearDialogue/index.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/web/rainmaker/dev-packages/egov-ui-kit-dev/src/common/propertyTax/YearDialogue/index.js b/web/rainmaker/dev-packages/egov-ui-kit-dev/src/common/propertyTax/YearDialogue/index.js index 02e64df98c..a29d690bdc 100644 --- a/web/rainmaker/dev-packages/egov-ui-kit-dev/src/common/propertyTax/YearDialogue/index.js +++ b/web/rainmaker/dev-packages/egov-ui-kit-dev/src/common/propertyTax/YearDialogue/index.js @@ -13,6 +13,7 @@ import { httpRequest } from "../../../utils/api"; import "./index.css"; import { getTenantId, getUserInfo } from "../../../utils/localStorageUtils"; //"egov-ui-kit/utils/localStorageUtils" + var localityCode = null; var surveyIdcode = null; var editlocalityCode = null; @@ -90,13 +91,13 @@ const breakYear = (financialYear)=>{ } return parseInt(financialYear.split("-")[1]); } -const checkAssessmentStatus = (constructionYear, assessmentArray,tenantId,selectedYear) => { - console.log("assessmentArray",assessmentArray) +const checkAssessmentStatus = (constructionYear, assessmentArray,tenantId,selectedYear, getYearList) => { + //console.log("assessmentArray",getYearList) let missingYears = []; // if(tenantId === "pb.testing" || tenantId === "pb.patiala"){ let checkedYears; - const mFinancialYear = getCurrentFinancialYear() + const mFinancialYear = getYearList[0]; //getCurrentFinancialYear() const currentFinancialYear = breakYear(mFinancialYear) const lastFifthFinancialYear = currentFinancialYear - 4; const newConstructionYear = constructionYear ==='NA' ? lastFifthFinancialYear : breakYear(constructionYear); @@ -226,7 +227,7 @@ class YearDialog extends Component { // let assessed = userType.toUpperCase() === 'CITIZEN' ? checkAssessmentStatus(constructionYear,assessment,propertiestenantId,this.state.selectedYear) // : checkAssessmentStatus(constructionYear,assessment,tenantIdcode,this.state.selectedYear); //console.log("assessed",assessed); - let assessed = checkAssessmentStatus(constructionYear,assessment,propertiestenantId,this.state.selectedYear); + let assessed = checkAssessmentStatus(constructionYear,assessment,propertiestenantId,this.state.selectedYear, getYearList); if(isLocMatch){ if (this.state.selectedYear !== '' && surveyIdcode != null) { if(assessed.length > 0){ From efbf0245ad0c973dbf05150d0f51270dc42bb28d Mon Sep 17 00:00:00 2001 From: erramesh000 Date: Tue, 7 Apr 2026 10:17:34 +0530 Subject: [PATCH 05/64] Updated Bulkmeter Reading --- .../screens/specs/abg/bulkmeterreading.js | 187 ++++++++++ .../screens/specs/abg/gBmr/functions.js | 232 ++++++++++++ .../screens/specs/abg/gBmr/groupBillSearch.js | 249 +++++++++++++ .../screens/specs/abg/gBmr/searchResults.js | 343 ++++++++++++++++++ 4 files changed, 1011 insertions(+) create mode 100644 web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/bulkmeterreading.js create mode 100644 web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/functions.js create mode 100644 web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/groupBillSearch.js create mode 100644 web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/searchResults.js 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 From e49e54537f95201e433fffb3d98d1b04060b84b7 Mon Sep 17 00:00:00 2001 From: erramesh000 Date: Tue, 7 Apr 2026 10:22:28 +0530 Subject: [PATCH 06/64] Revert "Updated Bulkmeter Reading" This reverts commit efbf0245ad0c973dbf05150d0f51270dc42bb28d. --- .../screens/specs/abg/bulkmeterreading.js | 187 ---------- .../screens/specs/abg/gBmr/functions.js | 232 ------------ .../screens/specs/abg/gBmr/groupBillSearch.js | 249 ------------- .../screens/specs/abg/gBmr/searchResults.js | 343 ------------------ 4 files changed, 1011 deletions(-) delete mode 100644 web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/bulkmeterreading.js delete mode 100644 web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/functions.js delete mode 100644 web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/groupBillSearch.js delete mode 100644 web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/searchResults.js 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 deleted file mode 100644 index f165bd0ca1..0000000000 --- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/bulkmeterreading.js +++ /dev/null @@ -1,187 +0,0 @@ -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 deleted file mode 100644 index 90c428682a..0000000000 --- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/functions.js +++ /dev/null @@ -1,232 +0,0 @@ -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 deleted file mode 100644 index a8bc0a1ca8..0000000000 --- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/groupBillSearch.js +++ /dev/null @@ -1,249 +0,0 @@ -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 deleted file mode 100644 index da0b33f93d..0000000000 --- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/searchResults.js +++ /dev/null @@ -1,343 +0,0 @@ -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 From 08526a1d455a94228e94283700a0e2e1fd9a0bbb Mon Sep 17 00:00:00 2001 From: erramesh000 Date: Tue, 7 Apr 2026 12:26:53 +0530 Subject: [PATCH 07/64] Updated Bulkmeter screen --- .../screens/specs/abg/bulkmeterreading.js | 187 ++++++++++ .../screens/specs/abg/gBmr/functions.js | 232 ++++++++++++ .../screens/specs/abg/gBmr/groupBillSearch.js | 249 +++++++++++++ .../screens/specs/abg/gBmr/searchResults.js | 343 ++++++++++++++++++ 4 files changed, 1011 insertions(+) create mode 100644 web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/bulkmeterreading.js create mode 100644 web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/functions.js create mode 100644 web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/groupBillSearch.js create mode 100644 web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/gBmr/searchResults.js 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 From fb07e4aa3d68a6f59055c16b1509376aeeea725b Mon Sep 17 00:00:00 2001 From: anujkit Date: Thu, 2 Apr 2026 12:34:21 +0530 Subject: [PATCH 08/64] PI-20912 Water Dcb Breakdown Penalty Amount Not showing (WS_BREAKDOWN_PENALTY) --- .../src/ui-config/screens/specs/wns/connection-details.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/screens/specs/wns/connection-details.js b/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/screens/specs/wns/connection-details.js index c447a25570..a907e75984 100644 --- a/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/screens/specs/wns/connection-details.js +++ b/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/screens/specs/wns/connection-details.js @@ -560,7 +560,7 @@ export const getDCBDetail = async (queryObject , dispatch) => { interestCollected=interestCollected+dd.collectionAmount; interestBalance=interestAmount-interestCollected; } - if(dd.taxHeadMasterCode=='WS_TIME_PENALTY' || dd.taxHeadMasterCode=='SW_TIME_PENALTY'){ + if(dd.taxHeadMasterCode=='WS_TIME_PENALTY' || dd.taxHeadMasterCode=='SW_TIME_PENALTY' || dd.taxHeadMasterCode == 'WS_BREAKDOWN_PENALTY' || dd.taxHeadMasterCode == 'SW_BREAKDOWN_PENALTY'){ penaltyAmount=penaltyAmount+dd.taxAmount; penaltyCollected=penaltyCollected+dd.collectionAmount; penaltyBalance=penaltyAmount-penaltyCollected; From 522ec7eab34e95d78b439c2f7f9682a55b1000a6 Mon Sep 17 00:00:00 2001 From: anujkit Date: Tue, 7 Apr 2026 14:49:46 +0530 Subject: [PATCH 09/64] Year property creation 2026-27 and dates to rectify --- .../specs/PropertyTaxPay/propertyAddress.js | 17 +++++----- .../src/redux/common/actions.js | 31 ++++++++++++++++++- .../src/Screens/FormWizard/index.js | 20 +++++++++--- .../specs/PropertyTaxPay/propertyAddress.js | 16 +++++----- 4 files changed, 64 insertions(+), 20 deletions(-) diff --git a/web/rainmaker/dev-packages/egov-ui-kit-dev/src/config/forms/specs/PropertyTaxPay/propertyAddress.js b/web/rainmaker/dev-packages/egov-ui-kit-dev/src/config/forms/specs/PropertyTaxPay/propertyAddress.js index 68aae207b6..0b4b686fd5 100644 --- a/web/rainmaker/dev-packages/egov-ui-kit-dev/src/config/forms/specs/PropertyTaxPay/propertyAddress.js +++ b/web/rainmaker/dev-packages/egov-ui-kit-dev/src/config/forms/specs/PropertyTaxPay/propertyAddress.js @@ -1,17 +1,12 @@ import { mohalla } from "egov-ui-kit/config/forms/specs/PropertyTaxPay/utils/reusableFields"; import { fetchLocalizationLabel } from "egov-ui-kit/redux/app/actions"; -import { fetchGeneralMDMSData, prepareFormData } from "egov-ui-kit/redux/common/actions"; +import { fetchGeneralMDMSData, fetchFinancialYearData, prepareFormData } from "egov-ui-kit/redux/common/actions"; import { setFieldProperty } from "egov-ui-kit/redux/form/actions"; import { fetchDropdownData, generalMDMSDataRequestObj, getGeneralMDMSDataDropdownName, getTranslatedLabel } from "egov-ui-kit/utils/commons"; import { getLocale } from "egov-ui-kit/utils/localStorageUtils"; import filter from "lodash/filter"; import get from "lodash/get"; import sortBy from "lodash/sortBy"; -let floorDropDownData = []; - -floorDropDownData.push({ label: "2013-14", value: "2013-14" }, { label: "2014-15", value: "2014-15" }, { label: "2015-16", value: "2015-16" }, { label: "2016-17", value: "2016-17" }, { label: "2017-18", value: "2017-18" }, { label: "2018-19", value: "2018-19" }, - { label: "2019-20", value: "2019-20" }, { label: "2020-21", value: "2020-21" }, - { label: "2021-22", value: "2021-22" }, { label: "2022-23", value: "2022-23" }, { label: "2023-24", value: "2023-24" }, { label: "2024-25", value: "2024-25" }, { label: "2025-26", value: "2025-26" }); const formConfig = { name: "propertyAddress", fields: { @@ -144,7 +139,7 @@ const formConfig = { YearcreationProperty: { id: "YearcreationProperty", type: "AutocompleteDropdown", - className: "pt-old-pid-text-field", + //className: "pt-old-pid-text-field", // iconRedirectionURL: getTenantId()=='pb.amritsar'? "https://arcserver.punjab.gov.in/portal/apps/webappviewer/index.html?id=8b678d4d5020448499054bf346843ea9": getTenantId()=='pb.hoshiarpur'?"https://arcserver.punjab.gov.in/portal/apps/webappviewer/index.html?id=9bc1b255320a49c590dd17d4d258e054": "https://gis.punjab.gov.in", jsonPath: "Properties[0].additionalDetails.yearConstruction", floatingLabelText: "Year of creation of Property", @@ -158,7 +153,6 @@ const formConfig = { errorMessage: "PT_PROPERTY_DETAILS_PINCODE_ERRORMSG", errorStyle: { position: "absolute", bottom: -8, zIndex: 5 }, formName: "propertyAddress", - dropDownData: floorDropDownData, updateDependentFields: ({ formKey, field, dispatch }) => { if (field.value && field.value.length > 0) { const mohalla = field.dropDownData.find((option) => { @@ -200,6 +194,13 @@ const formConfig = { // dispatch(setFieldProperty("propertyAddress", "YearcreationProperty", "value", yearConstructionValue)); // } + const financialYears = get(state, 'common.dropDownData.FinancialYear', []); + if (financialYears.length > 0) { + dispatch(setFieldProperty("propertyAddress", "YearcreationProperty", "dropDownData", financialYears)); + } else { + dispatch(fetchFinancialYearData()); + } + if (process.env.REACT_APP_NAME === "Citizen" && tenant && mohallaDropDownData.length == 0) { const dataFetchConfig = { url: "egov-location/location/v11/boundarys/_search?hierarchyTypeCode=REVENUE&boundaryType=Locality", diff --git a/web/rainmaker/dev-packages/egov-ui-kit-dev/src/redux/common/actions.js b/web/rainmaker/dev-packages/egov-ui-kit-dev/src/redux/common/actions.js index 493d115248..1000894bfb 100644 --- a/web/rainmaker/dev-packages/egov-ui-kit-dev/src/redux/common/actions.js +++ b/web/rainmaker/dev-packages/egov-ui-kit-dev/src/redux/common/actions.js @@ -191,7 +191,36 @@ export const fetchGeneralMDMSData = (requestBody, moduleName, masterArray, key, } }; }; - +export const fetchFinancialYearData = () => { + return async (dispatch) => { + const requestBody = { + MdmsCriteria: { + tenantId: commonConfig.tenantId, + moduleDetails: [ + { + moduleName: "egf-master", + masterDetails: [ + { + name: "FinancialYear", + filter: "[?(@.module == 'PT')]", + }, + ], + }, + ], + }, + }; + try { + const payload = await httpRequest(MDMS.GET.URL, MDMS.GET.ACTION, [], requestBody); + const financialYears = payload.MdmsRes["egf-master"].FinancialYear.map(fy => ({ + label: fy.finYearRange, + value: fy.finYearRange, + })); + dispatch(setDropDownData("FinancialYear", financialYears)); + } catch (error) { + dispatch(generalMDMSFetchError(error.message)); + } + }; +}; export const toggleSpinner = () => ({ type: actionTypes.TOGGLE_SPINNER, }); diff --git a/web/rainmaker/dev-packages/pt-employee-dev/src/Screens/FormWizard/index.js b/web/rainmaker/dev-packages/pt-employee-dev/src/Screens/FormWizard/index.js index 921bb04791..14c4bb2226 100644 --- a/web/rainmaker/dev-packages/pt-employee-dev/src/Screens/FormWizard/index.js +++ b/web/rainmaker/dev-packages/pt-employee-dev/src/Screens/FormWizard/index.js @@ -8,8 +8,8 @@ import { getHeaderDetails } from "egov-ui-kit/common/propertyTax/PaymentStatus/C import DocumentsUpload from "egov-ui-kit/common/propertyTax/Property/components/DocumentsUpload"; import { createAssessmentPayload, getCreatePropertyResponse, prefillPTDocuments, setOldPropertyData } from "egov-ui-kit/config/forms/specs/PropertyTaxPay/propertyCreateUtils"; import { setRoute, toggleSnackbarAndSetText, fetchLocalizationLabel } from "egov-ui-kit/redux/app/actions"; -import { fetchGeneralMDMSData, generalMDMSFetchSuccess, hideSpinner, prepareFormData as prepareFormDataAction, showSpinner, toggleSpinner, updatePrepareFormDataFromDraft } from "egov-ui-kit/redux/common/actions"; -import { deleteForm, displayFormErrors, handleFieldChange, removeForm, updateForms } from "egov-ui-kit/redux/form/actions"; +import { fetchGeneralMDMSData, fetchFinancialYearData, generalMDMSFetchSuccess, hideSpinner, prepareFormData as prepareFormDataAction, showSpinner, toggleSpinner, updatePrepareFormDataFromDraft } from "egov-ui-kit/redux/common/actions"; +import { deleteForm, displayFormErrors, handleFieldChange, removeForm, setFieldProperty, updateForms } from "egov-ui-kit/redux/form/actions"; import { validateForm } from "egov-ui-kit/redux/form/utils"; import { fetchAssessments } from "egov-ui-kit/redux/properties/actions"; import { httpRequest } from "egov-ui-kit/utils/api"; @@ -302,7 +302,7 @@ class FormWizard extends Component { renderCustomTitleForPt, showSpinner, hideSpinner, - fetchGeneralMDMSData, history, + fetchGeneralMDMSData, fetchFinancialYearData, history, prepareFinalObject, fetchLocalizationLabel } = this.props; @@ -320,7 +320,9 @@ class FormWizard extends Component { const tenantId = getQueryValue(search, "tenantId"); fetchLocalizationLabel(getLocale(), tenantId, tenantId); let requestBody = generalMDMSDataRequestObj(commonConfig.tenantId); + //console.log("sdghsgdsh") fetchGeneralMDMSData(requestBody, "PropertyTax", getGeneralMDMSDataDropdownName()); + fetchFinancialYearData(); this.loadUlbLogo(tenantId) const draftUuid = getQueryValue(search, "uuid"); const assessmentId = @@ -1837,7 +1839,7 @@ onPayButtonClick = async () => { hideSpinner(); } }; -componentDidUpdate() { +componentDidUpdate(prevProps) { const { selected, formValidIndexArray, @@ -1852,6 +1854,13 @@ componentDidUpdate() { formValidIndexArray: [...formValidIndexArray, 3] }); } + + // Set financial year dropdown when data arrives from Redux + const financialYears = get(this.props, "common.dropDownData.FinancialYear", []); + const prevFinancialYears = get(prevProps, "common.dropDownData.FinancialYear", []); + if (financialYears.length > 0 && financialYears !== prevFinancialYears) { + this.props.setFieldProperty("propertyAddress", "YearcreationProperty", "dropDownData", financialYears); + } } convertImgToDataURLviaCanvas = (url, callback, outputFormat) => { var img = new Image(); @@ -2003,6 +2012,9 @@ const mapDispatchToProps = dispatch => { dispatch(prepareFinalObject(jsonPath, value)), toggleSpinner: () => dispatch(toggleSpinner()), fetchAssessments: (fetchAssessmentsQueryObject) => dispatch(fetchAssessments(fetchAssessmentsQueryObject)), + fetchFinancialYearData: () => dispatch(fetchFinancialYearData()), + setFieldProperty: (formKey, fieldKey, property, value) => + dispatch(setFieldProperty(formKey, fieldKey, property, value)), fetchLocalizationLabel: (locale, moduleName, tenantId) => dispatch(fetchLocalizationLabel(locale, moduleName, tenantId)) }; }; diff --git a/web/rainmaker/packages/employee/src/config/forms/specs/PropertyTaxPay/propertyAddress.js b/web/rainmaker/packages/employee/src/config/forms/specs/PropertyTaxPay/propertyAddress.js index d3f70ded40..755f0117e3 100644 --- a/web/rainmaker/packages/employee/src/config/forms/specs/PropertyTaxPay/propertyAddress.js +++ b/web/rainmaker/packages/employee/src/config/forms/specs/PropertyTaxPay/propertyAddress.js @@ -1,7 +1,7 @@ import { pincode, mohalla, street, colony, houseNumber } from "egov-ui-kit/config/forms/specs/PropertyTaxPay/utils/reusableFields"; import { handleFieldChange, setFieldProperty } from "egov-ui-kit/redux/form/actions"; import { CITY } from "egov-ui-kit/utils/endPoints"; -import { prepareFormData } from "egov-ui-kit/redux/common/actions"; +import { prepareFormData, fetchFinancialYearData } from "egov-ui-kit/redux/common/actions"; import set from "lodash/set"; import get from "lodash/get"; import { getLocale, getTenantId } from "egov-ui-kit/utils/localStorageUtils"; @@ -12,11 +12,6 @@ import { httpRequest } from "egov-ui-kit/utils/api"; // const Search = ; var tenantIdcode = getTenantId(); -let floorDropDownData = []; - -floorDropDownData.push({ label: "2013-14", value: "2013-14" }, { label: "2014-15", value: "2014-15" }, { label: "2015-16", value: "2015-16" }, { label: "2016-17", value: "2016-17" }, { label: "2017-18", value: "2017-18" }, { label: "2018-19", value: "2018-19" }, - { label: "2019-20", value: "2019-20" }, { label: "2020-21", value: "2020-21" }, - { label: "2021-22", value: "2021-22" }, { label: "2022-23", value: "2022-23" }, { label: "2023-24", value: "2023-24" }, { label: "2024-25", value: "2024-25" }, { label: "2025-26", value: "2025-26" }); const formConfig = { @@ -192,7 +187,7 @@ const formConfig = { errorStyle: { position: "absolute", bottom: -8, zIndex: 5 }, formName: "propertyAddress", - dropDownData: floorDropDownData, + dropDownData: [], updateDependentFields: ({ formKey, field, dispatch }) => { if (field.value && field.value.length > 0) { const mohalla = field.dropDownData.find((option) => { @@ -212,6 +207,13 @@ const formConfig = { let tenantId = getTenantId(); let state = store.getState(); const { citiesByModule } = state.common; + // Load financial year dropdown from Redux + const financialYearData = get(state, "common.dropDownData.FinancialYear", []); + if (financialYearData.length > 0) { + set(action, "form.fields.YearcreationProperty.dropDownData", financialYearData); + } else { + dispatch(fetchFinancialYearData()); + } const { PT } = citiesByModule || {}; if (PT) { const tenants = PT.tenants; From d4ac12a1819e1c8d29e747f36464eb83b6a8ec6d Mon Sep 17 00:00:00 2001 From: anujkit Date: Tue, 7 Apr 2026 16:41:17 +0530 Subject: [PATCH 10/64] Year property creation 2026-27 and dates to rectify --- .../forms/specs/PropertyTaxPay/propertyAddress.js | 14 +++++++------- .../egov-ui-kit-dev/src/utils/PTCommon/index.js | 4 ++-- .../src/Screens/FormWizard/index.js | 14 ++++++++++++++ .../forms/specs/PropertyTaxPay/propertyAddress.js | 8 ++++++-- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/web/rainmaker/dev-packages/egov-ui-kit-dev/src/config/forms/specs/PropertyTaxPay/propertyAddress.js b/web/rainmaker/dev-packages/egov-ui-kit-dev/src/config/forms/specs/PropertyTaxPay/propertyAddress.js index 0b4b686fd5..e75a9455ce 100644 --- a/web/rainmaker/dev-packages/egov-ui-kit-dev/src/config/forms/specs/PropertyTaxPay/propertyAddress.js +++ b/web/rainmaker/dev-packages/egov-ui-kit-dev/src/config/forms/specs/PropertyTaxPay/propertyAddress.js @@ -186,17 +186,17 @@ const formConfig = { dispatch(setFieldProperty("propertyAddress", "city", "dropDownData", sortBy(dd, ["label"]))); } const tenant = get(state, 'form.propertyAddress.fields.city.value', null); - const mohallaDropDownData = get(state, 'form.propertyAddress.fields.mohalla.dropDownData', []); - // const yearConstructionValue = get(state, 'screenConfiguration.preparedFinalObject.Properties[0].additionalDetails.yearConstruction', null); - // get(state, 'Properties[0].additionalDetails.yearConstruction', null) || get(state, 'form.Properties[0].additionalDetails.yearConstruction', null) || - - // if (yearConstructionValue) { - // dispatch(setFieldProperty("propertyAddress", "YearcreationProperty", "value", yearConstructionValue)); - // } + const mohallaDropDownData = get(state, 'form.propertyAddress.fields.mohalla.dropDownData', []); + // Set YearcreationProperty dropdown and value for update mode const financialYears = get(state, 'common.dropDownData.FinancialYear', []); if (financialYears.length > 0) { dispatch(setFieldProperty("propertyAddress", "YearcreationProperty", "dropDownData", financialYears)); + // Set value if present in preparedFinalObject + const yearValue = get(state, 'screenConfiguration.preparedFinalObject.Properties[0].additionalDetails.yearConstruction', null); + if (yearValue) { + dispatch(setFieldProperty("propertyAddress", "YearcreationProperty", "value", yearValue)); + } } else { dispatch(fetchFinancialYearData()); } diff --git a/web/rainmaker/dev-packages/egov-ui-kit-dev/src/utils/PTCommon/index.js b/web/rainmaker/dev-packages/egov-ui-kit-dev/src/utils/PTCommon/index.js index 2fd44f3f55..16200380cb 100644 --- a/web/rainmaker/dev-packages/egov-ui-kit-dev/src/utils/PTCommon/index.js +++ b/web/rainmaker/dev-packages/egov-ui-kit-dev/src/utils/PTCommon/index.js @@ -194,9 +194,9 @@ export const findCorrectDateObj = (financialYear, category) => { } else if (chosenDateObj.endingDay) { month = getMonth(chosenDateObj.endingDay); if (month === 1 || month === 2 || month === 3) { - chosenDateObj.endingDay = chosenDateObj.endingDay + `/${++assessYear}`; + chosenDateObj.endingDay = chosenDateObj.endingDay ; } else { - chosenDateObj.endingDay = chosenDateObj.endingDay + `/${assessYear}`; + chosenDateObj.endingDay = chosenDateObj.endingDay; } } return chosenDateObj; diff --git a/web/rainmaker/dev-packages/pt-employee-dev/src/Screens/FormWizard/index.js b/web/rainmaker/dev-packages/pt-employee-dev/src/Screens/FormWizard/index.js index 14c4bb2226..3ddd2151ec 100644 --- a/web/rainmaker/dev-packages/pt-employee-dev/src/Screens/FormWizard/index.js +++ b/web/rainmaker/dev-packages/pt-employee-dev/src/Screens/FormWizard/index.js @@ -398,6 +398,16 @@ class FormWizard extends Component { if (isModify) { await setOldPropertyData(search, prepareFinalObject); } + + // If financial year data is already in Redux store, set dropdown and value now + const existingFinancialYears = get(this.props, "common.dropDownData.FinancialYear", []); + if (existingFinancialYears.length > 0) { + this.props.setFieldProperty("propertyAddress", "YearcreationProperty", "dropDownData", existingFinancialYears); + const yearValue = get(this.props, "prepareFormData.Properties[0].additionalDetails.yearConstruction", null); + if (yearValue) { + this.props.setFieldProperty("propertyAddress", "YearcreationProperty", "value", yearValue); + } + } //--------------------------------------------- }; @@ -1860,6 +1870,10 @@ componentDidUpdate(prevProps) { const prevFinancialYears = get(prevProps, "common.dropDownData.FinancialYear", []); if (financialYears.length > 0 && financialYears !== prevFinancialYears) { this.props.setFieldProperty("propertyAddress", "YearcreationProperty", "dropDownData", financialYears); + const yearValue = get(this.props, "prepareFormData.Properties[0].additionalDetails.yearConstruction", null); + if (yearValue) { + this.props.setFieldProperty("propertyAddress", "YearcreationProperty", "value", yearValue); + } } } convertImgToDataURLviaCanvas = (url, callback, outputFormat) => { diff --git a/web/rainmaker/packages/employee/src/config/forms/specs/PropertyTaxPay/propertyAddress.js b/web/rainmaker/packages/employee/src/config/forms/specs/PropertyTaxPay/propertyAddress.js index 755f0117e3..412128fe98 100644 --- a/web/rainmaker/packages/employee/src/config/forms/specs/PropertyTaxPay/propertyAddress.js +++ b/web/rainmaker/packages/employee/src/config/forms/specs/PropertyTaxPay/propertyAddress.js @@ -211,6 +211,12 @@ const formConfig = { const financialYearData = get(state, "common.dropDownData.FinancialYear", []); if (financialYearData.length > 0) { set(action, "form.fields.YearcreationProperty.dropDownData", financialYearData); + dispatch(setFieldProperty("propertyAddress", "YearcreationProperty", "dropDownData", financialYearData)); + // Set value if present in preparedFinalObject + const yearValue = get(state, 'screenConfiguration.preparedFinalObject.Properties[0].additionalDetails.yearConstruction', null); + if (yearValue) { + dispatch(setFieldProperty("propertyAddress", "YearcreationProperty", "value", yearValue)); + } } else { dispatch(fetchFinancialYearData()); } @@ -232,8 +238,6 @@ const formConfig = { cityName = tenantInfo.city.name; let surveyId = get(state.screenConfiguration.preparedFinalObject, "Properties[0].surveyId"); - let year = get(state.screenConfiguration.preparedFinalObject, "Properties[0].additionalDetails.yearConstruction"); - dispatch(handleFieldChange("propertyAddress", "YearcreationProperty", year)); if (surveyId) dispatch(handleFieldChange("propertyAddress", "UID", surveyId)); From c978312e1d3b900341a2edefab063073a309056f Mon Sep 17 00:00:00 2001 From: anujkit Date: Thu, 23 Apr 2026 16:11:24 +0530 Subject: [PATCH 11/64] PI-21257 google API Key Changes --- .../dev-packages/egov-abg-dev/src/ui-config/abg-app-config.js | 2 +- .../egov-billamend-dev/src/ui-config/noc-app-config.js | 2 +- .../egov-boilerplate-dev/src/ui-config/noc-app-config.js | 2 +- web/rainmaker/dev-packages/egov-bpa-dev/src/config/common.js | 2 +- .../dev-packages/egov-bpa-dev/src/ui-config/noc-app-config.js | 2 +- .../dev-packages/egov-bpa-dev/src/ui-config/tl-app-config.js | 2 +- web/rainmaker/dev-packages/egov-common-dev/src/config/common.js | 2 +- .../egov-common-dev/src/ui-config/common-app-config.js | 2 +- .../dev-packages/egov-firenoc-dev/src/config/common.js | 2 +- .../egov-firenoc-dev/src/ui-config/noc-app-config.js | 2 +- web/rainmaker/dev-packages/egov-noc-dev/src/config/common.js | 2 +- .../dev-packages/egov-noc-dev/src/ui-config/noc-app-config.js | 2 +- .../dev-packages/egov-pt-dev/src/ui-config/pt-app-config.js | 2 +- .../egov-ui-framework-core/src/ui-config/app-config.js | 2 +- .../dev-packages/egov-wns-dev/src/ui-config/tl-app-config.js | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/abg-app-config.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/abg-app-config.js index fb3bfac35d..ff272ed63f 100644 --- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/abg-app-config.js +++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/abg-app-config.js @@ -1,2 +1,2 @@ export const defaultLocation = { lat: 30.7333, lng: 76.7794 }; -export const MAP_API_KEY = "AIzaSyCH9PmCbk_mcpgijAAlTeltC4deOxC5wEM"; //CHANGE THIS +export const MAP_API_KEY = "AIzaSyB5xqCmrgz-IL-mPQiy7PI_mA4drmyr2fo"; //CHANGE THIS diff --git a/web/rainmaker/dev-packages/egov-billamend-dev/src/ui-config/noc-app-config.js b/web/rainmaker/dev-packages/egov-billamend-dev/src/ui-config/noc-app-config.js index fb3bfac35d..ff272ed63f 100644 --- a/web/rainmaker/dev-packages/egov-billamend-dev/src/ui-config/noc-app-config.js +++ b/web/rainmaker/dev-packages/egov-billamend-dev/src/ui-config/noc-app-config.js @@ -1,2 +1,2 @@ export const defaultLocation = { lat: 30.7333, lng: 76.7794 }; -export const MAP_API_KEY = "AIzaSyCH9PmCbk_mcpgijAAlTeltC4deOxC5wEM"; //CHANGE THIS +export const MAP_API_KEY = "AIzaSyB5xqCmrgz-IL-mPQiy7PI_mA4drmyr2fo"; //CHANGE THIS diff --git a/web/rainmaker/dev-packages/egov-boilerplate-dev/src/ui-config/noc-app-config.js b/web/rainmaker/dev-packages/egov-boilerplate-dev/src/ui-config/noc-app-config.js index fb3bfac35d..ff272ed63f 100644 --- a/web/rainmaker/dev-packages/egov-boilerplate-dev/src/ui-config/noc-app-config.js +++ b/web/rainmaker/dev-packages/egov-boilerplate-dev/src/ui-config/noc-app-config.js @@ -1,2 +1,2 @@ export const defaultLocation = { lat: 30.7333, lng: 76.7794 }; -export const MAP_API_KEY = "AIzaSyCH9PmCbk_mcpgijAAlTeltC4deOxC5wEM"; //CHANGE THIS +export const MAP_API_KEY = "AIzaSyB5xqCmrgz-IL-mPQiy7PI_mA4drmyr2fo"; //CHANGE THIS diff --git a/web/rainmaker/dev-packages/egov-bpa-dev/src/config/common.js b/web/rainmaker/dev-packages/egov-bpa-dev/src/config/common.js index 5e079f3062..8f3c8b6ce6 100644 --- a/web/rainmaker/dev-packages/egov-bpa-dev/src/config/common.js +++ b/web/rainmaker/dev-packages/egov-bpa-dev/src/config/common.js @@ -1,5 +1,5 @@ const commonConfig = { - MAP_API_KEY: "AIzaSyCH9PmCbk_mcpgijAAlTeltC4deOxC5wEM", + MAP_API_KEY: "AIzaSyB5xqCmrgz-IL-mPQiy7PI_mA4drmyr2fo", tenantId: process.env.REACT_APP_DEFAULT_TENANT_ID // forgotPasswordTenant: "pb.amritsar", }; diff --git a/web/rainmaker/dev-packages/egov-bpa-dev/src/ui-config/noc-app-config.js b/web/rainmaker/dev-packages/egov-bpa-dev/src/ui-config/noc-app-config.js index fb3bfac35d..ff272ed63f 100644 --- a/web/rainmaker/dev-packages/egov-bpa-dev/src/ui-config/noc-app-config.js +++ b/web/rainmaker/dev-packages/egov-bpa-dev/src/ui-config/noc-app-config.js @@ -1,2 +1,2 @@ export const defaultLocation = { lat: 30.7333, lng: 76.7794 }; -export const MAP_API_KEY = "AIzaSyCH9PmCbk_mcpgijAAlTeltC4deOxC5wEM"; //CHANGE THIS +export const MAP_API_KEY = "AIzaSyB5xqCmrgz-IL-mPQiy7PI_mA4drmyr2fo"; //CHANGE THIS diff --git a/web/rainmaker/dev-packages/egov-bpa-dev/src/ui-config/tl-app-config.js b/web/rainmaker/dev-packages/egov-bpa-dev/src/ui-config/tl-app-config.js index f04a1aacbe..bb9925a947 100644 --- a/web/rainmaker/dev-packages/egov-bpa-dev/src/ui-config/tl-app-config.js +++ b/web/rainmaker/dev-packages/egov-bpa-dev/src/ui-config/tl-app-config.js @@ -1,2 +1,2 @@ export const defaultLocation = { lat: 30.7333, lng: 76.7794 }; -export const MAP_API_KEY = "AIzaSyCH9PmCbk_mcpgijAAlTeltC4deOxC5wEM"; +export const MAP_API_KEY = "AIzaSyB5xqCmrgz-IL-mPQiy7PI_mA4drmyr2fo"; diff --git a/web/rainmaker/dev-packages/egov-common-dev/src/config/common.js b/web/rainmaker/dev-packages/egov-common-dev/src/config/common.js index 5e079f3062..8f3c8b6ce6 100644 --- a/web/rainmaker/dev-packages/egov-common-dev/src/config/common.js +++ b/web/rainmaker/dev-packages/egov-common-dev/src/config/common.js @@ -1,5 +1,5 @@ const commonConfig = { - MAP_API_KEY: "AIzaSyCH9PmCbk_mcpgijAAlTeltC4deOxC5wEM", + MAP_API_KEY: "AIzaSyB5xqCmrgz-IL-mPQiy7PI_mA4drmyr2fo", tenantId: process.env.REACT_APP_DEFAULT_TENANT_ID // forgotPasswordTenant: "pb.amritsar", }; diff --git a/web/rainmaker/dev-packages/egov-common-dev/src/ui-config/common-app-config.js b/web/rainmaker/dev-packages/egov-common-dev/src/ui-config/common-app-config.js index fb3bfac35d..ff272ed63f 100644 --- a/web/rainmaker/dev-packages/egov-common-dev/src/ui-config/common-app-config.js +++ b/web/rainmaker/dev-packages/egov-common-dev/src/ui-config/common-app-config.js @@ -1,2 +1,2 @@ export const defaultLocation = { lat: 30.7333, lng: 76.7794 }; -export const MAP_API_KEY = "AIzaSyCH9PmCbk_mcpgijAAlTeltC4deOxC5wEM"; //CHANGE THIS +export const MAP_API_KEY = "AIzaSyB5xqCmrgz-IL-mPQiy7PI_mA4drmyr2fo"; //CHANGE THIS diff --git a/web/rainmaker/dev-packages/egov-firenoc-dev/src/config/common.js b/web/rainmaker/dev-packages/egov-firenoc-dev/src/config/common.js index 5e079f3062..8f3c8b6ce6 100644 --- a/web/rainmaker/dev-packages/egov-firenoc-dev/src/config/common.js +++ b/web/rainmaker/dev-packages/egov-firenoc-dev/src/config/common.js @@ -1,5 +1,5 @@ const commonConfig = { - MAP_API_KEY: "AIzaSyCH9PmCbk_mcpgijAAlTeltC4deOxC5wEM", + MAP_API_KEY: "AIzaSyB5xqCmrgz-IL-mPQiy7PI_mA4drmyr2fo", tenantId: process.env.REACT_APP_DEFAULT_TENANT_ID // forgotPasswordTenant: "pb.amritsar", }; diff --git a/web/rainmaker/dev-packages/egov-firenoc-dev/src/ui-config/noc-app-config.js b/web/rainmaker/dev-packages/egov-firenoc-dev/src/ui-config/noc-app-config.js index fb3bfac35d..ff272ed63f 100644 --- a/web/rainmaker/dev-packages/egov-firenoc-dev/src/ui-config/noc-app-config.js +++ b/web/rainmaker/dev-packages/egov-firenoc-dev/src/ui-config/noc-app-config.js @@ -1,2 +1,2 @@ export const defaultLocation = { lat: 30.7333, lng: 76.7794 }; -export const MAP_API_KEY = "AIzaSyCH9PmCbk_mcpgijAAlTeltC4deOxC5wEM"; //CHANGE THIS +export const MAP_API_KEY = "AIzaSyB5xqCmrgz-IL-mPQiy7PI_mA4drmyr2fo"; //CHANGE THIS diff --git a/web/rainmaker/dev-packages/egov-noc-dev/src/config/common.js b/web/rainmaker/dev-packages/egov-noc-dev/src/config/common.js index 5e079f3062..8f3c8b6ce6 100644 --- a/web/rainmaker/dev-packages/egov-noc-dev/src/config/common.js +++ b/web/rainmaker/dev-packages/egov-noc-dev/src/config/common.js @@ -1,5 +1,5 @@ const commonConfig = { - MAP_API_KEY: "AIzaSyCH9PmCbk_mcpgijAAlTeltC4deOxC5wEM", + MAP_API_KEY: "AIzaSyB5xqCmrgz-IL-mPQiy7PI_mA4drmyr2fo", tenantId: process.env.REACT_APP_DEFAULT_TENANT_ID // forgotPasswordTenant: "pb.amritsar", }; diff --git a/web/rainmaker/dev-packages/egov-noc-dev/src/ui-config/noc-app-config.js b/web/rainmaker/dev-packages/egov-noc-dev/src/ui-config/noc-app-config.js index fb3bfac35d..ff272ed63f 100644 --- a/web/rainmaker/dev-packages/egov-noc-dev/src/ui-config/noc-app-config.js +++ b/web/rainmaker/dev-packages/egov-noc-dev/src/ui-config/noc-app-config.js @@ -1,2 +1,2 @@ export const defaultLocation = { lat: 30.7333, lng: 76.7794 }; -export const MAP_API_KEY = "AIzaSyCH9PmCbk_mcpgijAAlTeltC4deOxC5wEM"; //CHANGE THIS +export const MAP_API_KEY = "AIzaSyB5xqCmrgz-IL-mPQiy7PI_mA4drmyr2fo"; //CHANGE THIS diff --git a/web/rainmaker/dev-packages/egov-pt-dev/src/ui-config/pt-app-config.js b/web/rainmaker/dev-packages/egov-pt-dev/src/ui-config/pt-app-config.js index fb3bfac35d..ff272ed63f 100644 --- a/web/rainmaker/dev-packages/egov-pt-dev/src/ui-config/pt-app-config.js +++ b/web/rainmaker/dev-packages/egov-pt-dev/src/ui-config/pt-app-config.js @@ -1,2 +1,2 @@ export const defaultLocation = { lat: 30.7333, lng: 76.7794 }; -export const MAP_API_KEY = "AIzaSyCH9PmCbk_mcpgijAAlTeltC4deOxC5wEM"; //CHANGE THIS +export const MAP_API_KEY = "AIzaSyB5xqCmrgz-IL-mPQiy7PI_mA4drmyr2fo"; //CHANGE THIS diff --git a/web/rainmaker/dev-packages/egov-ui-framework-core/src/ui-config/app-config.js b/web/rainmaker/dev-packages/egov-ui-framework-core/src/ui-config/app-config.js index f071ddf817..8bc6bab9fc 100644 --- a/web/rainmaker/dev-packages/egov-ui-framework-core/src/ui-config/app-config.js +++ b/web/rainmaker/dev-packages/egov-ui-framework-core/src/ui-config/app-config.js @@ -1,2 +1,2 @@ export const defaultLocation = { lat: 31.633980, lng: -74.872261 }; -export const MAP_API_KEY = "AIzaSyDjSk-Bw1OuiOE-5K7jsP6KGN2rbcN7iBk"; +export const MAP_API_KEY = "AIzaSyB5xqCmrgz-IL-mPQiy7PI_mA4drmyr2fo"; diff --git a/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/tl-app-config.js b/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/tl-app-config.js index f04a1aacbe..bb9925a947 100644 --- a/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/tl-app-config.js +++ b/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/tl-app-config.js @@ -1,2 +1,2 @@ export const defaultLocation = { lat: 30.7333, lng: 76.7794 }; -export const MAP_API_KEY = "AIzaSyCH9PmCbk_mcpgijAAlTeltC4deOxC5wEM"; +export const MAP_API_KEY = "AIzaSyB5xqCmrgz-IL-mPQiy7PI_mA4drmyr2fo"; From 767b5e37f94d3350588ec8fc4203076af28b7573 Mon Sep 17 00:00:00 2001 From: erramesh000 Date: Tue, 28 Apr 2026 17:41:11 +0530 Subject: [PATCH 12/64] Fixed issues Bulkmeter screen and Usage Category --- .../screens/specs/abg/gBmr/functions.js | 32 ++++- .../screens/specs/abg/gBmr/searchResults.js | 119 ++++++++++-------- 2 files changed, 94 insertions(+), 57 deletions(-) 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 index 90c428682a..0a2b72ae53 100644 --- 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 @@ -18,7 +18,7 @@ import { loadUlbLogo } from "../../utils/receiptTransformer"; // const tenantId = getTenantId(); const tenantId = getTenantId(); -export const updatesingleReading = async (consumerId, lastReading, currentReadingRaw, currentReading, billingPeriod, status, readingDate, lastReadingDate, tenantId) => { +export const updatesingleReading = async (consumerId, lastReading, currentReadingRaw, currentReading, billingPeriod, status, readingDate, lastReadingDate, tenantId, dispatch) => { const payload = { meterReadingslist: [ @@ -38,14 +38,32 @@ export const updatesingleReading = async (consumerId, lastReading, currentReadin }; try { + if (dispatch) { + dispatch(toggleSpinner(true)); + } const url = "/ws-calculator/meterConnection/_createmultiple"; const response = await httpRequest("post", url, "_update", [], payload); - + if (dispatch) { + dispatch(toggleSpinner(false)); + } + dispatch( + toggleSnackbar( + true, + { + labelName: "Bulk update successful", + labelKey: "ABG_BULK_UPDATE_SUCCESS" + }, + "success" + ) + ); return response; } catch (e) { + if (dispatch) { + dispatch(toggleSpinner(false)); + } console.error("API error:", e); throw e; } @@ -129,9 +147,9 @@ export const searchApiCall = async (state, dispatch) => { // dispatch(toggleSpinner(false)); // return response; - const bills = (response && response.meterReadings) || []; + const bills = (response && response.bulkMeterReadings) || []; dispatch( - prepareFinalObject("searchScreenMdmsData.meterReadings", bills) + prepareFinalObject("searchScreenMdmsData.bulkMeterReadings", bills) ); dispatch(toggleSpinner(false)); return response; @@ -152,7 +170,7 @@ export const searchApiCall = async (state, dispatch) => { const responseFromAPI = await getGroupBillSearch(dispatch, searchScreenObject); - const bills = (responseFromAPI && responseFromAPI.meterReadings) || []; + const bills = (responseFromAPI && responseFromAPI.bulkMeterReadings) || []; dispatch( prepareFinalObject("searchScreenMdmsData.billSearchResponse", bills) ); @@ -168,6 +186,7 @@ export const searchApiCall = async (state, dispatch) => { currentReadingDate: get(bills[i], "currentReadingDate"), billingPeriod: get(bills[i], "billingPeriod"), meterStatus: get(bills[i], "meterStatus"), + usageCategory: get(bills[i], "usageCategory") || "", tenantId: tenantId }) @@ -175,7 +194,7 @@ export const searchApiCall = async (state, dispatch) => { try { let data = response.map(item => ({ ["Consumer ID"]: item.connectionNo || "-", - + ["Usage Category"]: item.usageCategory || "-", // last confirmed reading from system ["Last Reading"]: item.currentReading || "-", @@ -188,6 +207,7 @@ export const searchApiCall = async (state, dispatch) => { convertEpochToDate(item.currentReadingDate) || "-", ["Billing Period"]: item.billingPeriod || "-", ["Status"]: item.meterStatus || "-", + ["TENANT_ID"]: item.tenantId })); dispatch( 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 index da0b33f93d..0b436e81c5 100644 --- 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 @@ -2,9 +2,10 @@ 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 { httpRequest } from "egov-ui-framework/ui-utils/api"; import { localStorageGet } from "egov-ui-kit/utils/localStorageUtils"; import { download, downloadBill } from "egov-common/ui-utils/commons"; +import { toggleSpinner, toggleSnackbar } from "egov-ui-framework/ui-redux/screen-configuration/actions"; import { updatesingleReading } from "./functions"; @@ -15,7 +16,7 @@ export const searchResults = { props: { columns: [ { labelName: "Consumer ID", labelKey: "Consumer ID" }, - + { labelName: "Usage Category", labelKey: "Usage Category" }, { labelName: "Last Reading", labelKey: "Last Reading" }, { labelName: "Current Reading Date", labelKey: "Current Reading Date" }, { @@ -24,9 +25,9 @@ export const searchResults = { 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]; + // Last Reading is at index 2, Status is at index 7 + const lastReading = tableMeta.rowData && tableMeta.rowData[2]; + const status = tableMeta.rowData && tableMeta.rowData[7]; const isEditable = ["Working", "Breakdown", "Locked"].includes(status); return ( { // 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]; + tableMeta.rowData && tableMeta.rowData[3]; // Current Reading Date at index 3 + const status = tableMeta.rowData && tableMeta.rowData[7]; const isEditable = ["Working", "Breakdown", "Locked"].includes(status); let minDate = ""; @@ -151,21 +152,22 @@ export const searchResults = { options: { filter: false, customBodyRender: (value, tableMeta, updateValue) => { - let readingDatenew = tableMeta.rowData && tableMeta.rowData[4] ? tableMeta.rowData[4] : null; + let readingDatenew = tableMeta.rowData && tableMeta.rowData[5] ? tableMeta.rowData[5] : null; readingDatenew = readingDatenew ? readingDatenew.split("-").reverse().join("/") : null; const handleUpdate = async () => { + debugger; 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 lastReading = Number(tableMeta.rowData && tableMeta.rowData[2]) || 0; + const currentReadingDate = tableMeta.rowData && tableMeta.rowData[3] ? getEpochForDate(tableMeta.rowData[3]) : null; const lastReadingDate = currentReadingDate; - const currentReadingRaw = Number(tableMeta.rowData && tableMeta.rowData[3]) || 0; + const currentReadingRaw = Number(tableMeta.rowData && tableMeta.rowData[4]) || 0; const currentReading = Number(currentReadingRaw) || 0; - const billingPeriod = readingDatenew ? `${tableMeta.rowData[2]} - ${readingDatenew}` : ""; + const billingPeriod = readingDatenew ? `${tableMeta.rowData[3]} - ${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]; + const status = statusFromSelect || (tableMeta.rowData && tableMeta.rowData[7]) || ""; + const tenantId = tableMeta.rowData && tableMeta.rowData[8]; if (!currentReadingRaw || !Number.isFinite(currentReading)) { alert("Please enter a numeric Current Reading greater than or equal to Last Reading before updating"); return; @@ -220,7 +222,7 @@ export const searchResults = { column: "Date Created", sortingFn: (data, i, sortDateOrder) => { const epochDates = data.reduce((acc, curr) => { - acc.push([...curr, getEpochForDate(curr[2], "dayend")]); + acc.push([...curr, getEpochForDate(curr[3], "dayend")]); return acc; }, []); const order = sortDateOrder === "asc" ? true : false; @@ -234,7 +236,7 @@ export const searchResults = { } }; export const updateAllReadings = async (state, dispatch) => { - + debugger; let allarray = []; // get table data from screen config @@ -256,7 +258,10 @@ export const updateAllReadings = async (state, dispatch) => { const isArrayRow = Array.isArray(row); const consumerId = isArrayRow ? row[0] : row["Consumer ID"]; - const lastReading = Number(isArrayRow ? row[1] : row["Last Reading"]) || 0; + const usageCategory = isArrayRow ? row[1] : row["Usage Category"]; + const lastReading = Number(isArrayRow ? row[2] : row["Last Reading"]) || 0; + const currentReadingDateDisplay = isArrayRow ? row[3] : row["Current Reading Date"]; + const lastReadingDate = getEpochForDate(currentReadingDateDisplay); // New reading / date: always take what user typed in the row inputs const currentReadingRawEl = readingInputs[i]; @@ -264,11 +269,9 @@ export const updateAllReadings = async (state, dispatch) => { 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 statusFromRow = isArrayRow ? row[7] : row["Status"]; const status = statusSelects[i] && statusSelects[i].value ? statusSelects[i].value : statusFromRow; - const tenantId = isArrayRow ? row[7] : row["TENANT_ID"]; + const tenantId = isArrayRow ? row[8] : row["TENANT_ID"]; // only allow bulk update for selected meter statuses const isEditableStatus = ["Working", "Breakdown", "Locked"].includes(status); @@ -307,37 +310,51 @@ export const updateAllReadings = async (state, dispatch) => { } // push only complete row into array - allarray.push({ - consumerId, - lastReading, - newReading: currentReadingRaw, - newReadingDate, - currentReadingDate: currentReadingDateDisplay, - lastReadingDate, - billingPeriod, - status, - tenantId, - readingDate - }); + const payload = { + meterReadingslist: [ + { + currentReadingDate: readingDate, + currentReading: currentReading, + billingPeriod: billingPeriod, + meterStatus: status, + connectionNo: consumerId, + lastReading: lastReading, + lastReadingDate: lastReadingDate, + tenantId: tenantId, + generateDemand: true + } + ] + }; + allarray.push(payload.meterReadingslist[0]); + //let meterReadingslist = allarray; + console.log("Prepared data for bulk update:", allarray); - // 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); - } } + try { + dispatch(toggleSpinner(true)); + const url = "/ws-calculator/meterConnection/_createmultiple"; + - return allarray; -}; \ No newline at end of file + const response = await httpRequest("post", url, "_update", [], { meterReadingslist: allarray }); + + dispatch(toggleSpinner(false)); + dispatch( + toggleSnackbar( + true, + { + labelName: "Bulk update successful", + labelKey: "ABG_BULK_UPDATE_SUCCESS" + }, + "success" + ) + ); + return response; + } catch (e) { + dispatch(toggleSpinner(false)); + console.error("API error:", e); + throw e; + } + console.log("Prepared data for bulk update:", allarray); + // return allarray; +} \ No newline at end of file From 380d0944f83018d137fb051a34db97ae0d47f31d Mon Sep 17 00:00:00 2001 From: anujkit Date: Thu, 30 Apr 2026 17:18:08 +0530 Subject: [PATCH 13/64] PI-21249 UI Enhancement: Optimize PDF Report Layout and Enable Grid Borders --- .../modules/employee/reports/reportResult.js | 55 ++++++++++++++----- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/web/rainmaker/packages/employee/src/modules/employee/reports/reportResult.js b/web/rainmaker/packages/employee/src/modules/employee/reports/reportResult.js index 9a1d7be5e6..aa87913512 100644 --- a/web/rainmaker/packages/employee/src/modules/employee/reports/reportResult.js +++ b/web/rainmaker/packages/employee/src/modules/employee/reports/reportResult.js @@ -88,9 +88,9 @@ class ShowField extends Component { const { tabLabel, metaData } = _this.props; const reportDetails = metaData.hasOwnProperty("reportDetails") ? metaData.reportDetails : {}; - const additionalConfig = reportDetails.hasOwnProperty("additionalConfig") && reportDetails.additionalConfig ? reportDetails.additionalConfig: {}; + const additionalConfig = reportDetails.hasOwnProperty("additionalConfig") && reportDetails.additionalConfig ? reportDetails.additionalConfig : {}; const reportHeader = reportDetails.hasOwnProperty("reportHeader") ? reportDetails.reportHeader : []; - const pageSize = (additionalConfig.print && additionalConfig.print.pdfPageSize)? additionalConfig.print.pdfPageSize: "LEGAL" + const pageSize = (additionalConfig.print && additionalConfig.print.pdfPageSize) ? additionalConfig.print.pdfPageSize : "LEGAL" let reportTitle = this.getReportTitle(); let xlsTitle = this.getXlsReportTitle(); let orientation = reportHeader.length > 6 ? "landscape" : "portrait"; @@ -108,10 +108,35 @@ class ShowField extends Component { orientation: orientation, pageSize: pageSize, footer: true, - customize: function(doc) { + customize: function (doc) { + // Title customization (your existing code) doc.content[0].text = []; - doc.content[0].text.push({ text: "mSeva System Reports\n\n", bold: true, fontSize: 20 }); + doc.content[0].text.push({ text: "mSeva Reports\n\n", bold: true, fontSize: 20 }); doc.content[0].text.push({ text: reportTitle, fontSize: 18 }); + + // 🔥 Apply borders to table + const table = doc.content.find(c => c.table); + + if (table) { + table.layout = { + hLineWidth: function () { + return 1; // horizontal border thickness + }, + vLineWidth: function () { + return 1; // vertical border thickness + }, + hLineColor: function () { + return '#000000'; // black borders + }, + vLineColor: function () { + return '#000000'; + }, + paddingLeft: function () { return 5; }, + paddingRight: function () { return 5; }, + paddingTop: function () { return 4; }, + paddingBottom: function () { return 4; } + }; + } }, className: "report-pdf-button", }, @@ -162,12 +187,12 @@ class ShowField extends Component { scrollY: 400, aLengthMenu: [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]], scrollX: true, - fnInitComplete: function() { + fnInitComplete: function () { this.css("visibility", "visible"); $(".dataTables_scrollBody thead tr").css({ visibility: "collapse" }); }, - drawCallback: function(settings) { + drawCallback: function (settings) { $(".dataTables_scrollBody thead tr").css({ visibility: "collapse" }); }, ...tableConfig, @@ -224,7 +249,7 @@ class ShowField extends Component { searchParams, } ).then( - function(response) { + function (response) { if (response.viewPath && response.reportData && response.reportData[0]) { localStorage.reportData = JSON.stringify(response.reportData); setReturnUrl(window.location.hash.split("#/")[1]); @@ -249,7 +274,7 @@ class ShowField extends Component { setFlag(1); } }, - function(err) { + function (err) { console.log(err); } ); @@ -422,7 +447,7 @@ class ShowField extends Component { let resulturl = getResultUrl(match.params.moduleName); var tenantId = getTenantId() ? getTenantId() : commonConfig.tenantId; - resulturl && + resulturl && commonApiPost( resulturl, {}, @@ -432,14 +457,14 @@ class ShowField extends Component { searchParams, } ).then( - function(response) { + function (response) { if (response.viewPath && response.reportData) { localStorage.reportData = JSON.stringify(response.reportData); setReturnUrl(window.location.hash.split("#/")[1]); setRoute("/print/report/" + response.viewPath); } }, - function(err) { + function (err) { console.log(err); } ); @@ -453,7 +478,7 @@ class ShowField extends Component { reportResult.reportHeader && reportResult.reportHeader.length && reportResult.reportHeader[i] && - (reportResult.reportHeader[i].type == "currency" ||reportResult.reportHeader[i].total) + (reportResult.reportHeader[i].type == "currency" || reportResult.reportHeader[i].total) ) { return { textAlign: "right" }; } else { @@ -561,7 +586,7 @@ class ShowField extends Component { sumColumn.unshift(firstColObj); } - var intVal = function(i) { + var intVal = function (i) { if (typeof i === "string") { let a = i.replace(/,/g, ""); a = a.replace(/[^-+0-9. ]/g, " ").split(" ")[0]; @@ -653,7 +678,7 @@ class ShowField extends Component { if (char.length == 1) { reportTitle = char + ""; reportHeaderName += char; - } else if(typeof char === "object") { + } else if (typeof char === "object") { reportTitle = char.text + ""; } else { reportTitle = " " + char; @@ -665,7 +690,7 @@ class ShowField extends Component { // return reportTitle; return [reportHeaderName]; }; - + render() { let { isTableShow, metaData, reportResult } = this.props; From a58e8375bcb510065483606d390775e7cabc6846 Mon Sep 17 00:00:00 2001 From: Hari-egov Date: Mon, 4 May 2026 12:00:40 +0530 Subject: [PATCH 14/64] mono_ui_uat_matomo config and build check --- .../packages/citizen/public/index.html | 199 ++++++++++++++++++ .../packages/employee/public/index.html | 199 ++++++++++++++++++ 2 files changed, 398 insertions(+) diff --git a/web/rainmaker/packages/citizen/public/index.html b/web/rainmaker/packages/citizen/public/index.html index 81cc9ea974..f0894967c3 100644 --- a/web/rainmaker/packages/citizen/public/index.html +++ b/web/rainmaker/packages/citizen/public/index.html @@ -43,6 +43,205 @@ To begin the development, run `npm start` or `yarn start`. To create a production bundle, use `npm run build` or `yarn build`. --> + + + diff --git a/web/rainmaker/packages/employee/public/index.html b/web/rainmaker/packages/employee/public/index.html index f1d7f30c64..641324d775 100644 --- a/web/rainmaker/packages/employee/public/index.html +++ b/web/rainmaker/packages/employee/public/index.html @@ -33,5 +33,204 @@ To begin the development, run `npm start` or `yarn start`. To create a production bundle, use `npm run build` or `yarn build`. --> + + + From 2181ad43b863cdffcaec8fee8b213096ecf63d59 Mon Sep 17 00:00:00 2001 From: erramesh000 Date: Mon, 4 May 2026 15:29:38 +0530 Subject: [PATCH 15/64] Updated new changes bulkmeter --- .../screens/specs/abg/gBmr/functions.js | 3 +- .../screens/specs/abg/gBmr/searchResults.js | 192 ++++++++++-------- 2 files changed, 112 insertions(+), 83 deletions(-) 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 index 0a2b72ae53..de5169acfc 100644 --- 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 @@ -18,7 +18,7 @@ import { loadUlbLogo } from "../../utils/receiptTransformer"; // const tenantId = getTenantId(); const tenantId = getTenantId(); -export const updatesingleReading = async (consumerId, lastReading, currentReadingRaw, currentReading, billingPeriod, status, readingDate, lastReadingDate, tenantId, dispatch) => { +export const updatesingleReading = async (state, dispatch, consumerId, lastReading, currentReadingRaw, currentReading, billingPeriod, status, readingDate, lastReadingDate, tenantId) => { const payload = { meterReadingslist: [ @@ -207,7 +207,6 @@ export const searchApiCall = async (state, dispatch) => { convertEpochToDate(item.currentReadingDate) || "-", ["Billing Period"]: item.billingPeriod || "-", ["Status"]: item.meterStatus || "-", - ["TENANT_ID"]: item.tenantId })); dispatch( 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 index 0b436e81c5..707e0cfb01 100644 --- 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 @@ -19,20 +19,59 @@ export const searchResults = { { labelName: "Usage Category", labelKey: "Usage Category" }, { labelName: "Last Reading", labelKey: "Last Reading" }, { labelName: "Current Reading Date", labelKey: "Current Reading Date" }, + { + 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: "New Reading(in KL)", labelKey: "New Reading(in KL)", options: { filter: false, customBodyRender: (value, tableMeta, updateValue) => { - // Last Reading is at index 2, Status is at index 7 + // Last Reading is at index 2, Status is at index 4 const lastReading = tableMeta.rowData && tableMeta.rowData[2]; - const status = tableMeta.rowData && tableMeta.rowData[7]; - const isEditable = ["Working", "Breakdown", "Locked"].includes(status); + const status = tableMeta.rowData && tableMeta.rowData[4]; + const isEditable = ["Working", "Breakdown", "Locked", "Reset", "Replacement"].includes(status); + const isReset = status === "Reset" || status === "Replacement"; return ( 10000) { + e.target.value = ""; + updateValue(""); + alert("Please enter a numeric value less than or equal to 10000"); + return; + } + if (!isReset) { + const min = Number(lastReading || 0); + if (numeric < min) { + e.target.value = ""; + updateValue(""); + alert("Please enter a numeric value greater than or equal to Last Reading"); + return; + } + } + updateValue(v); }} /> ); @@ -69,8 +121,8 @@ export const searchResults = { // Disable dates earlier than Current Reading Date for that row const currentReadingDateDisplay = tableMeta.rowData && tableMeta.rowData[3]; // Current Reading Date at index 3 - const status = tableMeta.rowData && tableMeta.rowData[7]; - const isEditable = ["Working", "Breakdown", "Locked"].includes(status); + const status = tableMeta.rowData && tableMeta.rowData[4]; + const isEditable = ["Working", "Breakdown", "Locked", "Reset", "Replacement"].includes(status); let minDate = ""; if ( @@ -100,45 +152,7 @@ export const searchResults = { } } }, - { 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", @@ -152,32 +166,40 @@ export const searchResults = { options: { filter: false, customBodyRender: (value, tableMeta, updateValue) => { - let readingDatenew = tableMeta.rowData && tableMeta.rowData[5] ? tableMeta.rowData[5] : null; + let readingDatenew = tableMeta.rowData && tableMeta.rowData[5] ? tableMeta.rowData[6] : null; readingDatenew = readingDatenew ? readingDatenew.split("-").reverse().join("/") : null; const handleUpdate = async () => { - debugger; + const consumerId = tableMeta.rowData && tableMeta.rowData[0]; - const lastReading = Number(tableMeta.rowData && tableMeta.rowData[2]) || 0; + const status = statusFromSelect || (tableMeta.rowData && tableMeta.rowData[4]) || ""; + const lastReading = status == "Replacement" ? 0 : Number(tableMeta.rowData && tableMeta.rowData[2]) || 0; const currentReadingDate = tableMeta.rowData && tableMeta.rowData[3] ? getEpochForDate(tableMeta.rowData[3]) : null; const lastReadingDate = currentReadingDate; - const currentReadingRaw = Number(tableMeta.rowData && tableMeta.rowData[4]) || 0; - const currentReading = Number(currentReadingRaw) || 0; + const currentReadingRaw = Number(tableMeta.rowData && tableMeta.rowData[5]) || 0; + let currentReading = Number(currentReadingRaw) || 0; const billingPeriod = readingDatenew ? `${tableMeta.rowData[3]} - ${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[7]) || ""; + const tenantId = tableMeta.rowData && tableMeta.rowData[8]; if (!currentReadingRaw || !Number.isFinite(currentReading)) { - alert("Please enter a numeric Current Reading greater than or equal to Last Reading before updating"); + alert("Please enter a numeric Current Reading before updating"); + return; + } + + if (currentReading > 10000) { + alert("Please enter a numeric Current Reading less than or equal to 10000 before updating"); return; } - if (currentReading < lastReading) { + if (status !== "Reset" && currentReading < lastReading) { alert("Please enter a numeric Current Reading greater than or equal to Last Reading before updating"); return; } + currentReading = status === "Reset" ? (10000 + currentReading - lastReading) : currentReading; + // 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"); @@ -236,10 +258,9 @@ export const searchResults = { } }; export const updateAllReadings = async (state, dispatch) => { - debugger; + let allarray = []; - // get table data from screen config const rows = get( state, "screenConfiguration.screenConfig.bulkmeterreading.components.div.children.searchResults.props.data", @@ -274,7 +295,7 @@ export const updateAllReadings = async (state, dispatch) => { const tenantId = isArrayRow ? row[8] : row["TENANT_ID"]; // only allow bulk update for selected meter statuses - const isEditableStatus = ["Working", "Breakdown", "Locked"].includes(status); + const isEditableStatus = ["Working", "Breakdown", "Locked", "Reset", "Replacement"].includes(status); if (!isEditableStatus) { continue; } @@ -284,13 +305,25 @@ export const updateAllReadings = async (state, dispatch) => { continue; } - const currentReading = Number(currentReadingRaw) || 0; + let currentReading = Number(currentReadingRaw) || 0; + + // Validate input range + if (!Number.isFinite(currentReading) || currentReading > 10000) { + skippedRows++; + continue; + } + - // skip invalid readings - if (!Number.isFinite(currentReading) || currentReading < lastReading) { + if (status !== "Reset" && status !== "Replacement" && currentReading < lastReading) { + skippedRows++; continue; } + // Calculate actual reading for Reset status + if (status === "Reset") { + currentReading = 10000 + currentReading - lastReading; + } + const readingDatenew = newReadingDate ? newReadingDate.split("-").reverse().join("/") : null; @@ -326,8 +359,6 @@ export const updateAllReadings = async (state, dispatch) => { ] }; allarray.push(payload.meterReadingslist[0]); - //let meterReadingslist = allarray; - console.log("Prepared data for bulk update:", allarray); } @@ -337,24 +368,23 @@ export const updateAllReadings = async (state, dispatch) => { const response = await httpRequest("post", url, "_update", [], { meterReadingslist: allarray }); - - dispatch(toggleSpinner(false)); - dispatch( - toggleSnackbar( - true, - { - labelName: "Bulk update successful", - labelKey: "ABG_BULK_UPDATE_SUCCESS" - }, - "success" - ) - ); + if (response && response.meterReadingslist && response.meterReadingslist.length > 0) { + dispatch(toggleSpinner(false)); + dispatch( + toggleSnackbar( + true, + { + labelName: "Bulk update successful", + labelKey: "ABG_BULK_UPDATE_SUCCESS" + }, + "success" + ) + ); + } return response; } catch (e) { dispatch(toggleSpinner(false)); console.error("API error:", e); throw e; } - console.log("Prepared data for bulk update:", allarray); - // return allarray; -} \ No newline at end of file +} From ef9b0eed2e31fa9e22d5f607d331b2e30fdef92e Mon Sep 17 00:00:00 2001 From: anujkit Date: Sun, 10 May 2026 17:07:10 +0530 Subject: [PATCH 16/64] batach and group bill --- .../billdownloadfunction.js | 93 +++++++++++++++---- 1 file changed, 77 insertions(+), 16 deletions(-) diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/groupBillDownloadResource/billdownloadfunction.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/groupBillDownloadResource/billdownloadfunction.js index 9ba7b3d703..77035df697 100644 --- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/groupBillDownloadResource/billdownloadfunction.js +++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/abg/groupBillDownloadResource/billdownloadfunction.js @@ -35,9 +35,9 @@ export var searchApiCall = function (state, dispatch, limit, offset) { ); return; } - + var params = [{ key: "tenantId", value: tenantId }]; - + return httpRequest( "post", "/pdf-service/v1/_getBulkPdfRecordsDetails", @@ -70,17 +70,79 @@ export var searchApiCall = function (state, dispatch, limit, offset) { //make table data - let tableData = filteredBillData.map(item => ({ - ["ABG_JOB_ID"]: item.jobid || "-", - ["ABG_TENANT_ID"]: item.tenantId || "-", - ["ABG_FILESTORE_ID"]: item.filestoreid || "-", - ["ABG_TOTAL_RECORDS"]: item.totalrecords || "-", - ["ABG_RECORDS_COMPLETED"]:item.recordscompleted || "-", - ["ABG_LOCALITY_NAME"]: generateLocalityKey(state, item.locality)|| "-", - ["ABG_BUSINESS_SERVICE"]: item.bussinessService|| "-", - })); - - + const tableData = (filteredBillData || []).map(function (item) { + + var localityNames = "-"; + + if (item && item.locality) { + + var localityArray = []; + + // Case 1: {"SC1","SC2"} + if (item.locality.indexOf("{") !== -1) { + localityArray = item.locality + .replace(/[{}"]/g, "") + .split(",") + .filter(function (value) { + return value && value.trim(); + }); + } + // Case 2: SC1 + else { + localityArray = [item.locality]; + } + + localityNames = localityArray + .map(function (code) { + return generateLocalityKey(state, code.trim()); + }) + .filter(function (name) { + return name; + }) + .join(", "); + + if (!localityNames) { + localityNames = "-"; + } + } + + return { + ABG_JOB_ID: + item && item.jobid + ? item.jobid + : "-", + + ABG_TENANT_ID: + item && item.tenantId + ? item.tenantId + : "-", + + ABG_FILESTORE_ID: + item && item.filestoreid + ? item.filestoreid + : "-", + + ABG_TOTAL_RECORDS: + item && item.totalrecords + ? item.totalrecords + : "-", + + ABG_RECORDS_COMPLETED: + item && item.recordscompleted + ? item.recordscompleted + : "-", + + ABG_LOCALITY_NAME: + localityNames, + + ABG_BUSINESS_SERVICE: + item && item.bussinessService + ? item.bussinessService + : "-", + }; + }); + + dispatch( handleField( "groupBillDownloads", @@ -136,14 +198,13 @@ export var searchApiCall = function (state, dispatch, limit, offset) { ); }); }; -const generateLocalityKey=(state,localityCode) =>{ - debugger +const generateLocalityKey = (state, localityCode) => { const localitiesData = get( state, "screenConfiguration.preparedFinalObject.localitiesData", {} ); - let localityName = localitiesData.find((item=> item.code === localityCode)); + let localityName = localitiesData.find((item => item.code === localityCode)); return localityName.name; } const showHideTable = (booleanHideOrShow, dispatch) => { From f69b774f71ddce65a6fa530917746f2e2b9187d5 Mon Sep 17 00:00:00 2001 From: anujkit Date: Fri, 8 May 2026 12:48:36 +0530 Subject: [PATCH 17/64] PI-21299 21249 --- .../ui-config/screens/specs/utils/index.js | 63 +++-- .../screens/specs/utils/receiptPdf.js | 244 ++++++++++-------- 2 files changed, 174 insertions(+), 133 deletions(-) diff --git a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/utils/index.js b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/utils/index.js index ea780227b4..419afaa032 100644 --- a/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/utils/index.js +++ b/web/rainmaker/dev-packages/egov-abg-dev/src/ui-config/screens/specs/utils/index.js @@ -14,7 +14,7 @@ import { } from "egov-ui-framework/ui-config/screens/specs/utils"; import { httpRequest } from "../../../../ui-utils"; import { prepareFinalObject } from "egov-ui-framework/ui-redux/screen-configuration/actions"; -import { set } from "lodash"; +import { set, values } from "lodash"; import { downloadReceiptFromFilestoreID } from "egov-common/ui-utils/commons"; import commonConfig from "config/common.js"; @@ -629,30 +629,51 @@ export const checkValueForNA = (value) => { return value == null || value == undefined || value == "" ? "NA" : value; }; -export const batchMergeAndDownload = async (billkey, locality, businesService, tenantId, isConsolidated = false)=>{ +export const batchMergeAndDownload = async ( + billkey, + batchType, + searchCriteria, + isConsolidated = false +) => { - const DOWNLOADRECEIPT = { - GET: { - URL: "egov-pdf/download/WNS/wnsgroupbill", - ACTION: "", - }, - }; - - const queryStr = [ - { key: "key", value: billkey }, - { key: "tenantId", value: tenantId }, - {key : "locality", value : locality}, - {key : "isConsolidated", value : isConsolidated}, - {key : "bussinessService", value : businesService} - ]; + const DOWNLOADRECEIPT = { + GET: { + URL: "egov-pdf/download/WNS/wnsgroupbill", + ACTION: "", + }, + }; - const egovPdfResponse = await httpRequest( + const queryStr = [ + { key: "key", value: billkey }, + { key: "batchType", value: batchType }, + { key: "isConsolidated", value: isConsolidated } + ]; + + // ✅ Append searchCriteria dynamically + if (searchCriteria) { + Object.keys(searchCriteria).forEach((key) => { + const value = searchCriteria[key]; + + // 🔹 Handle array (multiple locality case) + if (Array.isArray(value)) { + value.forEach((item) => { + queryStr.push({ key, value: item }); + }); + } + + // 🔹 Handle normal values (group / locality string / tenantId etc.) + else if (value !== undefined && value !== null && value !== "") { + queryStr.push({ key, value }); + } + }); + } + + const egovPdfResponse = await httpRequest( "post", DOWNLOADRECEIPT.GET.URL, DOWNLOADRECEIPT.GET.ACTION, - queryStr, - + queryStr ); - return egovPdfResponse -} + return egovPdfResponse; +}; \ No newline at end of file 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 d212afa99a..27d13bdb9b 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 @@ -166,122 +166,142 @@ const getMutlipleBillsData = transformedDataArray => { return finalMultipleBillData; }; //generateMutlipleBills PDF -export const generateMultipleBill = async (state, dispatch, type) => { - debugger - dispatch(toggleSpinner()); - let allBills = get( - state.screenConfiguration, - "preparedFinalObject.searchScreenMdmsData.billSearchResponse", - [] - ); - let integratedBills = get(state.screenConfiguration, - "preparedFinalObject.searchScreenMdmsData.intergratedBills", - [] - ) +export const generateMultipleBill = async function (state, dispatch, type) { + try { + dispatch(toggleSpinner()); + + var preparedData = get(state, "screenConfiguration.preparedFinalObject", {}); + + var allBills = get(preparedData, "searchScreenMdmsData.billSearchResponse", []); + var integratedBills = get(preparedData, "searchScreenMdmsData.intergratedBills", []); + var commonPayDetails = get(preparedData, "searchScreenMdmsData.common-masters.uiCommonPay", []); + var searchCriteria = get(preparedData, "searchCriteria"); + var businessService = get(preparedData, "searchCriteria.businesService", ""); + var locality = get(preparedData, "searchCriteria.locality", ""); + var tenantId = get(preparedData, "searchCriteria.tenantId", ""); + var batchType = get(preparedData, "generateBillScreen.batchtype", ""); + var group = get(preparedData, "searchCriteria.group", ""); + + // ---------------------------- + // Get Bill Key + // ---------------------------- + function getBillKey() { + if (batchType === "Integrated Bill") { + return "wsn-integrated"; + } - const commonPayDetails = get( - state.screenConfiguration, - "preparedFinalObject.searchScreenMdmsData.common-masters.uiCommonPay", - [] - ); - const businessService = get( - state.screenConfiguration, - "preparedFinalObject.searchCriteria.businesService", - '' - ); - const locality = get( - state.screenConfiguration, - "preparedFinalObject.searchCriteria.locality", - '' - ); - const tenantId = get( - state.screenConfiguration, - "preparedFinalObject.searchCriteria.tenantId", - '' - ); - let batchtype = get( - state.screenConfiguration, - "preparedFinalObject.generateBillScreen.batchtype", - '' - ); - let billkey = '' - const index = commonPayDetails && commonPayDetails.findIndex((item) => { - return item.code == businessService; - }); - if(batchtype === "Integrated Bill"){ - billkey = 'wsn-integrated' - }else{ - if (index > -1) { - billkey = get(commonPayDetails[index], 'billKey', ''); + var match = null; + if (commonPayDetails && commonPayDetails.length) { + for (var i = 0; i < commonPayDetails.length; i++) { + if (commonPayDetails[i].code === businessService) { + match = commonPayDetails[i]; + break; + } + } + } + + if (match) { + return get(match, "billKey", ""); + } + + // fallback DEFAULT + if (commonPayDetails && commonPayDetails.length) { + for (var j = 0; j < commonPayDetails.length; j++) { + if (commonPayDetails[j].code === "DEFAULT") { + return get(commonPayDetails[j], "billKey", ""); + } + } + } + + return ""; + } + + var billKey = getBillKey(); + + // ---------------------------- + // Filter Bills + // ---------------------------- + function filterBills(bills) { + if (!bills || !bills.length) return []; + + var result = []; + + for (var i = 0; i < bills.length; i++) { + var bill = bills[i]; + + if (batchType === "Integrated Bill") { + if ( + bill && + bill.connection && + bill.connection.propertyTotalAmount > 0 + ) { + result.push(bill); + } + } else { + if ( + bill && + bill.status === "ACTIVE" && + bill.totalAmount > 0 && + bill.connection && + bill.connection.status === "Active" + ) { + result.push(bill); + } + } + } + + return result; + } + + var filteredBills = filterBills(allBills); + + // ---------------------------- + // Locality Batch Processing + // ---------------------------- + var isValidLocalityOrGroup = + (batchType === "Locality" && + typeof locality === "string" && + locality.trim() !== "") || + (batchType === "Group" && + typeof group === "string" && + group.trim() !== "") || + Array.isArray(locality) && locality.length > 0 + + if (isValidLocalityOrGroup) { + try { + var response = await batchMergeAndDownload( + billKey, + batchType, + searchCriteria + ); + + var message = response.message + " Job ID: " + response.jobId; + + dispatch( + toggleSnackbar(true, { labelName: message, labelKey: message }, "warning") + ); + } catch (error) { + console.error("Batch download error:", error); + + dispatch( + toggleSnackbar( + true, + { labelName: "Batch processing failed", labelKey: "Batch processing failed" }, + "error" + ) + ); + } } else { - const details = commonPayDetails && commonPayDetails.filter(item => item.code === "DEFAULT"); - billkey = get(details, 'billKey', ''); + if (filteredBills && filteredBills.length > 0) { + await downloadMultipleBill(filteredBills, billKey, businessService); + } } + + } catch (error) { + console.error("generateMultipleBill error:", error); + } finally { + dispatch(toggleSpinner()); } - 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.length > 0 && await downloadMultipleBill(allBills, billkey, businessService); - } - /* -To Download Files based on Filestoreid logic - -let filestoreids=[]; -let bills=[]; -allBills.map(bill=>{ - if(bill.status==='ACTIVE'){ - if(bill.fileStoreId==null){ - bills.push(bill); - }else{ - filestoreids.push(bill.fileStoreId) - } - } -}) -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 From 636b9bc68a55ea646db487a2b8130acc49a4fc6d Mon Sep 17 00:00:00 2001 From: erramesh000 Date: Tue, 12 May 2026 17:02:50 +0530 Subject: [PATCH 18/64] Update single reading reset and replacement --- .../wns/meterReading/meterReadingEditable.js | 101 ++++++++++++------ 1 file changed, 70 insertions(+), 31 deletions(-) diff --git a/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/screens/specs/wns/meterReading/meterReadingEditable.js b/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/screens/specs/wns/meterReading/meterReadingEditable.js index 428a031d49..19b7917462 100644 --- a/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/screens/specs/wns/meterReading/meterReadingEditable.js +++ b/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/screens/specs/wns/meterReading/meterReadingEditable.js @@ -21,16 +21,20 @@ import { } from "egov-ui-framework/ui-utils/commons"; function parseDDMMYYYY(dateStr) { - if (!dateStr) return new Date('Invalid Date'); - const parts = dateStr.includes('/') ? dateStr.split('/') : dateStr.split('-'); - if (parts.length !== 3) return new Date('Invalid Date'); - return new Date(Number(parts[2]), Number(parts[1]) - 1, Number(parts[0])); + if (!dateStr) return new Date('Invalid Date'); + const parts = dateStr.includes('/') ? dateStr.split('/') : dateStr.split('-'); + if (parts.length !== 3) return new Date('Invalid Date'); + return new Date(Number(parts[2]), Number(parts[1]) - 1, Number(parts[0])); } const saveData = async (state, dispatch) => { const mode = get(state, "screenConfiguration.preparedFinalObject.autoPopulatedValues.mode"); let data = get(state, "screenConfiguration.preparedFinalObject.metereading"); - + let lastReading = get(state, "screenConfiguration.preparedFinalObject.autoPopulatedValues.lastReading"); + let currentReading = Number(data.currentReading); + data.currentReading = data.meterStatus === "Reset" ? (10000 + currentReading - lastReading) : data.currentReading; + lastReading = data.meterStatus === "Replacement" ? 0 : lastReading; + if (!data || data.length === 0) { dispatch( toggleSnackbar( @@ -46,19 +50,19 @@ const saveData = async (state, dispatch) => { } data.billingPeriod = get(state, "screenConfiguration.preparedFinalObject.autoPopulatedValues.billingPeriod"); - + // Validation for Billing Period if (data.billingPeriod) { if (!data.currentReadingDate) { data.currentReadingDate = new Date().getTime(); } - + const separator = data.billingPeriod.includes(' - ') ? ' - ' : '-'; const fromDateStr = data.billingPeriod.split(separator)[0].trim(); const fromDate = parseDDMMYYYY(fromDateStr); const selectedDate = new Date(new Date(data.currentReadingDate).toDateString()); const toDate = new Date(new Date().toDateString()); - + if (!(selectedDate >= fromDate && selectedDate <= toDate)) { dispatch( toggleSnackbar( @@ -72,10 +76,10 @@ const saveData = async (state, dispatch) => { ); return; } - - const endDate = ("0" + selectedDate.getDate()).slice(-2) + '/' + - ("0" + (selectedDate.getMonth() + 1)).slice(-2) + '/' + - selectedDate.getFullYear(); + + const endDate = ("0" + selectedDate.getDate()).slice(-2) + '/' + + ("0" + (selectedDate.getMonth() + 1)).slice(-2) + '/' + + selectedDate.getFullYear(); data.billingPeriod = fromDateStr + separator + endDate; } @@ -83,11 +87,12 @@ const saveData = async (state, dispatch) => { data.meterStatus = get(state, "screenConfiguration.preparedFinalObject.meterMdmsData.['ws-services-calculation'].MeterStatus[0].code"); } data.connectionNo = getQueryArg(window.location.href, "connectionNos") - data.lastReading = get(state, "screenConfiguration.preparedFinalObject.autoPopulatedValues.lastReading"); + // data.lastReading = get(state, "screenConfiguration.preparedFinalObject.autoPopulatedValues.lastReading"); + data.lastReading = lastReading // Set last reading date and ID based on mode (add vs edit) if (mode === 'edit') { - + data.lastReadingDate = get(state, "screenConfiguration.preparedFinalObject.consumptionDetails[0].lastReadingDate"); } else { const lastReadingDate = get(state, "screenConfiguration.preparedFinalObject.consumptionDetails[0].currentReadingDate"); @@ -97,7 +102,7 @@ const saveData = async (state, dispatch) => { data.lastReadingDate = new Date().setMonth(new Date().getMonth() - 1); } } - + if (data.meterStatus === 'Working') { validateFields( "components.div.children.meterReadingEditable.children.card.children.cardContent.children.fourthContainer.children", @@ -111,7 +116,7 @@ const saveData = async (state, dispatch) => { dispatch, "meter-reading" ); - } + } else if (data.meterStatus === 'Locked' || data.meterStatus === 'Breakdown') { validateFields( "components.div.children.meterReadingEditable.children.card.children.cardContent.children.fourthContainer.children", @@ -126,10 +131,44 @@ const saveData = async (state, dispatch) => { "meter-reading" ); data.currentReading = data.lastReading; - if (data.currentReading === null || data.currentReading === undefined || data.currentReading === '') { - return; + if (data.currentReading === null || data.currentReading === undefined || data.currentReading === '') { + return; + } + } + + else if (data.meterStatus === 'Reset' || data.meterStatus === 'Replacement' || data.meterStatus === 'No-meter') { + // For these statuses, consumption field is hidden. Validate currentReading and date fields instead. + validateFields( + "components.div.children.meterReadingEditable.children.card.children.cardContent.children.fourthContainer.children", + state, + dispatch, + "meter-reading" + ); + validateFields( + "components.div.children.meterReadingEditable.children.card.children.cardContent.children.fifthContainer.children", + state, + dispatch, + "meter-reading" + ); + + // Ensure currentReading is present (for Reset/Replacement user should enter currentReading) + if (data.currentReading === null || data.currentReading === undefined || data.currentReading === "") { + return; + } + + // If date not provided, set to today + if (!data.currentReadingDate) { + data.currentReadingDate = new Date().getTime(); + } + + // Apply Reset calculation if needed + if (data.meterStatus === 'Reset') { + const curr = Number(data.currentReading) || 0; + data.currentReading = 10000 + curr - lastReading; + } + + // Replacement: ensure lastReading considered 0 (already handled above) } - } else { const consumption = validateFields( "components.div.children.meterReadingEditable.children.card.children.cardContent.children.sixthContainer.children", @@ -140,21 +179,21 @@ const saveData = async (state, dispatch) => { if (!data.consumption) { return; } - const previousreading = get(state, "screenConfiguration.preparedFinalObject.autoPopulatedValues.lastReading"); - data.currentReading = parseFloat(data.consumption) + previousreading; + const previousreading = lastReading; + // data.currentReading = parseFloat(data.consumption) + previousreading; data.currentReadingDate = new Date().getTime(); } - + set(data, "currentReadingDate", convertDateToEpoch(data.currentReadingDate, "dayend")); data.currentReading = parseFloat(data.currentReading); - + if (data.consumption) { delete data.consumption; } - + data.tenantId = getQueryArg(window.location.href, "tenantId"); data.generateDemand = true; - + createMeterReading(dispatch, data, mode); } @@ -428,14 +467,14 @@ export const meterReadingEditable = "" ) ); - } - else if (status == 'Reset' || status == 'Replacement' || status == 'No-meter' ) { + } + else if (status == 'Reset' || status == 'Replacement' || status == 'No-meter') { dispatch( handleField( "meter-reading", "components.div.children.meterReadingEditable.children.card.children.cardContent.children.fourthContainer.children.currentReading.props", "disabled", - true + false ) ); dispatch( @@ -443,7 +482,7 @@ export const meterReadingEditable = "meter-reading", "components.div.children.meterReadingEditable.children.card.children.cardContent.children.fifthContainer.children.currentReadingDate.props", "disabled", - true + false ) ); dispatch( @@ -459,7 +498,7 @@ export const meterReadingEditable = "meter-reading", "components.div.children.meterReadingEditable.children.card.children.cardContent.children.sixthContainer.children.thirdCont", "visible", - true + false ) ); dispatch( @@ -467,7 +506,7 @@ export const meterReadingEditable = "meter-reading", "components.div.children.meterReadingEditable.children.card.children.cardContent.children.sixthContainer.children.thirdCont", "visible", - true + false ) ); dispatch( From edcf3f2461cdd323c5909d28556c80e86a5338a2 Mon Sep 17 00:00:00 2001 From: erramesh000 Date: Tue, 12 May 2026 17:22:58 +0530 Subject: [PATCH 19/64] Fixed issues Reset and replacement functionality --- .../screens/specs/abg/gBmr/functions.js | 40 +++--- .../screens/specs/abg/gBmr/groupBillSearch.js | 46 +++++- .../screens/specs/abg/gBmr/searchResults.js | 135 +++++++++++++++--- 3 files changed, 173 insertions(+), 48 deletions(-) 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 index de5169acfc..627d0efec7 100644 --- 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 @@ -18,7 +18,7 @@ import { loadUlbLogo } from "../../utils/receiptTransformer"; // const tenantId = getTenantId(); const tenantId = getTenantId(); -export const updatesingleReading = async (state, dispatch, consumerId, lastReading, currentReadingRaw, currentReading, billingPeriod, status, readingDate, lastReadingDate, tenantId) => { +export const updatesingleReading = async (consumerId, lastReading, currentReadingRaw, currentReading, billingPeriod, status, readingDate, lastReadingDate, tenantId, state = null, dispatch = null) => { const payload = { meterReadingslist: [ @@ -34,8 +34,6 @@ export const updatesingleReading = async (state, dispatch, consumerId, lastReadi generateDemand: true } ] - - }; try { if (dispatch) { @@ -43,22 +41,23 @@ export const updatesingleReading = async (state, dispatch, consumerId, lastReadi } const url = "/ws-calculator/meterConnection/_createmultiple"; - const response = await httpRequest("post", url, "_update", [], payload); if (dispatch) { dispatch(toggleSpinner(false)); } - dispatch( - toggleSnackbar( - true, - { - labelName: "Bulk update successful", - labelKey: "ABG_BULK_UPDATE_SUCCESS" - }, - "success" - ) - ); + if (dispatch) { + dispatch( + toggleSnackbar( + true, + { + labelName: "Bulk update successful", + labelKey: "ABG_BULK_UPDATE_SUCCESS" + }, + "success" + ) + ); + } return response; } catch (e) { if (dispatch) { @@ -103,7 +102,8 @@ export const searchApiCall = async (state, dispatch) => { "warning" ) ); - } else if ( + } + else if ( Object.keys(searchScreenObject).length == 0 || Object.values(searchScreenObject).every(x => x === "") ) { @@ -117,7 +117,9 @@ export const searchApiCall = async (state, dispatch) => { "warning" ) ); - } else { + } + + else { for (var key in searchScreenObject) { if ( searchScreenObject.hasOwnProperty(key) && @@ -138,7 +140,7 @@ export const searchApiCall = async (state, dispatch) => { try { dispatch(toggleSpinner(true)); const requestBody = { - tenantId: searchScreenObject.tenantId || tenantId, + tenantId: getTenantId() || tenantId, locality: searchScreenObject.locality || "", offset: searchScreenObject.offset !== undefined ? searchScreenObject.offset : 0 }; @@ -203,10 +205,10 @@ export const searchApiCall = async (state, dispatch) => { ["New Reading Date"]: "", // existing reading date from system - ["Current Reading Date"]: + ["Last Reading Date"]: convertEpochToDate(item.currentReadingDate) || "-", ["Billing Period"]: item.billingPeriod || "-", - ["Status"]: item.meterStatus || "-", + ["Meter Status"]: item.meterStatus || "-", ["TENANT_ID"]: item.tenantId })); dispatch( 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 index a8bc0a1ca8..f16162f8f5 100644 --- 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 @@ -99,18 +99,52 @@ export const abgSearchCard = getCommonCard({ labelName: "Select ULB", labelKey: "ABG_ULB_PLACEHOLDER" }, - required: true, + required: false, value: tenantId, - disabled: true, - isClearable: true, - labelsFromLocalisation: true, + isDisabled: getTenantId() === "pb.punjab" ? false : true, + readOnly: getTenantId() === "pb.punjab" ? false : true, + isClearable: false, + labelsFromLocalisation: getTenantId() === "pb.punjab" ? false : true, className: "autocomplete-dropdown", jsonPath: "searchCriteria.tenantId", sourceJsonPath: "searchScreenMdmsData.tenant.tenants", + }, - required: true, + 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: false, jsonPath: "searchCriteria.tenantId", - disabled: false, + disabled: true, gridDefination: { xs: 12, sm: 4 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 index 707e0cfb01..48cadb8f14 100644 --- 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 @@ -18,21 +18,19 @@ export const searchResults = { { labelName: "Consumer ID", labelKey: "Consumer ID" }, { labelName: "Usage Category", labelKey: "Usage Category" }, { labelName: "Last Reading", labelKey: "Last Reading" }, - { labelName: "Current Reading Date", labelKey: "Current Reading Date" }, + { labelName: "Last Reading Date", labelKey: "Last Reading Date" }, { - labelName: "Status", - labelKey: "Status", + labelName: "Meter Status", + labelKey: "Meter Status", options: { filter: false, customBodyRender: (value, tableMeta, updateValue) => { const statusOptions = [ "Working", "Locked", - "No-meter", "Breakdown", "No_Meter", "Reset", - "NULL", "Replacement" ]; const currentStatus = value || ""; @@ -65,7 +63,7 @@ export const searchResults = { // Last Reading is at index 2, Status is at index 4 const lastReading = tableMeta.rowData && tableMeta.rowData[2]; const status = tableMeta.rowData && tableMeta.rowData[4]; - const isEditable = ["Working", "Breakdown", "Locked", "Reset", "Replacement"].includes(status); + const isEditable = ["Working", "Reset", "Replacement"].includes(status); const isReset = status === "Reset" || status === "Replacement"; return ( { - // Disable dates earlier than Current Reading Date for that row + // Disable dates earlier than Last Reading Date for that row const currentReadingDateDisplay = - tableMeta.rowData && tableMeta.rowData[3]; // Current Reading Date at index 3 + tableMeta.rowData && tableMeta.rowData[3]; // Last Reading Date at index 3 const status = tableMeta.rowData && tableMeta.rowData[4]; - const isEditable = ["Working", "Breakdown", "Locked", "Reset", "Replacement"].includes(status); + const isEditable = ["Working", "Reset", "Replacement", "Locked", "No_Meter", "Breakdown"].includes(status); let minDate = ""; if ( @@ -141,12 +139,29 @@ export const searchResults = { min={minDate || undefined} className="bulk-new-reading-date" style={{ width: "160px", padding: "6px", boxSizing: "border-box" }} - disabled={!isEditable} + // disabled={!isEditable} // defaultValue={value || today} onChange={e => { - if (!isEditable) return; + // if (!isEditable) return; updateValue(e.target.value); }} + onBlur={e => { + const dateValue = e.target.value; + + // Validate date is not empty + if (!dateValue) { + alert("Please enter a New Reading Date"); + return; + } + + // Validate date is not earlier than Last Reading Date + if (minDate && dateValue < minDate) { + alert("New Reading Date cannot be earlier than Last Reading Date"); + e.target.value = ""; + updateValue(""); + return; + } + }} /> ); } @@ -166,10 +181,13 @@ export const searchResults = { options: { filter: false, customBodyRender: (value, tableMeta, updateValue) => { - let readingDatenew = tableMeta.rowData && tableMeta.rowData[5] ? tableMeta.rowData[6] : null; + let readingDatenew = tableMeta.rowData[6]; readingDatenew = readingDatenew ? readingDatenew.split("-").reverse().join("/") : null; const handleUpdate = async () => { + const statusSelects = document.querySelectorAll("select.bulk-status-select"); + const statusFromSelect = statusSelects[tableMeta.rowIndex] && statusSelects[tableMeta.rowIndex].value; + const consumerId = tableMeta.rowData && tableMeta.rowData[0]; const status = statusFromSelect || (tableMeta.rowData && tableMeta.rowData[4]) || ""; const lastReading = status == "Replacement" ? 0 : Number(tableMeta.rowData && tableMeta.rowData[2]) || 0; @@ -179,15 +197,31 @@ export const searchResults = { let currentReading = Number(currentReadingRaw) || 0; const billingPeriod = readingDatenew ? `${tableMeta.rowData[3]} - ${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 tenantId = tableMeta.rowData && tableMeta.rowData[8]; + + // If status is Locked, No_Meter, or Breakdown, automatically set currentReading to lastReading + if (["Locked", "No_Meter", "Breakdown"].includes(status)) { + currentReading = lastReading; + try { + const resp = await updatesingleReading(consumerId, lastReading, lastReading, currentReading, billingPeriod, status, readingDate, lastReadingDate, tenantId); + alert("Update successful for Consumer ID: " + (consumerId || "")); + } catch (err) { + console.error(err); + alert("Update failed: " + (err && err.message ? err.message : "Unknown error")); + } + return; + } + if (!currentReadingRaw || !Number.isFinite(currentReading)) { alert("Please enter a numeric Current Reading before updating"); return; } + if (!readingDate || !Number.isFinite(currentReading)) { + alert("Please enter a numeric Current date before updating"); + return; + } if (currentReading > 10000) { alert("Please enter a numeric Current Reading less than or equal to 10000 before updating"); return; @@ -200,9 +234,9 @@ export const searchResults = { currentReading = status === "Reset" ? (10000 + currentReading - lastReading) : currentReading; - // New Reading Date must not be earlier than Current Reading Date + // New Reading Date must not be earlier than Last Reading Date if (readingDate && currentReadingDate && readingDate < currentReadingDate) { - alert("New Reading Date cannot be earlier than Current Reading Date"); + alert("New Reading Date cannot be earlier than Last Reading Date"); return; } @@ -260,6 +294,8 @@ export const searchResults = { export const updateAllReadings = async (state, dispatch) => { let allarray = []; + let skippedRows = 0; + let errorRows = []; const rows = get( state, @@ -281,7 +317,7 @@ export const updateAllReadings = async (state, dispatch) => { const consumerId = isArrayRow ? row[0] : row["Consumer ID"]; const usageCategory = isArrayRow ? row[1] : row["Usage Category"]; const lastReading = Number(isArrayRow ? row[2] : row["Last Reading"]) || 0; - const currentReadingDateDisplay = isArrayRow ? row[3] : row["Current Reading Date"]; + const currentReadingDateDisplay = isArrayRow ? row[3] : row["Last Reading Date"]; const lastReadingDate = getEpochForDate(currentReadingDateDisplay); // New reading / date: always take what user typed in the row inputs @@ -290,18 +326,63 @@ export const updateAllReadings = async (state, dispatch) => { const currentReadingRaw = currentReadingRawEl ? currentReadingRawEl.value : ""; const newReadingDate = newReadingDateEl ? newReadingDateEl.value : ""; - const statusFromRow = isArrayRow ? row[7] : row["Status"]; + const statusFromRow = isArrayRow ? row[7] : row["Meter Status"]; const status = statusSelects[i] && statusSelects[i].value ? statusSelects[i].value : statusFromRow; const tenantId = isArrayRow ? row[8] : row["TENANT_ID"]; // only allow bulk update for selected meter statuses - const isEditableStatus = ["Working", "Breakdown", "Locked", "Reset", "Replacement"].includes(status); + const isEditableStatus = ["Working", "Reset", "Replacement", "Locked", "No_Meter", "Breakdown"].includes(status); if (!isEditableStatus) { continue; } - // only take complete rows (both value and date filled) + // For Locked, No_Meter, Breakdown - automatically use lastReading and still require date + if (["Locked", "No_Meter", "Breakdown"].includes(status)) { + if (!newReadingDate) { + errorRows.push(consumerId); + continue; + } + const readingDatenew = newReadingDate + ? newReadingDate.split("-").reverse().join("/") + : null; + const billingPeriod = + readingDatenew && currentReadingDateDisplay + ? `${currentReadingDateDisplay} - ${readingDatenew}` + : ""; + const readingDate = readingDatenew ? getEpochForDate(readingDatenew) : null; + + const currentReadingDateEpoch = currentReadingDateDisplay + ? getEpochForDate(currentReadingDateDisplay) + : null; + if (readingDate && currentReadingDateEpoch && readingDate < currentReadingDateEpoch) { + errorRows.push(consumerId); + continue; + } + + const payload = { + meterReadingslist: [ + { + currentReadingDate: readingDate, + currentReading: lastReading, + billingPeriod: billingPeriod, + meterStatus: status, + connectionNo: consumerId, + lastReading: status === "Replacement" ? 0 : lastReading, + lastReadingDate: lastReadingDate, + tenantId: tenantId, + generateDemand: true + } + ] + }; + allarray.push(payload.meterReadingslist[0]); + continue; + } + + // only take complete rows (both value and date filled) for other statuses if (!currentReadingRaw || !newReadingDate) { + if (!newReadingDate) { + errorRows.push(consumerId); + } continue; } @@ -333,12 +414,12 @@ export const updateAllReadings = async (state, dispatch) => { : ""; const readingDate = readingDatenew ? getEpochForDate(readingDatenew) : null; - // New Reading Date must not be earlier than Current Reading Date + // New Reading Date must not be earlier than Last Reading Date const currentReadingDateEpoch = currentReadingDateDisplay ? getEpochForDate(currentReadingDateDisplay) : null; if (readingDate && currentReadingDateEpoch && readingDate < currentReadingDateEpoch) { - // skip this row if date is invalid + errorRows.push(consumerId); continue; } @@ -351,7 +432,7 @@ export const updateAllReadings = async (state, dispatch) => { billingPeriod: billingPeriod, meterStatus: status, connectionNo: consumerId, - lastReading: lastReading, + lastReading: status === "Replacement" ? 0 : lastReading, lastReadingDate: lastReadingDate, tenantId: tenantId, generateDemand: true @@ -362,6 +443,14 @@ export const updateAllReadings = async (state, dispatch) => { } + // Show validation error summary + + + if (allarray.length === 0) { + alert("No valid rows to update. Please fill in all required fields."); + return; + } + try { dispatch(toggleSpinner(true)); const url = "/ws-calculator/meterConnection/_createmultiple"; From ae13c619cd398b9d242cc471eb98941b38348ab0 Mon Sep 17 00:00:00 2001 From: Hari-egov Date: Tue, 12 May 2026 17:52:45 +0530 Subject: [PATCH 20/64] Route Page Title Update Matomo --- .../packages/citizen/public/index.html | 94 ++++++++++++++----- .../packages/employee/public/index.html | 94 ++++++++++++++----- 2 files changed, 138 insertions(+), 50 deletions(-) diff --git a/web/rainmaker/packages/citizen/public/index.html b/web/rainmaker/packages/citizen/public/index.html index f0894967c3..09a69f4b21 100644 --- a/web/rainmaker/packages/citizen/public/index.html +++ b/web/rainmaker/packages/citizen/public/index.html @@ -74,34 +74,78 @@ var pathname = new URL(url).pathname; var path = pathname.replace(/^\/+|\/+$/g, ''); - var pageTitleMap = { - "https://sdc-uat.lgpunjab.gov.in/digit-ui/citizen/select-location": "Citizen Select Location", - "https://sdc-uat.lgpunjab.gov.in/digit-ui/citizen/error": "Citizen Error", - "https://sdc-uat.lgpunjab.gov.in/digit-ui/employee/error": "Employee Error", - "citizen/tl": "Business License Citizen", "employee/tl": "Business License Employee", - "employee/dss/dashboard/tradelicense": "Business License Employee", - "citizen/pt": "Property Tax Citizen", "employee/pt": "Property Tax Employee", - "employee/dss/dashboard/propertytax": "Property Tax Employee", - "citizen/obps": "Building Permit Citizen", "employee/obps": "Building Permit Employee", - "employee/dss/dashboard/obps": "Building Permit Employee", "employee/noc": "Building Permit Employee", - "citizen/mcollect": "mCollect Citizen", "employee/mcollect": "mCollect Employee", - "employee/dss/dashboard/mcollect": "mCollect Employee", "employee/finance": "Finance Employee", - "citizen/ws": "WS Citizen", "employee/ws": "WS Employee", - "employee/dss/dashboard/ws": "WS Employee", - "citizen/birth": "Birth Citizen", "employee/birth": "Birth Employee", - "employee/dss/dashboard/birth-death": "Birth&Death Dashboard Employee", - "citizen/death": "Death Citizen", "employee/death": "Death Employee", - "citizen/fsm": "FSM Citizen", "employee/fsm": "FSM Administrator", - "employee/dss/dashboard/fsm": "FSM Administrator", "employee/tqm": "FSM Plant Operator", - "employee/dss/dashboard/pqm": "FSM Plant Operator", - "citizen/fire-noc": "FNOC Citizen", "employee/fire-noc": "FNOC Employee", - "citizen/engagement/surveys": "Survey Citizen", "employee/engagement/surveys": "Survey Employee" + var exactTitleMap = { + "": "mSeva Home", + "citizen": "Citizen Home", + "employee": "Employee Home", + "employee/inbox": "Employee Inbox", + "employee/landing-page": "Employee Landing Page", + "employee/user/login": "Login Employee", + "employee/user/otp": "OTP Employee", + "employee/user/profile": "Profile Employee", + "employee/language-selection": "Language Selection Employee", + "citizen/user/login": "Login Citizen", + "citizen/user/register": "Register Citizen", + "citizen/user/otp": "OTP Citizen", + "citizen/user/profile": "Profile Citizen", + "citizen/language-selection": "Language Selection Citizen" }; + if (exactTitleMap[path] !== undefined) return exactTitleMap[path]; - if (pageTitleMap[path]) return pageTitleMap[path]; - for (var key in pageTitleMap) { - if (path.includes(key)) return pageTitleMap[key]; + var prefixTitleMap = [ + ["employee/dss/dashboard/propertytax", "Property Tax Dashboard Employee"], + ["employee/dss/dashboard/tradelicense", "Business License Dashboard Employee"], + ["employee/dss/dashboard/obps", "Building Permit Dashboard Employee"], + ["employee/dss/dashboard/ws", "Water & Sewerage Dashboard Employee"], + ["employee/dss/dashboard/mcollect", "mCollect Dashboard Employee"], + ["employee/dss/dashboard/fsm", "FSM Dashboard Employee"], + ["employee/dss/dashboard/pqm", "FSM Plant Operator Dashboard Employee"], + ["employee/dss/dashboard/birth-death", "Birth & Death Dashboard Employee"], + ["employee/dss", "DSS Dashboard Employee"], + ["citizen/engagement/surveys", "Survey Citizen"], + ["employee/engagement/surveys", "Survey Employee"], + ["citizen/property-tax", "Property Tax Citizen"], + ["citizen/propert-tax", "Property Tax Citizen"], + ["employee/property-tax", "Property Tax Employee"], + ["employee/pt-mutation", "Property Tax Employee"], + ["citizen/tradelicense-citizen", "Business License Citizen"], + ["citizen/tradelicence", "Business License Citizen"], + ["citizen/trade-license", "Business License Citizen"], + ["employee/tradelicence", "Business License Employee"], + ["employee/tradelicense", "Business License Employee"], + ["citizen/fire-noc", "FNOC Citizen"], + ["employee/fire-noc", "FNOC Employee"], + ["citizen/obps", "Building Permit Citizen"], + ["employee/obps", "Building Permit Employee"], + ["citizen/bpa", "Building Permit Citizen"], + ["employee/bpa", "Building Permit Employee"], + ["employee/noc", "Building Permit Employee"], + ["citizen/wns", "Water & Sewerage Citizen"], + ["employee/wns", "Water & Sewerage Employee"], + ["citizen/ws", "Water & Sewerage Citizen"], + ["employee/ws", "Water & Sewerage Employee"], + ["citizen/mcollect", "mCollect Citizen"], + ["employee/mcollect", "mCollect Employee"], + ["citizen/fsm", "FSM Citizen"], + ["employee/fsm", "FSM Administrator"], + ["employee/tqm", "FSM Plant Operator"], + ["citizen/birth", "Birth Citizen"], + ["employee/birth", "Birth Employee"], + ["citizen/death", "Death Citizen"], + ["employee/death", "Death Employee"], + ["employee/services", "Finance Employee"], + ["employee/finance", "Finance Employee"], + ["employee/hrms", "HRMS Employee"] + ]; + + for (var i = 0; i < prefixTitleMap.length; i++) { + if (path.indexOf(prefixTitleMap[i][0]) === 0) return prefixTitleMap[i][1]; + } + + if (/(pgr-home|my-complaints|add-complaint|complaint-|create-complaint|all-complaints|search-complaint|closed-complaints|assign-complaint|reassign-complaint|request-reassign|reject-complaint|reopen-complaint|reopen-acknowledgement|feedback|resolve-success|reassign-success)/.test(path)) { + return path.indexOf("citizen") === 0 ? "Complaints Citizen" : "Complaints Employee"; } + return "DIGIT"; } catch (e) { console.error("Error getting page title:", e); diff --git a/web/rainmaker/packages/employee/public/index.html b/web/rainmaker/packages/employee/public/index.html index 641324d775..28d863b25f 100644 --- a/web/rainmaker/packages/employee/public/index.html +++ b/web/rainmaker/packages/employee/public/index.html @@ -64,34 +64,78 @@ var pathname = new URL(url).pathname; var path = pathname.replace(/^\/+|\/+$/g, ''); - var pageTitleMap = { - "https://sdc-uat.lgpunjab.gov.in/digit-ui/citizen/select-location": "Citizen Select Location", - "https://sdc-uat.lgpunjab.gov.in/digit-ui/citizen/error": "Citizen Error", - "https://sdc-uat.lgpunjab.gov.in/digit-ui/employee/error": "Employee Error", - "citizen/tl": "Business License Citizen", "employee/tl": "Business License Employee", - "employee/dss/dashboard/tradelicense": "Business License Employee", - "citizen/pt": "Property Tax Citizen", "employee/pt": "Property Tax Employee", - "employee/dss/dashboard/propertytax": "Property Tax Employee", - "citizen/obps": "Building Permit Citizen", "employee/obps": "Building Permit Employee", - "employee/dss/dashboard/obps": "Building Permit Employee", "employee/noc": "Building Permit Employee", - "citizen/mcollect": "mCollect Citizen", "employee/mcollect": "mCollect Employee", - "employee/dss/dashboard/mcollect": "mCollect Employee", "employee/finance": "Finance Employee", - "citizen/ws": "WS Citizen", "employee/ws": "WS Employee", - "employee/dss/dashboard/ws": "WS Employee", - "citizen/birth": "Birth Citizen", "employee/birth": "Birth Employee", - "employee/dss/dashboard/birth-death": "Birth&Death Dashboard Employee", - "citizen/death": "Death Citizen", "employee/death": "Death Employee", - "citizen/fsm": "FSM Citizen", "employee/fsm": "FSM Administrator", - "employee/dss/dashboard/fsm": "FSM Administrator", "employee/tqm": "FSM Plant Operator", - "employee/dss/dashboard/pqm": "FSM Plant Operator", - "citizen/fire-noc": "FNOC Citizen", "employee/fire-noc": "FNOC Employee", - "citizen/engagement/surveys": "Survey Citizen", "employee/engagement/surveys": "Survey Employee" + var exactTitleMap = { + "": "mSeva Home", + "citizen": "Citizen Home", + "employee": "Employee Home", + "employee/inbox": "Employee Inbox", + "employee/landing-page": "Employee Landing Page", + "employee/user/login": "Login Employee", + "employee/user/otp": "OTP Employee", + "employee/user/profile": "Profile Employee", + "employee/language-selection": "Language Selection Employee", + "citizen/user/login": "Login Citizen", + "citizen/user/register": "Register Citizen", + "citizen/user/otp": "OTP Citizen", + "citizen/user/profile": "Profile Citizen", + "citizen/language-selection": "Language Selection Citizen" }; + if (exactTitleMap[path] !== undefined) return exactTitleMap[path]; - if (pageTitleMap[path]) return pageTitleMap[path]; - for (var key in pageTitleMap) { - if (path.includes(key)) return pageTitleMap[key]; + var prefixTitleMap = [ + ["employee/dss/dashboard/propertytax", "Property Tax Dashboard Employee"], + ["employee/dss/dashboard/tradelicense", "Business License Dashboard Employee"], + ["employee/dss/dashboard/obps", "Building Permit Dashboard Employee"], + ["employee/dss/dashboard/ws", "Water & Sewerage Dashboard Employee"], + ["employee/dss/dashboard/mcollect", "mCollect Dashboard Employee"], + ["employee/dss/dashboard/fsm", "FSM Dashboard Employee"], + ["employee/dss/dashboard/pqm", "FSM Plant Operator Dashboard Employee"], + ["employee/dss/dashboard/birth-death", "Birth & Death Dashboard Employee"], + ["employee/dss", "DSS Dashboard Employee"], + ["citizen/engagement/surveys", "Survey Citizen"], + ["employee/engagement/surveys", "Survey Employee"], + ["citizen/property-tax", "Property Tax Citizen"], + ["citizen/propert-tax", "Property Tax Citizen"], + ["employee/property-tax", "Property Tax Employee"], + ["employee/pt-mutation", "Property Tax Employee"], + ["citizen/tradelicense-citizen", "Business License Citizen"], + ["citizen/tradelicence", "Business License Citizen"], + ["citizen/trade-license", "Business License Citizen"], + ["employee/tradelicence", "Business License Employee"], + ["employee/tradelicense", "Business License Employee"], + ["citizen/fire-noc", "FNOC Citizen"], + ["employee/fire-noc", "FNOC Employee"], + ["citizen/obps", "Building Permit Citizen"], + ["employee/obps", "Building Permit Employee"], + ["citizen/bpa", "Building Permit Citizen"], + ["employee/bpa", "Building Permit Employee"], + ["employee/noc", "Building Permit Employee"], + ["citizen/wns", "Water & Sewerage Citizen"], + ["employee/wns", "Water & Sewerage Employee"], + ["citizen/ws", "Water & Sewerage Citizen"], + ["employee/ws", "Water & Sewerage Employee"], + ["citizen/mcollect", "mCollect Citizen"], + ["employee/mcollect", "mCollect Employee"], + ["citizen/fsm", "FSM Citizen"], + ["employee/fsm", "FSM Administrator"], + ["employee/tqm", "FSM Plant Operator"], + ["citizen/birth", "Birth Citizen"], + ["employee/birth", "Birth Employee"], + ["citizen/death", "Death Citizen"], + ["employee/death", "Death Employee"], + ["employee/services", "Finance Employee"], + ["employee/finance", "Finance Employee"], + ["employee/hrms", "HRMS Employee"] + ]; + + for (var i = 0; i < prefixTitleMap.length; i++) { + if (path.indexOf(prefixTitleMap[i][0]) === 0) return prefixTitleMap[i][1]; + } + + if (/(pgr-home|my-complaints|add-complaint|complaint-|create-complaint|all-complaints|search-complaint|closed-complaints|assign-complaint|reassign-complaint|request-reassign|reject-complaint|reopen-complaint|reopen-acknowledgement|feedback|resolve-success|reassign-success)/.test(path)) { + return path.indexOf("citizen") === 0 ? "Complaints Citizen" : "Complaints Employee"; } + return "DIGIT"; } catch (e) { console.error("Error getting page title:", e); From ee95fab3d5ddd3e825f300ea0afbae75d7aefcd2 Mon Sep 17 00:00:00 2001 From: erramesh000 Date: Thu, 14 May 2026 16:54:50 +0530 Subject: [PATCH 21/64] Fixed issues bulkmeter screen --- .../screens/specs/abg/gBmr/functions.js | 3 +- .../screens/specs/abg/gBmr/searchResults.js | 60 +++++++++++++++---- 2 files changed, 49 insertions(+), 14 deletions(-) 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 index 627d0efec7..5236f2e8b1 100644 --- 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 @@ -31,7 +31,8 @@ export const updatesingleReading = async (consumerId, lastReading, currentReadin lastReading: lastReading, lastReadingDate: lastReadingDate, tenantId: tenantId, - generateDemand: true + generateDemand: true, + isBulkMeter: lastReading > 10000 ? true : false } ] }; 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 index 48cadb8f14..aeb75719b8 100644 --- 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 @@ -69,7 +69,7 @@ export const searchResults = { 10000) { + if (numeric > 10000 && status != "Reset") { e.target.value = ""; updateValue(""); alert("Please enter a numeric value less than or equal to 10000"); @@ -110,6 +110,35 @@ export const searchResults = { } } }, + { + labelName: "Consumption", + labelKey: "Consumption", + options: { + filter: false, + customBodyRender: (value, tableMeta) => { + const lastReading = Number(tableMeta.rowData && tableMeta.rowData[2]) || 0; + const status = tableMeta.rowData && tableMeta.rowData[4]; + const inputs = (document.querySelectorAll && document.querySelectorAll("input.bulk-new-reading")) || []; + const inputEl = inputs[tableMeta.rowIndex]; + const newReadingRaw = inputEl ? inputEl.value : (tableMeta.rowData && tableMeta.rowData[5]); + + if (newReadingRaw === undefined || newReadingRaw === null || newReadingRaw === "") return ""; + const newReading = Number(newReadingRaw) || 0; + + if (["Locked", "No_Meter", "Breakdown"].includes(status)) return String(0); + + if (status === "Replacement") { + return String(newReading - 0); + } + + if (status === "Reset") { + return String(10000 + newReading - lastReading); + } + + return String(newReading - lastReading); + } + } + }, { labelName: "New Reading Date", labelKey: "New Reading Date", @@ -181,7 +210,8 @@ export const searchResults = { options: { filter: false, customBodyRender: (value, tableMeta, updateValue) => { - let readingDatenew = tableMeta.rowData[6]; + + let readingDatenew = tableMeta.rowData[7]; readingDatenew = readingDatenew ? readingDatenew.split("-").reverse().join("/") : null; const handleUpdate = async () => { @@ -195,16 +225,17 @@ export const searchResults = { const lastReadingDate = currentReadingDate; const currentReadingRaw = Number(tableMeta.rowData && tableMeta.rowData[5]) || 0; let currentReading = Number(currentReadingRaw) || 0; + let consumption = currentReading - lastReading; const billingPeriod = readingDatenew ? `${tableMeta.rowData[3]} - ${readingDatenew}` : ""; const readingDate = readingDatenew ? getEpochForDate(readingDatenew) : null; - - const tenantId = tableMeta.rowData && tableMeta.rowData[8]; + let isBulkMeter = currentReading > 10000 ? false : true; + const tenantId = tableMeta.rowData && tableMeta.rowData[9]; // If status is Locked, No_Meter, or Breakdown, automatically set currentReading to lastReading if (["Locked", "No_Meter", "Breakdown"].includes(status)) { currentReading = lastReading; try { - const resp = await updatesingleReading(consumerId, lastReading, lastReading, currentReading, billingPeriod, status, readingDate, lastReadingDate, tenantId); + const resp = await updatesingleReading(consumerId, lastReading, lastReading, currentReading, billingPeriod, status, readingDate, lastReadingDate, tenantId, isBulkMeter); alert("Update successful for Consumer ID: " + (consumerId || "")); } catch (err) { console.error(err); @@ -213,7 +244,7 @@ export const searchResults = { return; } - if (!currentReadingRaw || !Number.isFinite(currentReading)) { + if (!currentReadingRaw) { alert("Please enter a numeric Current Reading before updating"); return; } @@ -232,7 +263,7 @@ export const searchResults = { return; } - currentReading = status === "Reset" ? (10000 + currentReading - lastReading) : currentReading; + consumption = status === "Reset" ? (10000 + currentReading - lastReading) : currentReading; // New Reading Date must not be earlier than Last Reading Date if (readingDate && currentReadingDate && readingDate < currentReadingDate) { @@ -241,7 +272,7 @@ export const searchResults = { } try { - const resp = await updatesingleReading(consumerId, lastReading, currentReadingRaw, currentReading, billingPeriod, status, readingDate, lastReadingDate, tenantId); + const resp = await updatesingleReading(consumerId, lastReading, currentReadingRaw, currentReading, billingPeriod, status, readingDate, lastReadingDate, tenantId, isBulkMeter); // updatesingleReading may return response or throw on error alert("Update successful for Consumer ID: " + (consumerId || "")); } catch (err) { @@ -263,7 +294,7 @@ export const searchResults = { } }, ], - title: { labelName: "Search Results for Group Bills", labelKey: "BILL_GENIE_GROUP_SEARCH_HEADER" }, + title: { labelName: "Search Results for Water Connection", labelKey: "BILL_GENIE_GROUP_SEARCH_HEADER_Water-Connection" }, rows: "", options: { filter: false, @@ -370,7 +401,8 @@ export const updateAllReadings = async (state, dispatch) => { lastReading: status === "Replacement" ? 0 : lastReading, lastReadingDate: lastReadingDate, tenantId: tenantId, - generateDemand: true + generateDemand: true, + isBulkMeter: lastReading > 10000 ? true : false } ] }; @@ -402,7 +434,8 @@ export const updateAllReadings = async (state, dispatch) => { // Calculate actual reading for Reset status if (status === "Reset") { - currentReading = 10000 + currentReading - lastReading; + currentReading = currentReading; + //consumption = 10000 + currentReading - lastReading; } const readingDatenew = newReadingDate @@ -435,7 +468,8 @@ export const updateAllReadings = async (state, dispatch) => { lastReading: status === "Replacement" ? 0 : lastReading, lastReadingDate: lastReadingDate, tenantId: tenantId, - generateDemand: true + generateDemand: true, + isBulkMeter: lastReading > 10000 ? true : false } ] }; From 5bafe89e72e0f2e80cdd1f96fccecd2d5a529395 Mon Sep 17 00:00:00 2001 From: erramesh000 Date: Thu, 14 May 2026 17:47:43 +0530 Subject: [PATCH 22/64] update Reset and Replacement changes --- .../wns/meterReading/meterReadingEditable.js | 84 ++++++------------- 1 file changed, 26 insertions(+), 58 deletions(-) diff --git a/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/screens/specs/wns/meterReading/meterReadingEditable.js b/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/screens/specs/wns/meterReading/meterReadingEditable.js index 19b7917462..6529ba9b7a 100644 --- a/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/screens/specs/wns/meterReading/meterReadingEditable.js +++ b/web/rainmaker/dev-packages/egov-wns-dev/src/ui-config/screens/specs/wns/meterReading/meterReadingEditable.js @@ -30,10 +30,6 @@ function parseDDMMYYYY(dateStr) { const saveData = async (state, dispatch) => { const mode = get(state, "screenConfiguration.preparedFinalObject.autoPopulatedValues.mode"); let data = get(state, "screenConfiguration.preparedFinalObject.metereading"); - let lastReading = get(state, "screenConfiguration.preparedFinalObject.autoPopulatedValues.lastReading"); - let currentReading = Number(data.currentReading); - data.currentReading = data.meterStatus === "Reset" ? (10000 + currentReading - lastReading) : data.currentReading; - lastReading = data.meterStatus === "Replacement" ? 0 : lastReading; if (!data || data.length === 0) { dispatch( @@ -87,8 +83,7 @@ const saveData = async (state, dispatch) => { data.meterStatus = get(state, "screenConfiguration.preparedFinalObject.meterMdmsData.['ws-services-calculation'].MeterStatus[0].code"); } data.connectionNo = getQueryArg(window.location.href, "connectionNos") - // data.lastReading = get(state, "screenConfiguration.preparedFinalObject.autoPopulatedValues.lastReading"); - data.lastReading = lastReading + data.lastReading = get(state, "screenConfiguration.preparedFinalObject.autoPopulatedValues.lastReading"); // Set last reading date and ID based on mode (add vs edit) if (mode === 'edit') { @@ -103,7 +98,7 @@ const saveData = async (state, dispatch) => { } } - if (data.meterStatus === 'Working') { + if (data.meterStatus === 'Working' || data.meterStatus === 'Reset' || data.meterStatus === 'Replacement') { validateFields( "components.div.children.meterReadingEditable.children.card.children.cardContent.children.fourthContainer.children", state, @@ -135,40 +130,6 @@ const saveData = async (state, dispatch) => { return; } } - - else if (data.meterStatus === 'Reset' || data.meterStatus === 'Replacement' || data.meterStatus === 'No-meter') { - // For these statuses, consumption field is hidden. Validate currentReading and date fields instead. - validateFields( - "components.div.children.meterReadingEditable.children.card.children.cardContent.children.fourthContainer.children", - state, - dispatch, - "meter-reading" - ); - validateFields( - "components.div.children.meterReadingEditable.children.card.children.cardContent.children.fifthContainer.children", - state, - dispatch, - "meter-reading" - ); - - // Ensure currentReading is present (for Reset/Replacement user should enter currentReading) - if (data.currentReading === null || data.currentReading === undefined || data.currentReading === "") { - return; - } - - // If date not provided, set to today - if (!data.currentReadingDate) { - data.currentReadingDate = new Date().getTime(); - } - - // Apply Reset calculation if needed - if (data.meterStatus === 'Reset') { - const curr = Number(data.currentReading) || 0; - data.currentReading = 10000 + curr - lastReading; - } - - // Replacement: ensure lastReading considered 0 (already handled above) - } else { const consumption = validateFields( "components.div.children.meterReadingEditable.children.card.children.cardContent.children.sixthContainer.children", @@ -179,8 +140,8 @@ const saveData = async (state, dispatch) => { if (!data.consumption) { return; } - const previousreading = lastReading; - // data.currentReading = parseFloat(data.consumption) + previousreading; + const previousreading = get(state, "screenConfiguration.preparedFinalObject.autoPopulatedValues.lastReading"); + data.currentReading = parseFloat(data.consumption) + previousreading; data.currentReadingDate = new Date().getTime(); } @@ -310,7 +271,7 @@ export const meterReadingEditable = }), afterFieldChange: async (action, state, dispatch) => { let status = get(state, "screenConfiguration.preparedFinalObject.metereading.meterStatus"); - if (status == 'Working') { + if (status == 'Working' || status == 'Reset' || status == 'Replacement') { dispatch( handleField( "meter-reading", @@ -468,13 +429,13 @@ export const meterReadingEditable = ) ); } - else if (status == 'Reset' || status == 'Replacement' || status == 'No-meter') { + else if (status == 'No-meter') { dispatch( handleField( "meter-reading", "components.div.children.meterReadingEditable.children.card.children.cardContent.children.fourthContainer.children.currentReading.props", "disabled", - false + true ) ); dispatch( @@ -482,7 +443,7 @@ export const meterReadingEditable = "meter-reading", "components.div.children.meterReadingEditable.children.card.children.cardContent.children.fifthContainer.children.currentReadingDate.props", "disabled", - false + true ) ); dispatch( @@ -498,7 +459,7 @@ export const meterReadingEditable = "meter-reading", "components.div.children.meterReadingEditable.children.card.children.cardContent.children.sixthContainer.children.thirdCont", "visible", - false + true ) ); dispatch( @@ -506,7 +467,7 @@ export const meterReadingEditable = "meter-reading", "components.div.children.meterReadingEditable.children.card.children.cardContent.children.sixthContainer.children.thirdCont", "visible", - false + true ) ); dispatch( @@ -765,14 +726,24 @@ export const meterReadingEditable = afterFieldChange: async (action, state, dispatch) => { let lastReading = get(state, "screenConfiguration.preparedFinalObject.autoPopulatedValues.lastReading"); let currentReading = get(state, "screenConfiguration.preparedFinalObject.metereading.currentReading"); + let newstatus = get(state, "screenConfiguration.preparedFinalObject.metereading.meterStatus"); let consumption; - if (lastReading === 0) { + if (newstatus == "Reset") { + consumption = (10000 + Number(currentReading) - lastReading).toFixed(2); + } + else if (newstatus == "Replacement") { consumption = currentReading - } else { - consumption = (currentReading - lastReading).toFixed(2); } - if (currentReading == '' || consumption < 0) { - consumption = '' + else { + + if (lastReading === 0) { + consumption = currentReading + } else { + consumption = (currentReading - lastReading).toFixed(2); + } + if (currentReading == '' || consumption < 0) { + consumption = '' + } } dispatch( handleField( @@ -959,7 +930,4 @@ export const meterReadingEditable = }) } -} - - - +} \ No newline at end of file From 26f6159ac0e8385ab2c762aed687594f44e2a267 Mon Sep 17 00:00:00 2001 From: anujkit Date: Thu, 14 May 2026 18:19:32 +0530 Subject: [PATCH 23/64] PI-21349 --- .../egov-workflow-dev/src/ui-molecules-local/Footer/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/rainmaker/dev-packages/egov-workflow-dev/src/ui-molecules-local/Footer/index.js b/web/rainmaker/dev-packages/egov-workflow-dev/src/ui-molecules-local/Footer/index.js index a949415d75..7d423992e5 100644 --- a/web/rainmaker/dev-packages/egov-workflow-dev/src/ui-molecules-local/Footer/index.js +++ b/web/rainmaker/dev-packages/egov-workflow-dev/src/ui-molecules-local/Footer/index.js @@ -540,10 +540,10 @@ class Footer extends React.Component { } }; if (responseLength > 1) { - if (applicationType !== "NEW") { + //if (applicationType !== "NEW") { downloadMenu && downloadMenu.push(editButton); downloadMenu && downloadMenu.push(submitButton); - } + // } } else if (responseLength === 1) { From 854f6e63e794d17ea501b33f4b75062fd9d01f95 Mon Sep 17 00:00:00 2001 From: erramesh000 Date: Tue, 19 May 2026 09:36:36 +0530 Subject: [PATCH 24/64] Fixed issues bulkmeter reading --- .../screens/specs/abg/gBmr/searchResults.js | 1 - .../src/ui-molecules-local/MeterReading/index.js | 13 ++++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) 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 index aeb75719b8..862787e899 100644 --- 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 @@ -29,7 +29,6 @@ export const searchResults = { "Working", "Locked", "Breakdown", - "No_Meter", "Reset", "Replacement" ]; diff --git a/web/rainmaker/dev-packages/egov-wns-dev/src/ui-molecules-local/MeterReading/index.js b/web/rainmaker/dev-packages/egov-wns-dev/src/ui-molecules-local/MeterReading/index.js index 551d5c6159..3258400c3c 100644 --- a/web/rainmaker/dev-packages/egov-wns-dev/src/ui-molecules-local/MeterReading/index.js +++ b/web/rainmaker/dev-packages/egov-wns-dev/src/ui-molecules-local/MeterReading/index.js @@ -11,7 +11,7 @@ import get from "lodash/get"; import LabelContainer from "egov-ui-framework/ui-containers/LabelContainer"; import { setRoute } from "egov-ui-framework/ui-redux/app/actions"; import { convertEpochToDate } from "../../ui-config/screens/specs/utils"; -import {addMeterReading} from "../../ui-config/screens/specs/wns/meter-reading" +import { addMeterReading } from "../../ui-config/screens/specs/wns/meter-reading" const styles = { card: { marginLeft: 8, @@ -151,7 +151,14 @@ class MeterReading extends React.Component {