2021-12-21 09:05:24 +00:00
|
|
|
import frappe from 'frappejs';
|
2021-12-21 12:33:30 +00:00
|
|
|
import {
|
|
|
|
getSavePath,
|
|
|
|
saveData,
|
|
|
|
showItemInFolder,
|
|
|
|
showToast,
|
|
|
|
} from '../src/utils';
|
2021-12-21 08:37:06 +00:00
|
|
|
|
|
|
|
function templateToInnerText(innerHTML) {
|
|
|
|
const temp = document.createElement('template');
|
|
|
|
temp.innerHTML = innerHTML.trim();
|
|
|
|
return temp.content.firstChild.innerText;
|
|
|
|
}
|
|
|
|
|
2021-12-21 09:05:24 +00:00
|
|
|
function deObjectify(value) {
|
|
|
|
if (typeof value !== 'object') return value;
|
|
|
|
if (value === null) return '';
|
|
|
|
|
|
|
|
const innerHTML = value.template;
|
|
|
|
if (!innerHTML) return '';
|
|
|
|
return templateToInnerText(innerHTML);
|
|
|
|
}
|
|
|
|
|
2021-12-21 08:37:06 +00:00
|
|
|
function csvFormat(value) {
|
|
|
|
if (typeof value === 'string') {
|
|
|
|
return `"${value}"`;
|
|
|
|
} else if (value === null) {
|
|
|
|
return '';
|
|
|
|
} else if (typeof value === 'object') {
|
|
|
|
const innerHTML = value.template;
|
|
|
|
if (!innerHTML) return '';
|
2021-12-21 09:05:24 +00:00
|
|
|
return csvFormat(deObjectify(value));
|
2021-12-21 08:37:06 +00:00
|
|
|
}
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2021-12-21 09:05:24 +00:00
|
|
|
async function exportCsv(rows, columns, filePath) {
|
2021-12-21 08:37:06 +00:00
|
|
|
const fieldnames = columns.map(({ fieldname }) => fieldname);
|
|
|
|
const labels = columns.map(({ label }) => csvFormat(label));
|
|
|
|
const csvRows = [
|
|
|
|
labels.join(','),
|
|
|
|
...rows.map((row) => fieldnames.map((f) => csvFormat(row[f])).join(',')),
|
|
|
|
];
|
2021-12-21 12:33:30 +00:00
|
|
|
|
|
|
|
saveExportData(csvRows.join('\n'), filePath);
|
2021-12-21 08:37:06 +00:00
|
|
|
}
|
|
|
|
|
2021-12-21 09:05:24 +00:00
|
|
|
async function exportJson(rows, columns, filePath, filters, reportName) {
|
|
|
|
const exportObject = {};
|
|
|
|
const fieldnames = columns.map(({ fieldname }) => fieldname);
|
|
|
|
|
|
|
|
exportObject.columns = columns.map(({ fieldname, label }) => ({
|
|
|
|
fieldname,
|
|
|
|
label,
|
|
|
|
}));
|
|
|
|
|
|
|
|
exportObject.rows = rows.map((row) =>
|
|
|
|
fieldnames.reduce((acc, f) => {
|
|
|
|
acc[f] = deObjectify(row[f]);
|
|
|
|
return acc;
|
|
|
|
}, {})
|
|
|
|
);
|
2021-12-21 08:37:06 +00:00
|
|
|
|
2021-12-21 09:05:24 +00:00
|
|
|
exportObject.filters = Object.keys(filters)
|
|
|
|
.filter((name) => filters[name] !== null && filters[name] !== undefined)
|
|
|
|
.reduce((acc, name) => {
|
|
|
|
acc[name] = filters[name];
|
|
|
|
return acc;
|
|
|
|
}, {});
|
|
|
|
|
|
|
|
exportObject.timestamp = new Date().toISOString();
|
|
|
|
exportObject.reportName = reportName;
|
|
|
|
exportObject.softwareName = 'Frappe Books';
|
|
|
|
exportObject.softwareVersion = frappe.store.appVersion;
|
|
|
|
|
2021-12-21 12:33:30 +00:00
|
|
|
await saveExportData(JSON.stringify(exportObject), filePath);
|
2021-12-21 09:05:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async function exportReport(extention, reportName, getReportData) {
|
|
|
|
const { rows, columns, filters } = getReportData();
|
|
|
|
|
|
|
|
const { filePath, canceled } = await getSavePath(reportName, extention);
|
2021-12-21 08:37:06 +00:00
|
|
|
if (canceled || !filePath) return;
|
2021-12-21 09:05:24 +00:00
|
|
|
|
|
|
|
switch (extention) {
|
|
|
|
case 'csv':
|
|
|
|
await exportCsv(rows, columns, filePath);
|
|
|
|
return;
|
|
|
|
case 'json':
|
|
|
|
await exportJson(rows, columns, filePath, filters, reportName);
|
|
|
|
return;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
2021-12-21 08:37:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export default function getCommonExportActions(reportName) {
|
2021-12-21 09:05:24 +00:00
|
|
|
return ['csv', 'json'].map((ext) => ({
|
|
|
|
group: 'Export',
|
|
|
|
label: ext.toUpperCase(),
|
|
|
|
type: 'primary',
|
|
|
|
action: async (getReportData) =>
|
|
|
|
await exportReport(ext, reportName, getReportData),
|
|
|
|
}));
|
2021-12-21 08:37:06 +00:00
|
|
|
}
|
2021-12-21 12:33:30 +00:00
|
|
|
|
|
|
|
export async function saveExportData(data, filePath) {
|
|
|
|
await saveData(data, filePath);
|
|
|
|
showToast({
|
|
|
|
message: frappe._('Export Successful'),
|
|
|
|
actionText: frappe._('Open Folder'),
|
|
|
|
action: async () => {
|
|
|
|
await showItemInFolder(filePath);
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|