excel fix

This commit is contained in:
Raman Marikanti 2026-02-12 16:39:43 +05:30
parent 03dd5406aa
commit a100d99f1d
1 changed files with 397 additions and 160 deletions

View File

@ -509,6 +509,7 @@ export class CustomerOrderStatusGrid extends Component {
const dayStr = `${day.toString().padStart(2, '0')}/${month}/${year}`; const dayStr = `${day.toString().padStart(2, '0')}/${month}/${year}`;
const dayKey = `day_${day}`; const dayKey = `day_${day}`;
dayColumns.push({ dayColumns.push({
title: dayStr, title: dayStr,
width: 90, width: 90,
@ -540,6 +541,7 @@ export class CustomerOrderStatusGrid extends Component {
const orderQty = pendingOrder + currentOrder; const orderQty = pendingOrder + currentOrder;
const fgAvailable = parseFloat(row.fg_qty) || 0; const fgAvailable = parseFloat(row.fg_qty) || 0;
const remainingProduction = Math.max(0, orderQty - fgAvailable); const remainingProduction = Math.max(0, orderQty - fgAvailable);
const remaining_dispatch_qty = Math.max(0, orderQty - parseFloat(row.dispatch_qty) )
// Process date-wise production data // Process date-wise production data
const dailyProduction = {}; const dailyProduction = {};
@ -584,7 +586,9 @@ export class CustomerOrderStatusGrid extends Component {
dispatch_qty: parseFloat(row.dispatch_qty) || 0, dispatch_qty: parseFloat(row.dispatch_qty) || 0,
dispatched_qty_kg: parseFloat(row.dispatched_qty_kg) || 0, dispatched_qty_kg: parseFloat(row.dispatched_qty_kg) || 0,
remaining_production: remainingProduction, remaining_production: remainingProduction,
remaining_dispatch_qty: remaining_dispatch_qty,
date_wise: row.date_wise, date_wise: row.date_wise,
produced_qty: row.produced_qty,
...dailyProduction ...dailyProduction
}; };
}); });
@ -1451,9 +1455,9 @@ export class CustomerOrderStatusGrid extends Component {
style: { backgroundColor: '#d4edda', textAlign: 'right' } style: { backgroundColor: '#d4edda', textAlign: 'right' }
}, },
{ {
title: "Dispatch Qty", title: "Produced Qty",
width: 90, width: 90,
dataIndx: "dispatch_qty", dataIndx: "produced_qty",
dataType: "float", dataType: "float",
align: "right", align: "right",
render: (ui) => this.formatInteger(ui.cellData), render: (ui) => this.formatInteger(ui.cellData),
@ -1484,6 +1488,36 @@ export class CustomerOrderStatusGrid extends Component {
textAlign: 'right' textAlign: 'right'
}; };
} }
},
{
title: "Dispatch Qty",
width: 90,
dataIndx: "dispatch_qty",
dataType: "float",
align: "right",
render: (ui) => this.formatInteger(ui.cellData),
summary: {
type: "sum",
label: "Total:",
render: (ui) => this.formatInteger(ui.data)
},
style: { backgroundColor: '#e3f2fd', textAlign: 'right' }
},
{
title: "Remaining Dispatch",
width: 120,
dataIndx: "remaining_dispatch_qty",
dataType: "float",
filter: true,
sortable: true,
align: "right",
render: (ui) => this.formatInteger(ui.cellData),
summary: {
type: "sum",
label: "Total:",
render: (ui) => this.formatInteger(ui.data)
},
style: { textAlign: 'right', backgroundColor: '#fff3cd' }
} }
]; ];
@ -1559,14 +1593,6 @@ export class CustomerOrderStatusGrid extends Component {
// EXPORT METHODS // EXPORT METHODS
// ==================== // ====================
// Replace your exportGrid method with this:
// ====================
// EXPORT METHODS - FIXED FOR DATA EXPORT
// ====================
// ====================
// EXPORT METHODS - WITH MERGED CELLS FOR GROUP HEADERS
// ====================
exportGrid(ev, type) { exportGrid(ev, type) {
ev.preventDefault(); ev.preventDefault();
@ -1582,25 +1608,25 @@ exportGrid(ev, type) {
gridData = this.state.gridData; gridData = this.state.gridData;
columns = this.getOrderGridColumns(); columns = this.getOrderGridColumns();
sheetName = 'Customer Order Status'; sheetName = 'Customer Order Status';
filename = `Customer_Order_Status_${this.getMonthYearLabel().replace(/ /g, '_')}_${new Date().toISOString().split('T')[0]}.xlsx`; filename = `Customer_Order_Status_${this.getMonthYearLabel().replace(/ /g, '_')}_${new Date().toISOString().split('T')[0]}.xls`;
break; break;
case 'dispatch': case 'dispatch':
gridData = this.state.dispatchData; gridData = this.state.dispatchData;
columns = this.getDispatchGridColumns(); columns = this.getDispatchGridColumns();
sheetName = 'Dispatch Summary'; sheetName = 'Dispatch Summary';
filename = `Dispatch_Summary_${this.getMonthYearLabel().replace(/ /g, '_')}_${new Date().toISOString().split('T')[0]}.xlsx`; filename = `Dispatch_Summary_${this.getMonthYearLabel().replace(/ /g, '_')}_${new Date().toISOString().split('T')[0]}.xls`;
break; break;
case 'rm': case 'rm':
gridData = this.state.rmData; gridData = this.state.rmData;
columns = this.getRMGridColumns(); columns = this.getRMGridColumns();
sheetName = 'Raw Material Availability'; sheetName = 'Raw Material Availability';
filename = `RM_Availability_${this.getMonthYearLabel().replace(/ /g, '_')}_${new Date().toISOString().split('T')[0]}.xlsx`; filename = `RM_Availability_${this.getMonthYearLabel().replace(/ /g, '_')}_${new Date().toISOString().split('T')[0]}.xls`;
break; break;
case 'dpr': case 'dpr':
gridData = this.state.dprData; gridData = this.state.dprData;
columns = this.getDPRGridColumns(); columns = this.getDPRGridColumns();
sheetName = 'Daily Production Report'; sheetName = 'Daily Production Report';
filename = `DPR_${this.getMonthYearLabel().replace(/ /g, '_')}_${new Date().toISOString().split('T')[0]}.xlsx`; filename = `DPR_${this.getMonthYearLabel().replace(/ /g, '_')}_${new Date().toISOString().split('T')[0]}.xls`;
break; break;
default: default:
return; return;
@ -1618,7 +1644,7 @@ exportGrid(ev, type) {
// Generate HTML table with merged headers // Generate HTML table with merged headers
const table = this.generateMergedHeaderTable(gridData, columns, sheetName); const table = this.generateMergedHeaderTable(gridData, columns, sheetName);
// Convert to Excel // Convert to Excel (MS Excel compatible)
this.exportToExcel(table, filename, sheetName); this.exportToExcel(table, filename, sheetName);
} catch (error) { } catch (error) {
@ -1631,135 +1657,27 @@ exportGrid(ev, type) {
} }
// Generate HTML table with merged column headers // Generate HTML table with merged column headers
generateMergedHeaderTable(data, columns, sheetName) { // Format float for Excel
// First, analyze column structure to determine merge ranges formatFloatForExcel(value) {
const headerRows = this.buildHeaderRows(columns); if (value === null || value === undefined || isNaN(value)) return '0.00';
const flatColumns = this.flattenColumns(columns); return parseFloat(value).toFixed(2);
}
let html = '<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse; font-family: Arial, sans-serif; width: 100%;">'; // Format integer for Excel
formatIntegerForExcel(value) {
if (value === null || value === undefined || isNaN(value)) return '0';
return parseInt(value).toString();
}
// ==================== HEADER SECTION WITH MERGED CELLS ==================== // Escape HTML special characters
html += '<thead>'; escapeHtml(text) {
if (!text) return '';
// Generate multi-row header with merged cells return String(text)
for (let rowIdx = 0; rowIdx < headerRows.length; rowIdx++) { .replace(/&/g, '&amp;')
html += '<tr>'; .replace(/</g, '&lt;')
const row = headerRows[rowIdx]; .replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
for (let colIdx = 0; colIdx < row.length; colIdx++) { .replace(/'/g, '&#039;');
const cell = row[colIdx];
if (cell) {
// Skip if this cell was already merged (null in the array)
if (cell.colspan === 0) continue;
let colspan = cell.colspan || 1;
let rowspan = cell.rowspan || 1;
html += `<th colspan="${colspan}" rowspan="${rowspan}"
style="background-color: ${rowIdx === 0 ? '#2C3E50' : '#E3F2FD'};
color: ${rowIdx === 0 ? 'white' : 'black'};
font-weight: bold;
text-align: center;
padding: 10px;
border: 1px solid #000;
vertical-align: middle;
font-size: ${rowIdx === 0 ? '12px' : '11px'};
border-bottom: ${rowIdx === 0 ? '3px solid #1a252f' : '1px solid #000'};">${cell.title}</th>`;
}
}
html += '</tr>';
}
html += '</thead>';
// ==================== BODY SECTION ====================
html += '<tbody>';
// Data rows
data.forEach((row, index) => {
// Add zebra striping
const bgColor = index % 2 === 0 ? '#FFFFFF' : '#F8F9FA';
html += '<tr>';
flatColumns.forEach(col => {
let value = row[col.dataIndx];
let displayValue = '';
// Format value based on data type
if (value === null || value === undefined || value === '' || value === 0) {
displayValue = '';
} else if (col.dataType === 'float') {
displayValue = parseFloat(value).toLocaleString('en-US', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
} else if (col.dataType === 'integer') {
displayValue = parseInt(value).toLocaleString('en-US');
} else {
displayValue = value.toString();
}
const align = col.dataType === 'float' || col.dataType === 'integer' ? 'right' : 'left';
html += `<td style="text-align: ${align};
padding: 8px;
border: 1px solid #ddd;
background-color: ${bgColor};
white-space: nowrap;
width:100%;
${col.dataType === 'float' || col.dataType === 'integer' ? 'font-family: Arial, sans-serif;' : ''}">${displayValue}</td>`;
});
html += '</tr>';
});
// ==================== SUMMARY SECTION WITH MERGED CELL ====================
html += '<tfoot>';
// Calculate totals for numeric columns
const totals = {};
flatColumns.forEach(col => {
if (col.dataType === 'float' || col.dataType === 'integer') {
totals[col.dataIndx] = 0;
data.forEach(row => {
totals[col.dataIndx] += parseFloat(row[col.dataIndx]) || 0;
});
}
});
// Grand Total row with merged first cell
html += '<tr>';
html += `<td colspan="1" style="font-weight: bold;
background-color: #2C3E50;
color: white;
text-align: left;
padding: 10px;
border: 1px solid #000;
font-size: 12px;">GRAND TOTAL</td>`;
// Add totals for remaining columns
for (let i = 1; i < flatColumns.length; i++) {
const col = flatColumns[i];
if (col.dataType === 'float' || col.dataType === 'integer') {
let total = totals[col.dataIndx] || 0;
let formattedTotal = col.dataType === 'float'
? total.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
: total.toLocaleString('en-US');
html += `<td style="font-weight: bold;
background-color: #2C3E50;
color: white;
text-align: right;
padding: 10px;
border: 1px solid #000;
font-family: Arial, sans-serif;">${formattedTotal}</td>`;
} else {
html += `<td style="background-color: #2C3E50;
border: 1px solid #000;"></td>`;
}
}
html += '</tr>';
html += '</tfoot>';
html += '</tbody></table>';
return html;
} }
// Build multi-row header structure with merge information // Build multi-row header structure with merge information
@ -1854,7 +1772,7 @@ flattenColumns(columns) {
flatColumns.push({ flatColumns.push({
dataIndx: col.dataIndx, dataIndx: col.dataIndx,
title: parentTitle ? `${parentTitle} - ${col.title}` : col.title, title: parentTitle ? `${parentTitle} - ${col.title}` : col.title,
width: col.dataIndx === 'product'? 600 : (col.width || 100), width: col.dataIndx === 'product' ? 500 : (col.width || 100),
align: col.align || 'left', align: col.align || 'left',
dataType: col.dataType || 'string' dataType: col.dataType || 'string'
}); });
@ -1866,41 +1784,177 @@ flattenColumns(columns) {
return flatColumns; return flatColumns;
} }
// Export to Excel // Export to Excel (MS Excel compatible) - Gray and White Theme, Arial font, Frozen Header, Fit to Text
exportToExcel(htmlTable, filename, sheetName) { exportToExcel(htmlTable, filename, sheetName) {
// Calculate header rows depth from the table
const headerDepth = (htmlTable.match(/<thead>[\s\S]*?<\/thead>/) || [''])[0];
const headerRowCount = (headerDepth.match(/<tr>/g) || []).length;
// MS Excel specific XML format
const excelContent = ` const excelContent = `
<html xmlns:o="urn:schemas-microsoft-com:office:office" <html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns="http://www.w3.org/TR/REC-html40"> xmlns="http://www.w3.org/TR/REC-html40">
<head> <head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="ProgId" content="Excel.Sheet"> <meta name="ProgId" content="Excel.Sheet">
<meta name="Generator" content="Odoo Excel Export"> <meta name="Generator" content="Odoo Excel Export">
<xml>
<x:ExcelWorkbook>
<x:ExcelWorksheets>
<x:ExcelWorksheet>
<x:Name>${this.escapeHtml(sheetName)}</x:Name>
<x:WorksheetOptions>
<x:DisplayGridlines/>
<x:Zoom>90</x:Zoom>
<x:Selected/>
<x:FreezePanes/>
<x:FrozenNoSplit/>
<x:SplitHorizontal>${6}</x:SplitHorizontal>
<x:TopRowBottomPane>${headerRowCount}</x:TopRowBottomPane>
<x:ProtectContents>False</x:ProtectContents>
<x:ProtectObjects>False</x:ProtectObjects>
<x:ProtectScenarios>False</x:ProtectScenarios>
</x:WorksheetOptions>
</x:ExcelWorksheet>
</x:ExcelWorksheets>
<x:WindowHeight>9000</x:WindowHeight>
<x:WindowWidth>13860</x:WindowWidth>
<x:WindowTopX>0</x:WindowTopX>
<x:WindowTopY>0</x:WindowTopY>
<x:ProtectStructure>False</x:ProtectStructure>
<x:ProtectWindows>False</x:ProtectWindows>
</x:ExcelWorkbook>
</xml>
<style> <style>
table { border-collapse: collapse; width: 100%; } body {
th { vertical-align: middle; } font-family: Calibri;
td { vertical-align: middle; } margin: 20px;
.grand-total { font-weight: bold; background-color: #2C3E50; color: white; } background-color: #FFFFFF;
}
table {
border-collapse: collapse;
width: 100%;
font-family: Calibri;
font-size: 10pt;
background-color: #FFFFFF;
table-layout: auto;
}
th {
background-color: #E0E0E0;
color: #000000;
font-weight: bold;
text-align: center;
padding: 8px;
border: 1px solid #808080;
font-size: 11pt;
font-family: Calibri;
white-space: nowrap;
}
td {
padding: 6px;
border: 1px solid #CCCCCC;
font-size: 10pt;
font-family: Calibri;
background-color: #FFFFFF;
white-space: nowrap;
}
td.product-cell {
white-space: normal;
min-width: 300px;
max-width: 500px;
word-wrap: break-word;
}
.header-main {
background-color: #C0C0C0;
color: #000000;
font-weight: bold;
border-bottom: 2px solid #404040;
}
.header-sub {
background-color: #E0E0E0;
color: #000000;
font-weight: bold;
}
.grand-total {
font-weight: bold;
background-color: #D3D3D3;
color: #000000;
border-top: 2px solid #404040;
}
.total-label {
background-color: #D3D3D3;
color: #000000;
font-weight: bold;
text-align: left;
}
.total-value {
background-color: #D3D3D3;
color: #000000;
font-weight: bold;
text-align: right;
}
.row-even {
background-color: #FFFFFF;
}
.row-odd {
background-color: #F8F8F8;
}
h2 {
color: #333333;
font-family: Calibri;
font-size: 16pt;
font-weight: bold;
border-bottom: 2px solid #808080;
padding-bottom: 8px;
}
h3 {
color: #666666;
font-family: Calibri;
font-size: 11pt;
font-weight: normal;
}
.footer-note {
color: #666666;
font-size: 9pt;
font-style: italic;
margin-top: 20px;
border-top: 1px solid #CCCCCC;
padding-top: 10px;
}
</style> </style>
</head> </head>
<body> <body>
<h2 style="color: #2C3E50; font-family: Arial, sans-serif; margin-bottom: 5px;">${sheetName}</h2> <table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color: #FFFFFF; font-family: Calibri;">
<h3 style="color: #666; font-family: Arial, sans-serif; margin-top: 0; margin-bottom: 20px; font-weight: normal;"> <tr>
${this.getMonthYearLabel()} | Exported on: ${new Date().toLocaleString()} <td style="font-family: Calibri; padding-bottom: 15px;">
</h3> <h2>${this.escapeHtml(sheetName)}</h2>
${htmlTable} <h3>
<p style="margin-top: 20px; font-family: Arial, sans-serif; color: #666; font-size: 10px;"> ${this.escapeHtml(this.getMonthYearLabel())} | Exported on: ${new Date().toLocaleString()}
* All quantities are in bags unless specified otherwise </h3>
</p> </td>
</tr>
<tr>
<td>
${htmlTable}
</td>
</tr>
<tr>
<td class="footer-note" style="font-family: Calibri;">
* All quantities are in bags unless specified otherwise
</td>
</tr>
</table>
</body> </body>
</html> </html>
`; `;
// Create blob with proper MIME type for MS Excel
const blob = new Blob([excelContent], { const blob = new Blob([excelContent], {
type: 'application/vnd.ms-excel' type: 'application/vnd.ms-excel; charset=UTF-8'
}); });
// Download file
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
const a = document.createElement('a'); const a = document.createElement('a');
a.href = url; a.href = url;
@ -1916,7 +1970,191 @@ exportToExcel(htmlTable, filename, sheetName) {
}); });
} }
// Helper methods for export buttons // Generate HTML table with merged column headers - Arial font, Auto width, Frozen Header
generateMergedHeaderTable(data, columns, sheetName) {
// First, analyze column structure to determine merge ranges
const headerRows = this.buildHeaderRows(columns);
const flatColumns = this.flattenColumns(columns);
let html = '<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse; font-family: Calibri; width: 100%; background-color: #FFFFFF; table-layout: auto;">';
// ==================== COLUMN WIDTHS - AUTO FIT ====================
html += '<colgroup>';
flatColumns.forEach(col => {
// Don't set fixed widths - let Excel auto-fit
html += `<col style="width: auto;">`;
});
html += '</colgroup>';
// ==================== HEADER SECTION WITH MERGED CELLS ====================
html += '<thead>';
// Generate multi-row header with merged cells
for (let rowIdx = 0; rowIdx < headerRows.length; rowIdx++) {
html += '<tr>';
const row = headerRows[rowIdx];
const headerClass = rowIdx === 0 ? 'header-main' : 'header-sub';
for (let colIdx = 0; colIdx < row.length; colIdx++) {
const cell = row[colIdx];
if (cell) {
// Skip if this cell was already merged
if (cell.colspan === 0) continue;
let colspan = cell.colspan || 1;
let rowspan = cell.rowspan || 1;
html += `<th colspan="${colspan}" rowspan="${rowspan}"
class="${headerClass}"
style="background-color: ${rowIdx === 0 ? '#C0C0C0' : '#E0E0E0'};
color: #000000;
font-weight: bold;
text-align: center;
padding: 8px 12px;
border: 1px solid #808080;
border-bottom: ${rowIdx === 0 ? '2px solid #404040' : '1px solid #808080'};
vertical-align: middle;
font-size: ${rowIdx === 0 ? '11pt' : '10pt'};
font-family: Calibri;
white-space: nowrap;">${this.escapeHtml(cell.title || '')}</th>`;
}
}
html += '</tr>';
}
html += '</thead>';
// ==================== BODY SECTION ====================
html += '<tbody>';
// Data rows
data.forEach((row, index) => {
// Add zebra striping - subtle gray
const bgColor = index % 2 === 0 ? '#FFFFFF' : '#F8F8F8';
const rowClass = index % 2 === 0 ? 'row-even' : 'row-odd';
html += `<tr class="${rowClass}" style="font-family: Calibri;">`;
flatColumns.forEach(col => {
let value = row[col.dataIndx];
let displayValue = '';
// Format value based on data type
if (value === null || value === undefined || value === '' || value === 0) {
displayValue = '';
} else if (col.dataType === 'float') {
displayValue = this.formatFloatForExcel(value);
} else if (col.dataType === 'integer') {
displayValue = this.formatIntegerForExcel(value);
} else {
displayValue = this.escapeHtml(value.toString());
}
const align = col.dataType === 'float' || col.dataType === 'integer' ? 'right' : 'left';
const isProduct = col.dataIndx === 'product' || col.title?.toLowerCase().includes('product');
// Determine if this is a date column (format: YYYY-MM-DD or day_*)
const isDateColumn = col.dataIndx?.match(/^\d{4}-\d{2}-\d{2}$/) || col.dataIndx?.startsWith('day_');
let cellStyle = `text-align: ${align};
padding: 6px 10px;
border: 1px solid #CCCCCC;
background-color: ${bgColor};
font-family: Calibri;
font-size: 10pt;
color: #333333;`;
// Product columns - wrap text, auto width
if (isProduct) {
cellStyle += ` white-space: normal;
min-width: 300px;
max-width: 500px;
word-wrap: break-word;`;
}
// Date columns - fixed width, center aligned
else if (isDateColumn) {
cellStyle += ` white-space: nowrap;
text-align: center;
min-width: 80px;`;
}
// Numeric columns - right aligned, monospace numbers
else if (col.dataType === 'float' || col.dataType === 'integer') {
cellStyle += ` white-space: nowrap;
mso-number-format:\\#\\,\\#\\#0\\.00;`;
}
// Other text columns - nowrap by default
else {
cellStyle += ` white-space: nowrap;`;
}
html += `<td style="${cellStyle}">${displayValue}</td>`;
});
html += '</tr>';
});
// ==================== SUMMARY SECTION WITH MERGED CELL ====================
html += '<tfoot>';
// Calculate totals for numeric columns
const totals = {};
flatColumns.forEach(col => {
if (col.dataType === 'float' || col.dataType === 'integer') {
totals[col.dataIndx] = 0;
data.forEach(row => {
totals[col.dataIndx] += parseFloat(row[col.dataIndx]) || 0;
});
}
});
// Grand Total row with merged first cell
html += '<tr>';
html += `<td colspan="1" class="total-label"
style="font-weight: bold;
background-color: #D3D3D3;
color: #000000;
text-align: left;
padding: 8px 12px;
border: 1px solid #808080;
border-top: 2px solid #404040;
font-size: 11pt;
font-family: Calibri;
white-space: nowrap;">GRAND TOTAL</td>`;
// Add totals for remaining columns
for (let i = 1; i < flatColumns.length; i++) {
const col = flatColumns[i];
if (col.dataType === 'float' || col.dataType === 'integer') {
let total = totals[col.dataIndx] || 0;
let formattedTotal = col.dataType === 'float'
? this.formatFloatForExcel(total)
: this.formatIntegerForExcel(total);
html += `<td style="font-weight: bold;
background-color: #D3D3D3;
color: #000000;
text-align: right;
padding: 8px 12px;
border: 1px solid #808080;
border-top: 2px solid #404040;
font-family: Calibri;
font-size: 11pt;
white-space: nowrap;
mso-number-format:\\#\\,\\#\\#0\\.00;">${formattedTotal}</td>`;
} else {
html += `<td style="background-color: #D3D3D3;
border: 1px solid #808080;
border-top: 2px solid #404040;
font-family: Calibri;"></td>`;
}
}
html += '</tr>';
html += '</tfoot>';
html += '</tbody></table>';
return html;
}
// Flatten nested columns - with auto width
exportOrderGrid(ev) { exportOrderGrid(ev) {
this.exportGrid(ev, 'order'); this.exportGrid(ev, 'order');
} }
@ -1932,7 +2170,6 @@ exportRMGrid(ev) {
exportDPRGrid(ev) { exportDPRGrid(ev) {
this.exportGrid(ev, 'dpr'); this.exportGrid(ev, 'dpr');
} }
// ==================== // ====================
// TAB EVENT HANDLER // TAB EVENT HANDLER
// ==================== // ====================