2
0
mirror of https://github.com/frappe/books.git synced 2024-12-26 20:30:25 +00:00
books/src/utils.js

290 lines
7.1 KiB
JavaScript
Raw Normal View History

2019-12-03 08:15:12 +00:00
import frappe from 'frappejs';
import fs from 'fs';
import { _ } from 'frappejs/utils';
2020-01-28 11:10:01 +00:00
import migrate from './migrate';
2020-01-02 17:06:57 +00:00
import { remote, shell, ipcRenderer } from 'electron';
import SQLite from 'frappejs/backends/sqlite';
import postStart from '../server/postStart';
import router from '@/router';
import Avatar from '@/components/Avatar';
import config from '@/config';
export function createNewDatabase() {
return new Promise(resolve => {
remote.dialog.showSaveDialog(
remote.getCurrentWindow(),
{
title: _('Select folder'),
2020-01-02 17:36:00 +00:00
defaultPath: 'frappe-books.db'
},
filePath => {
if (filePath) {
if (!filePath.endsWith('.db')) {
filePath = filePath + '.db';
}
if (fs.existsSync(filePath)) {
showMessageDialog({
// prettier-ignore
message: _('A file exists with the same name and it will be overwritten. Are you sure you want to continue?'),
buttons: [
{
label: _('Overwrite'),
action() {
fs.unlinkSync(filePath);
resolve(filePath);
}
},
{ label: _('Cancel'), action() {} }
]
});
} else {
resolve(filePath);
}
}
}
);
});
}
export function loadExistingDatabase() {
return new Promise(resolve => {
remote.dialog.showOpenDialog(
remote.getCurrentWindow(),
{
title: _('Select file'),
properties: ['openFile'],
filters: [{ name: 'SQLite DB File', extensions: ['db'] }]
},
files => {
if (files && files[0]) {
resolve(files[0]);
}
}
);
});
}
export async function connectToLocalDatabase(filepath) {
frappe.login('Administrator');
frappe.db = new SQLite({
dbPath: filepath
});
await frappe.db.connect();
2020-01-28 11:10:01 +00:00
await migrate();
await postStart();
// set file info in config
let files = config.get('files') || [];
if (!files.find(file => file.filePath === filepath)) {
files = [
{
companyName: frappe.AccountingSettings.companyName,
filePath: filepath
},
...files
];
config.set('files', files);
}
// set last selected file
config.set('lastSelectedFilePath', filepath);
}
2019-12-03 08:15:12 +00:00
export function showMessageDialog({ message, description, buttons = [] }) {
let buttonLabels = buttons.map(a => a.label);
remote.dialog.showMessageBox(
remote.getCurrentWindow(),
{
message,
detail: description,
buttons: buttonLabels
},
response => {
let button = buttons[response];
if (button && button.action) {
button.action();
}
}
);
}
2019-12-03 08:15:12 +00:00
export function deleteDocWithPrompt(doc) {
return new Promise(resolve => {
2019-12-03 08:15:12 +00:00
showMessageDialog({
message: _('Are you sure you want to delete {0} "{1}"?', [
doc.doctype,
doc.name
]),
description: _('This action is permanent'),
buttons: [
{
label: _('Delete'),
action: () => {
doc
.delete()
.then(() => resolve(true))
.catch(e => {
handleErrorWithDialog(e, doc);
2019-12-03 08:15:12 +00:00
});
}
},
{
label: _('Cancel'),
action() {
resolve(false);
}
}
]
});
});
}
export function partyWithAvatar(party) {
return {
data() {
return {
imageURL: null,
label: null
};
},
components: {
Avatar
},
async mounted() {
this.imageURL = await frappe.db.getValue('Party', party, 'image');
this.label = party;
},
template: `
<div class="flex items-center" v-if="label">
<Avatar class="flex-shrink-0" :imageURL="imageURL" :label="label" size="sm" />
<span class="ml-2 truncate">{{ label }}</span>
</div>
`
};
}
export function openQuickEdit({ doctype, name, hideFields, defaults = {} }) {
let currentRoute = router.currentRoute;
2019-12-04 17:26:17 +00:00
let query = currentRoute.query;
let method = 'push';
if (query.edit && query.doctype === doctype) {
// replace the current route if we are
// editing another document of the same doctype
method = 'replace';
}
router[method]({
query: {
edit: 1,
doctype,
name,
hideFields,
values: defaults,
lastRoute: currentRoute
}
});
}
2020-01-29 11:01:45 +00:00
export function getErrorMessage(e, doc) {
let errorMessage = e.message || _('An error occurred');
if (e.type === frappe.errors.LinkValidationError) {
errorMessage = _('{0} {1} is linked with existing records.', [
doc.doctype,
doc.name
]);
} else if (e.type === frappe.errors.DuplicateEntryError) {
errorMessage = _('{0} {1} already exists.', [doc.doctype, doc.name]);
}
2020-01-29 11:01:45 +00:00
return errorMessage;
}
2020-01-29 11:01:45 +00:00
export function handleErrorWithDialog(e, doc) {
let errorMessage = getErrorMessage(e, doc);
showMessageDialog({ message: errorMessage });
throw e;
}
export function makePDF(html, destination) {
const { BrowserWindow } = remote;
let printWindow = new BrowserWindow({
width: 595,
height: 842,
show: false,
webPreferences: {
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION
}
});
let webpackDevServerURL = remote.getGlobal('WEBPACK_DEV_SERVER_URL');
if (webpackDevServerURL) {
// Load the url of the dev server if in development mode
printWindow.loadURL(webpackDevServerURL + 'print');
} else {
// Load the index.html when not in development
printWindow.loadURL(`app://./print.html`);
}
printWindow.on('closed', () => {
printWindow = null;
});
const code = `
document.body.innerHTML = \`${html}\`;
`;
printWindow.webContents.executeJavaScript(code);
return new Promise(resolve => {
printWindow.webContents.on('did-finish-load', () => {
printWindow.webContents.printToPDF(
{
marginsType: 1, // no margin
pageSize: 'A4',
printBackground: true
},
(error, data) => {
if (error) throw error;
printWindow.close();
fs.writeFile(destination, data, error => {
if (error) throw error;
resolve(shell.openItem(destination));
});
}
);
});
});
}
export function getActionsForDocument(doc) {
if (!doc) return [];
let deleteAction = {
component: {
template: `<span class="text-red-700">{{ _('Delete') }}</span>`
},
condition: doc => !doc.isNew() && !doc.submitted && !doc.meta.isSingle,
action: () =>
deleteDocWithPrompt(doc).then(res => {
if (res) {
router.push(`/list/${doc.doctype}`);
}
})
};
let actions = [...(doc.meta.actions || []), deleteAction]
.filter(d => (d.condition ? d.condition(doc) : true))
.map(d => {
return {
label: d.label,
component: d.component,
action: d.action.bind(this, doc, router)
};
});
return actions;
}
2020-01-02 17:06:57 +00:00
export function openSettings(tab = 'General') {
ipcRenderer.send('open-settings-window', tab);
}