Skip to content
10 changes: 1 addition & 9 deletions .github/workflows/buildProjectFactory.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ on:
branches:
- allValidations
- master
pull_request:
branches:
- allValidations
- master

env:
DOCKER_USERNAME: ${{ vars.DOCKER_USERNAME }}
Expand Down Expand Up @@ -69,11 +65,7 @@ jobs:
id: tag
run: |
set -euxo pipefail
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
BRANCH="${GITHUB_HEAD_REF}"
else
BRANCH="${GITHUB_REF##*/}"
fi
BRANCH="${GITHUB_REF##*/}"
COMMIT_HASH=$(git rev-parse --short HEAD)
SERVICE_NAME="project-factory"
TOKEN=$(curl -s -X POST "https://hub.docker.com/v2/users/login/" \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
searchProjectTypeCampaignService,
updateProjectTypeCampaignService
} from "../../service/campaignManageService";
import { getCampaignStatusService } from "../../service/campaignStatusService";
import { logger } from "../../utils/logger";
import { errorResponder, sendResponse } from "../../utils/genericUtils";
import { validateSearchProjectCampaignRequest } from "../../validators/campaignValidators";
Expand All @@ -33,6 +34,7 @@ class campaignManageController {
this.router.post(`${this.path}/createCampaign`, this.createCampaign);
this.router.post(`${this.path}/fetch-from-microplan`, this.fetchFromMicroplan);
this.router.post(`${this.path}/cancel-campaign`, this.cancelCampaign);
this.router.post(`${this.path}/status`, this.getCampaignStatus);
}


Expand Down Expand Up @@ -157,6 +159,60 @@ class campaignManageController {
}
}

getCampaignStatus = async (
request: express.Request,
response: express.Response
) => {
try {
logger.info("RECEIVED A CAMPAIGN STATUS REQUEST");
const campaignNumber = request?.body?.CampaignDetails?.campaignNumber;
const tenantId = request?.body?.CampaignDetails?.tenantId;

if (!campaignNumber) {
return errorResponder({
message: "Campaign number is required",
code: "CAMPAIGN_NUMBER_REQUIRED",
description: "Please provide campaignNumber in request body"
}, request, response, 400);
}

if (!tenantId) {
return errorResponder({
message: "TenantId is required",
code: "TENANT_ID_REQUIRED",
description: "Please provide tenantId in request body"
}, request, response, 400);
}

// Check if campaign exists
const campaignSearchCriteria = {
tenantId,
campaignNumber
};

const responseData = await searchProjectTypeCampaignService(campaignSearchCriteria, request);

if (!responseData || responseData?.CampaignDetails.length === 0) {
return errorResponder({
message: "Campaign not found",
code: "CAMPAIGN_NOT_FOUND",
description: `Campaign with number ${campaignNumber} not found`
}, request, response, 404);
}

const statusResponse = await getCampaignStatusService(campaignNumber, tenantId, request);
return sendResponse(response, { CampaignStatus: statusResponse }, request);
} catch (e: any) {
console.log(e);
logger.error(String(e));
return errorResponder({
message: String(e),
code: e?.code,
description: e?.description
}, request, response, e?.status || 500);
}
};

};

export default campaignManageController;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import config from "../config";
import { executeQuery, getTableName } from "../utils/db";
import { logger } from "../utils/logger";

interface MappingRow {
type: string;
status: string;
status_count: string;
}

interface CampaignRow {
type: string;
status: string;
status_count: string;
}

interface ProcessRow {
processname: string;
status: string;
}

interface CampaignStatusResponse {
campaignNumber: string;
summary: Record<string, Record<string, number>>;
processes: ProcessRow[];
}

