mirror of
https://github.com/frappe/books.git
synced 2024-12-23 11:29:03 +00:00
Merge pull request #424 from frappe/minor-fixes-two
fix: a bunch of minor issues
This commit is contained in:
commit
8c7088d752
@ -394,7 +394,7 @@ export class Doc extends Observable<DocValue | Doc[]> {
|
||||
}
|
||||
|
||||
if (filterComputed) {
|
||||
fields = this.schema.fields.filter((f) => !f.computed);
|
||||
fields = fields.filter((f) => !f.computed);
|
||||
}
|
||||
|
||||
const data: DocValueMap = {};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { app, dialog, ipcMain } from 'electron';
|
||||
import { autoUpdater } from 'electron-updater';
|
||||
import { autoUpdater, UpdateInfo } from 'electron-updater';
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import databaseManager from '../backend/database/manager';
|
||||
@ -15,6 +15,40 @@ import {
|
||||
} from './helpers';
|
||||
import { saveHtmlAsPdf } from './saveHtmlAsPdf';
|
||||
|
||||
autoUpdater.autoDownload = false;
|
||||
|
||||
autoUpdater.on('error', (error) => {
|
||||
dialog.showErrorBox(
|
||||
'Update Error: ',
|
||||
error == null ? 'unknown' : (error.stack || error).toString()
|
||||
);
|
||||
});
|
||||
|
||||
autoUpdater.on('update-available', async (info: UpdateInfo) => {
|
||||
const currentVersion = app.getVersion();
|
||||
const nextVersion = info.version;
|
||||
const isCurrentBeta = currentVersion.includes('beta');
|
||||
const isNextBeta = nextVersion.includes('beta');
|
||||
|
||||
let downloadUpdate = true;
|
||||
if (!isCurrentBeta && isNextBeta) {
|
||||
const option = await dialog.showMessageBox({
|
||||
type: 'info',
|
||||
title: `Update Frappe Books?`,
|
||||
message: `Download version ${nextVersion}?`,
|
||||
buttons: ['Yes', 'No'],
|
||||
});
|
||||
|
||||
downloadUpdate = option.response === 0;
|
||||
}
|
||||
|
||||
if (!downloadUpdate) {
|
||||
return;
|
||||
}
|
||||
|
||||
await autoUpdater.downloadUpdate();
|
||||
});
|
||||
|
||||
export default function registerIpcMainActionListeners(main: Main) {
|
||||
ipcMain.handle(IPC_ACTIONS.GET_OPEN_FILEPATH, async (event, options) => {
|
||||
return await dialog.showOpenDialog(main.mainWindow!, options);
|
||||
@ -51,9 +85,9 @@ export default function registerIpcMainActionListeners(main: Main) {
|
||||
sendError(bodyJson);
|
||||
});
|
||||
|
||||
ipcMain.handle(IPC_ACTIONS.CHECK_FOR_UPDATES, () => {
|
||||
ipcMain.handle(IPC_ACTIONS.CHECK_FOR_UPDATES, async () => {
|
||||
if (!main.isDevelopment && !main.checkedForUpdate) {
|
||||
autoUpdater.checkForUpdates();
|
||||
await autoUpdater.checkForUpdates();
|
||||
main.checkedForUpdate = true;
|
||||
}
|
||||
});
|
||||
|
@ -539,7 +539,9 @@ function pruneAccountTree(accountTree: AccountTree) {
|
||||
}
|
||||
|
||||
for (const root of Object.keys(accountTree)) {
|
||||
accountTree[root].children = getPrunedChildren(accountTree[root].children!);
|
||||
accountTree[root].children = getPrunedChildren(
|
||||
accountTree[root].children ?? []
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,21 +74,65 @@ export class ProfitAndLoss extends AccountReport {
|
||||
async getReportDataFromRows(
|
||||
incomeRows: ReportData,
|
||||
expenseRows: ReportData,
|
||||
incomeRoot: AccountTreeNode,
|
||||
expenseRoot: AccountTreeNode
|
||||
incomeRoot: AccountTreeNode | undefined,
|
||||
expenseRoot: AccountTreeNode | undefined
|
||||
): Promise<ReportData> {
|
||||
if (incomeRoot && !expenseRoot) {
|
||||
return await this.getIncomeOrExpenseRows(
|
||||
incomeRoot,
|
||||
incomeRows,
|
||||
t`Total Income (Credit)`
|
||||
);
|
||||
}
|
||||
|
||||
if (expenseRoot && !incomeRoot) {
|
||||
return await this.getIncomeOrExpenseRows(
|
||||
expenseRoot,
|
||||
expenseRows,
|
||||
t`Total Income (Credit)`
|
||||
);
|
||||
}
|
||||
|
||||
if (!incomeRoot || !expenseRoot) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return await this.getIncomeAndExpenseRows(
|
||||
incomeRows,
|
||||
expenseRows,
|
||||
incomeRoot,
|
||||
expenseRoot
|
||||
);
|
||||
}
|
||||
|
||||
async getIncomeOrExpenseRows(
|
||||
root: AccountTreeNode,
|
||||
rows: ReportData,
|
||||
totalRowName: string
|
||||
): Promise<ReportData> {
|
||||
const total = await this.getTotalNode(root, totalRowName);
|
||||
const totalRow = this.getRowFromAccountListNode(total);
|
||||
|
||||
return [rows, totalRow].flat();
|
||||
}
|
||||
|
||||
async getIncomeAndExpenseRows(
|
||||
incomeRows: ReportData,
|
||||
expenseRows: ReportData,
|
||||
incomeRoot: AccountTreeNode,
|
||||
expenseRoot: AccountTreeNode
|
||||
) {
|
||||
const totalIncome = await this.getTotalNode(
|
||||
incomeRoot,
|
||||
t`Total Income (Credit)`
|
||||
);
|
||||
const totalIncomeRow = this.getRowFromAccountListNode(totalIncome);
|
||||
|
||||
const totalExpense = await this.getTotalNode(
|
||||
expenseRoot,
|
||||
t`Total Expense (Debit)`
|
||||
);
|
||||
const totalExpenseRow = this.getRowFromAccountListNode(totalExpense);
|
||||
|
||||
const totalValueMap: ValueMap = new Map();
|
||||
for (const key of totalIncome.valueMap!.keys()) {
|
||||
@ -103,9 +147,6 @@ export class ProfitAndLoss extends AccountReport {
|
||||
level: 0,
|
||||
} as AccountListNode;
|
||||
|
||||
const totalIncomeRow = this.getRowFromAccountListNode(totalIncome);
|
||||
const totalExpenseRow = this.getRowFromAccountListNode(totalExpense);
|
||||
|
||||
const totalProfitRow = this.getRowFromAccountListNode(totalProfit);
|
||||
totalProfitRow.cells.forEach((c) => {
|
||||
c.bold = true;
|
||||
|
@ -175,7 +175,6 @@ export default {
|
||||
this.filters = this.filters.filter((f) => f !== filter);
|
||||
},
|
||||
setFilter(filters, implicit) {
|
||||
console.log(filters);
|
||||
this.filters = [];
|
||||
|
||||
Object.keys(filters).map((fieldname) => {
|
||||
|
@ -1,15 +1,10 @@
|
||||
<template>
|
||||
<div
|
||||
class="
|
||||
px-4
|
||||
flex
|
||||
justify-between
|
||||
window-drag
|
||||
items-center
|
||||
h-row-largest
|
||||
flex-shrink-0
|
||||
"
|
||||
:class="border ? 'border-b' : ''"
|
||||
class="px-4 flex justify-between items-center h-row-largest flex-shrink-0"
|
||||
:class="[
|
||||
border ? 'border-b' : '',
|
||||
platform !== 'Windows' ? 'window-drag' : '',
|
||||
]"
|
||||
>
|
||||
<h1 class="text-xl font-semibold select-none" v-if="title">
|
||||
{{ title }}
|
||||
|
@ -121,9 +121,11 @@ export default {
|
||||
},
|
||||
setActiveTab() {
|
||||
const { tab } = this.$route.query;
|
||||
const index = this.tabs.findIndex((i) => i.key === tab || 'Invoice');
|
||||
const index = this.tabs.findIndex((i) => i.key === tab);
|
||||
if (index !== -1) {
|
||||
this.activeTab = index;
|
||||
} else {
|
||||
this.activeTab = 0;
|
||||
}
|
||||
},
|
||||
getIconComponent(tab) {
|
||||
|
@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<div class="flex-1 bg-gray-25 flex justify-center items-center window-drag">
|
||||
<div
|
||||
class="flex-1 bg-gray-25 flex justify-center items-center window-drag"
|
||||
:class="{ 'window-drag': platform !== 'Windows' }"
|
||||
>
|
||||
<!-- Setup Wizard Slide -->
|
||||
<Slide
|
||||
:primary-disabled="!valuesFilled || loading"
|
||||
|
@ -1,35 +1,39 @@
|
||||
import { Directive } from 'vue';
|
||||
|
||||
const instances: OutsideClickCallback[] = [];
|
||||
type OutsideClickCallback = (e: Event) => void;
|
||||
const instanceMap: Map<HTMLElement, OutsideClickCallback> = new Map();
|
||||
|
||||
export const outsideClickDirective: Directive<
|
||||
HTMLElement,
|
||||
OutsideClickCallback
|
||||
> = {
|
||||
beforeMount(el, binding) {
|
||||
el.dataset.outsideClickIndex = String(instances.length);
|
||||
|
||||
const fn = binding.value;
|
||||
const click = function (e: Event) {
|
||||
onDocumentClick(e, el, fn);
|
||||
const clickHandler = function (e: Event) {
|
||||
onDocumentClick(e, el, binding.value);
|
||||
};
|
||||
|
||||
document.addEventListener('click', click);
|
||||
instances.push(click);
|
||||
removeHandlerIfPresent(el);
|
||||
instanceMap.set(el, clickHandler);
|
||||
document.addEventListener('click', clickHandler);
|
||||
},
|
||||
unmounted(el) {
|
||||
const index = parseInt(el.dataset.outsideClickIndex ?? '0');
|
||||
const handler = instances[index];
|
||||
document.addEventListener('click', handler);
|
||||
instances.splice(index, 1);
|
||||
removeHandlerIfPresent(el);
|
||||
},
|
||||
};
|
||||
|
||||
function onDocumentClick(e: Event, el: HTMLElement, fn: OutsideClickCallback) {
|
||||
const target = e.target;
|
||||
|
||||
if (el !== target && !el.contains(target as Node)) {
|
||||
fn(e);
|
||||
const target = e.target as Node;
|
||||
if (el !== target && !el.contains(target)) {
|
||||
fn?.(e);
|
||||
}
|
||||
}
|
||||
|
||||
function removeHandlerIfPresent(el: HTMLElement) {
|
||||
const clickHandler = instanceMap.get(el);
|
||||
if (!clickHandler) {
|
||||
return;
|
||||
}
|
||||
|
||||
instanceMap.delete(el);
|
||||
document.removeEventListener('click', clickHandler);
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ export function getGetStartedConfig() {
|
||||
key: 'Add Customers',
|
||||
label: t`Add Customers`,
|
||||
icon: 'customer',
|
||||
description: t`Add a few customers to create your first invoice`,
|
||||
description: t`Add a few customers to create your first sales invoice`,
|
||||
action: () => routeTo(`/list/Party/role/Customer/${t`Customers`}`),
|
||||
fieldname: 'customerCreated',
|
||||
documentation:
|
||||
@ -104,7 +104,7 @@ export function getGetStartedConfig() {
|
||||
key: 'Create Sales Invoice',
|
||||
label: t`Create Sales Invoice`,
|
||||
icon: 'sales-invoice',
|
||||
description: t`Create your first invoice and mail it to your customer`,
|
||||
description: t`Create your first sales invoice for the created customer`,
|
||||
action: () => routeTo('/list/SalesInvoice'),
|
||||
fieldname: 'invoiceCreated',
|
||||
documentation:
|
||||
@ -129,7 +129,7 @@ export function getGetStartedConfig() {
|
||||
key: 'Add Suppliers',
|
||||
label: t`Add Suppliers`,
|
||||
icon: 'supplier',
|
||||
description: t`Add a few suppliers to create your first bill`,
|
||||
description: t`Add a few suppliers to create your first purchase invoice`,
|
||||
action: () => routeTo(`/list/Party/role/Supplier/${t`Suppliers`}`),
|
||||
fieldname: 'supplierCreated',
|
||||
},
|
||||
@ -137,7 +137,7 @@ export function getGetStartedConfig() {
|
||||
key: 'Create Purchase Invoice',
|
||||
label: t`Create Purchase Invoice`,
|
||||
icon: 'purchase-invoice',
|
||||
description: t`Create your first bill and mail it to your supplier`,
|
||||
description: t`Create your first purchase invoice from the created supplier`,
|
||||
action: () => routeTo('/list/PurchaseInvoice'),
|
||||
fieldname: 'billCreated',
|
||||
documentation:
|
||||
|
Loading…
Reference in New Issue
Block a user