tercer commit
This commit is contained in:
+89
-3
@@ -97,12 +97,21 @@ function buildFieldsList() {
|
||||
'summary',
|
||||
'status',
|
||||
'assignee',
|
||||
config.fields.spEstimate, // Story points estimate
|
||||
config.fields.spFinal, // Story points finales
|
||||
config.fields.developer, // Desarrollador (multi-user)
|
||||
config.fields.spEstimate, // Story points estimate
|
||||
config.fields.spFinal, // Story points finales
|
||||
config.fields.developer, // Desarrollador (multi-user)
|
||||
'resolutiondate',
|
||||
'created',
|
||||
'updated',
|
||||
// ── QA Fields ──────────────────────────────────────
|
||||
config.fields.qaAssignee, // QA asignado
|
||||
config.fields.qaEntryRtqa, // Fecha entrada READY TO QA
|
||||
config.fields.qaTotalTimeRtqa, // Tiempo total en READY TO QA (min)
|
||||
config.fields.qaLastDurRtqa, // Última duración en READY TO QA (min)
|
||||
config.fields.qaEntryQa, // Fecha entrada QA
|
||||
config.fields.qaTotalTimeQa, // Tiempo total en QA (min)
|
||||
config.fields.qaLastDurQa, // Última duración en QA (min)
|
||||
config.fields.timesReturned, // Veces que volvió a En Curso
|
||||
].join(',');
|
||||
}
|
||||
|
||||
@@ -112,12 +121,31 @@ function buildFieldsList() {
|
||||
* @param {Array} issues - Array de issues de JIRA
|
||||
* @returns {Object} Datos procesados
|
||||
*/
|
||||
// Helper: convierte minutos a horas redondeadas a 1 decimal
|
||||
function minsToHrs(mins) {
|
||||
if (mins == null || mins === 0) return 0;
|
||||
return Math.round((mins / 60) * 10) / 10;
|
||||
}
|
||||
|
||||
function processIssues(issues) {
|
||||
const assigneeData = {};
|
||||
const monthlyDone = {};
|
||||
const issuesList = [];
|
||||
const warnings = [];
|
||||
const now = new Date();
|
||||
|
||||
// ── QA Aggregation ──────────────────────────────────────────────────
|
||||
const qaData = {
|
||||
tickets: 0,
|
||||
ticketsReturned: 0,
|
||||
totalTimeQa: 0, // minutos
|
||||
totalTimeRtqa: 0, // minutos
|
||||
monthlyTotalQa: {}, // { 'YYYY-MM': totalMin }
|
||||
monthlyCountQa: {}, // { 'YYYY-MM': count }
|
||||
monthlyTotalRtqa: {},
|
||||
monthlyCountRtqa: {},
|
||||
issues: [],
|
||||
};
|
||||
|
||||
let processedCount = 0;
|
||||
let skippedCount = 0;
|
||||
@@ -197,6 +225,41 @@ function processIssues(issues) {
|
||||
creMonth
|
||||
});
|
||||
|
||||
// ── Acumular datos de QA ────────────────────────────────────
|
||||
const timeQaMin = f[config.fields.qaTotalTimeQa] ?? 0;
|
||||
const timeRtqaMin = f[config.fields.qaTotalTimeRtqa] ?? 0;
|
||||
const lastDurQa = f[config.fields.qaLastDurQa] ?? 0;
|
||||
const timesRet = f[config.fields.timesReturned] ?? 0;
|
||||
const qaMonth = resMonth || creMonth;
|
||||
|
||||
if (timeQaMin > 0) {
|
||||
qaData.tickets++;
|
||||
qaData.totalTimeQa += timeQaMin;
|
||||
if (timesRet > 1) qaData.ticketsReturned++;
|
||||
|
||||
if (qaMonth) {
|
||||
qaData.monthlyTotalQa[qaMonth] = (qaData.monthlyTotalQa[qaMonth] || 0) + timeQaMin;
|
||||
qaData.monthlyCountQa[qaMonth] = (qaData.monthlyCountQa[qaMonth] || 0) + 1;
|
||||
}
|
||||
|
||||
qaData.issues.push({
|
||||
key: issue.key,
|
||||
summary: f.summary,
|
||||
timeQa: minsToHrs(timeQaMin),
|
||||
timeRtqa: minsToHrs(timeRtqaMin),
|
||||
lastDurQa: minsToHrs(lastDurQa),
|
||||
timesReturned: timesRet,
|
||||
status: statusKey,
|
||||
resMonth: qaMonth,
|
||||
});
|
||||
}
|
||||
|
||||
if (timeRtqaMin > 0 && qaMonth) {
|
||||
qaData.totalTimeRtqa += timeRtqaMin;
|
||||
qaData.monthlyTotalRtqa[qaMonth] = (qaData.monthlyTotalRtqa[qaMonth] || 0) + timeRtqaMin;
|
||||
qaData.monthlyCountRtqa[qaMonth] = (qaData.monthlyCountRtqa[qaMonth] || 0) + 1;
|
||||
}
|
||||
|
||||
// ── Detectar Warnings ───────────────────────────────────────
|
||||
// 1. Tickets > 14 días in-progress
|
||||
if (isInProgress && f.updated) {
|
||||
@@ -225,6 +288,28 @@ function processIssues(issues) {
|
||||
|
||||
console.log(`📊 Procesados: ${processedCount} | Saltados: ${skippedCount} | Warnings: ${warnings.length}`);
|
||||
|
||||
// ── Calcular promedios mensuales QA ─────────────────────────────────
|
||||
const monthlyAvgQa = {};
|
||||
for (const m of Object.keys(qaData.monthlyTotalQa)) {
|
||||
monthlyAvgQa[m] = minsToHrs(qaData.monthlyTotalQa[m] / qaData.monthlyCountQa[m]);
|
||||
}
|
||||
const monthlyAvgRtqa = {};
|
||||
for (const m of Object.keys(qaData.monthlyTotalRtqa)) {
|
||||
monthlyAvgRtqa[m] = minsToHrs(qaData.monthlyTotalRtqa[m] / qaData.monthlyCountRtqa[m]);
|
||||
}
|
||||
qaData.monthlyAvgQa = monthlyAvgQa;
|
||||
qaData.monthlyAvgRtqa = monthlyAvgRtqa;
|
||||
qaData.avgTimeQa = qaData.tickets > 0 ? minsToHrs(qaData.totalTimeQa / qaData.tickets) : 0;
|
||||
qaData.avgTimeRtqa = qaData.tickets > 0 ? minsToHrs(qaData.totalTimeRtqa / qaData.tickets) : 0;
|
||||
|
||||
// Limpiar campos internos de acumulación
|
||||
delete qaData.monthlyTotalQa;
|
||||
delete qaData.monthlyCountQa;
|
||||
delete qaData.monthlyTotalRtqa;
|
||||
delete qaData.monthlyCountRtqa;
|
||||
|
||||
console.log(`🧪 QA: ${qaData.tickets} tickets | ${qaData.ticketsReturned} devueltos | Avg QA: ${qaData.avgTimeQa}hs`);
|
||||
|
||||
return {
|
||||
lastUpdated: new Date().toISOString(),
|
||||
totalIssues: processedCount,
|
||||
@@ -233,6 +318,7 @@ function processIssues(issues) {
|
||||
monthlyDone,
|
||||
issuesList,
|
||||
warnings,
|
||||
qaData,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user