async function getCampaignStatusService(
campaignNumber: string,
tenantId: string,
request?: any
): Promise<CampaignStatusResponse> {
try {
logger.info(`Fetching campaign status for campaign: ${campaignNumber}, tenant: ${tenantId}`);

// Get table names with tenant schema
const mappingTableName = getTableName(config.DB_CONFIG.DB_CAMPAIGN_MAPPING_DATA_TABLE_NAME, tenantId);
const campaignDataTableName = getTableName(config.DB_CONFIG.DB_CAMPAIGN_DATA_TABLE_NAME, tenantId);
const processTableName = getTableName(config.DB_CONFIG.DB_CAMPAIGN_PROCESS_DATA_TABLE_NAME, tenantId);

// 1. Mapping Data Query (no tenantid column in this table)
const mappingQuery = `
SELECT type, status, COUNT(status) AS status_count
FROM ${mappingTableName}
WHERE campaignnumber = $1
GROUP BY type, status
`;
const mappingResult = await executeQuery(mappingQuery, [campaignNumber]);

// 2. Campaign Data Query (no tenantid column in this table)
const campaignQuery = `
SELECT type, status, COUNT(status) AS status_count
FROM ${campaignDataTableName}
WHERE campaignnumber = $1
GROUP BY type, status
`;
const campaignResult = await executeQuery(campaignQuery, [campaignNumber]);

// 3. Process Data Query (no tenantid column in this table)
const processQuery = `
SELECT processname, status
FROM ${processTableName}
WHERE campaignnumber = $1
`;
const processResult = await executeQuery(processQuery, [campaignNumber]);

// Transform results
const summary: Record<string, Record<string, number>> = {};

// Process mapping data
mappingResult.rows.forEach((row: MappingRow) => {
if (!summary[row.type]) {
summary[row.type] = {};
}
summary[row.type][row.status] = parseInt(row.status_count, 10);
});

// Process campaign data
campaignResult.rows.forEach((row: CampaignRow) => {
if (!summary[row.type]) {
summary[row.type] = {};
}
summary[row.type][row.status] = parseInt(row.status_count, 10);
});

const response: CampaignStatusResponse = {
campaignNumber,
summary,
processes: processResult.rows
};

logger.info(`Successfully fetched campaign status for campaign: ${campaignNumber}`);
return response;
} catch (error: any) {
logger.error(`Error fetching campaign status: ${error?.message}`);
throw error;
}
}

export { getCampaignStatusService };
Original file line number Diff line number Diff line change
Expand Up @@ -1282,10 +1282,10 @@ async function makeParentInactiveOrActive(parentCampaign: any, userUuid: string,
};
parentCampaign.auditDetails.lastModifiedTime = Date.now();
parentCampaign.auditDetails.lastModifiedBy = userUuid;
const RequestInfo = JSON.parse(JSON.stringify(defaultRequestInfo || {}));
RequestInfo.userInfo.uuid = userUuid;
const requestInfoObject = JSON.parse(JSON.stringify(defaultRequestInfo || {}));
requestInfoObject.RequestInfo.userInfo.uuid = userUuid;
const produceMessage: any = {
RequestInfo,
RequestInfo: requestInfoObject.RequestInfo,
CampaignDetails: parentCampaign,
};
await produceModifiedMessages(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export async function validateMissingBoundaryFromParent(requestBody : any) {
// as we've already confirmed it's not missing any from the parent.
if (setOfBoundaryCodesFromCurrentCampaign.size !== parentBoundaryCodes.size) {
const boundaryResource = CampaignDetails.resources?.find(
(r: any) => r.type === 'boundary' && r.fileStoreId
(r: any) => r.type === 'boundary' && r.filestoreId
);
if (!boundaryResource) {
throwError("COMMON", 400, "VALIDATION_ERROR_MISSING_TARGET_FILE", "A new boundary file must be provided when changing boundaries from the parent campaign.");
Expand Down Expand Up @@ -750,4 +750,4 @@ export {
fetchProjectsWithBoundaryCodeAndReferenceId,
delinkAndLinkResourcesWithProjectCorrespondingToGivenBoundary,
processResources,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ async function lockSheetAccordingToConfig(workBook: any, templateConfig: any, lo
// Protect sheet with full options
await worksheet.protect('passwordhere', {
selectLockedCells: true,
selectUnlockedCells: true,
selectUnlockedCells: false,
formatCells: false,
formatColumns: false,
formatRows: false,
Expand Down Expand Up @@ -725,10 +725,3 @@ export function filterResourceDetailType(type : string){
throwError("COMMON", 400, "VALIDATION_ERROR", `Type ${type} not found or invalid`);
}
}







Loading