2019-12-21 20:16:50 +05:30
|
|
|
<template>
|
2019-12-23 18:21:04 +05:30
|
|
|
<div class="flex flex-col overflow-y-hidden">
|
2019-12-21 20:16:50 +05:30
|
|
|
<PageHeader>
|
|
|
|
<h1 slot="title" class="text-2xl font-bold">
|
|
|
|
{{ _('Setup your workspace') }}
|
|
|
|
</h1>
|
|
|
|
</PageHeader>
|
2019-12-23 18:21:04 +05:30
|
|
|
<div class="px-8">
|
2020-02-03 19:03:53 +05:30
|
|
|
<div class="border-t"></div>
|
2019-12-23 18:21:04 +05:30
|
|
|
</div>
|
2020-04-30 16:40:03 +05:30
|
|
|
<div class="flex-1 px-8 overflow-y-auto">
|
2019-12-23 18:21:04 +05:30
|
|
|
<div class="my-6" v-for="section in sections" :key="section.label">
|
2019-12-21 20:16:50 +05:30
|
|
|
<h2 class="font-medium">{{ section.label }}</h2>
|
2020-04-30 16:40:03 +05:30
|
|
|
<div class="flex mt-4 -mx-2">
|
2019-12-21 20:16:50 +05:30
|
|
|
<div
|
|
|
|
class="w-1/3 px-2"
|
|
|
|
v-for="item in section.items"
|
|
|
|
:key="item.label"
|
|
|
|
>
|
|
|
|
<div
|
2020-04-30 16:40:03 +05:30
|
|
|
class="flex flex-col justify-between h-full p-6 border rounded-lg cursor-pointer hover:shadow-md"
|
2020-01-02 22:40:18 +05:30
|
|
|
@mouseenter="() => (activeCard = item.key)"
|
|
|
|
@mouseleave="() => (activeCard = null)"
|
2019-12-21 20:16:50 +05:30
|
|
|
>
|
|
|
|
<div>
|
|
|
|
<component
|
2020-01-02 22:40:18 +05:30
|
|
|
v-show="activeCard !== item.key && !isCompleted(item)"
|
|
|
|
:is="getIconComponent(item)"
|
2019-12-21 20:16:50 +05:30
|
|
|
class="mb-4"
|
|
|
|
/>
|
2020-01-02 22:40:18 +05:30
|
|
|
<Icon
|
|
|
|
v-show="isCompleted(item)"
|
|
|
|
name="green-check"
|
|
|
|
size="24"
|
|
|
|
class="w-5 h-5 mb-4"
|
|
|
|
/>
|
2019-12-21 20:16:50 +05:30
|
|
|
<h3 class="font-medium">{{ item.label }}</h3>
|
|
|
|
<p class="mt-2 text-sm text-gray-800">
|
|
|
|
{{ item.description }}
|
|
|
|
</p>
|
|
|
|
</div>
|
2020-01-02 22:40:18 +05:30
|
|
|
<div
|
2020-04-30 16:40:03 +05:30
|
|
|
class="flex mt-2"
|
2020-01-02 22:40:18 +05:30
|
|
|
v-show="activeCard === item.key && !isCompleted(item)"
|
|
|
|
>
|
|
|
|
<Button
|
2020-04-30 16:40:03 +05:30
|
|
|
v-if="item.action"
|
2020-01-02 22:40:18 +05:30
|
|
|
class="leading-tight"
|
|
|
|
type="primary"
|
|
|
|
v-on="
|
|
|
|
item.action
|
|
|
|
? {
|
|
|
|
click: () => {
|
|
|
|
item.action();
|
|
|
|
activeCard = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
: null
|
|
|
|
"
|
|
|
|
>
|
2020-04-30 16:40:03 +05:30
|
|
|
<span class="text-base text-white">
|
|
|
|
{{ item.actionLabel || _('Setup') }}
|
2019-12-21 20:16:50 +05:30
|
|
|
</span>
|
|
|
|
</Button>
|
2020-04-30 16:40:03 +05:30
|
|
|
<Button
|
|
|
|
v-if="item.documentation"
|
|
|
|
class="leading-tight"
|
|
|
|
:class="{ 'ml-4': item.action }"
|
|
|
|
@click="visitLink(item.documentation)"
|
|
|
|
>
|
2019-12-21 20:16:50 +05:30
|
|
|
<span class="text-base">
|
|
|
|
{{ _('Documentation') }}
|
|
|
|
</span>
|
|
|
|
</Button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2020-01-02 22:40:18 +05:30
|
|
|
import frappe from 'frappejs';
|
|
|
|
import { _ } from 'frappejs/utils';
|
2019-12-21 20:16:50 +05:30
|
|
|
import PageHeader from '@/components/PageHeader';
|
|
|
|
import Icon from '@/components/Icon';
|
|
|
|
import Button from '@/components/Button';
|
2020-01-02 22:40:18 +05:30
|
|
|
import { openSettings } from '@/utils';
|
2019-12-21 20:16:50 +05:30
|
|
|
|
|
|
|
export default {
|
|
|
|
name: 'GetStarted',
|
|
|
|
components: {
|
|
|
|
PageHeader,
|
2020-01-02 22:40:18 +05:30
|
|
|
Button,
|
|
|
|
Icon
|
2019-12-21 20:16:50 +05:30
|
|
|
},
|
2020-01-02 22:40:18 +05:30
|
|
|
computed: {
|
|
|
|
sections() {
|
|
|
|
/* eslint-disable vue/no-side-effects-in-computed-properties */
|
|
|
|
return [
|
2019-12-21 20:16:50 +05:30
|
|
|
{
|
2020-01-02 22:40:18 +05:30
|
|
|
label: _('Organisation'),
|
2019-12-21 20:16:50 +05:30
|
|
|
|
|
|
|
items: [
|
|
|
|
{
|
2020-01-02 22:40:18 +05:30
|
|
|
key: 'General',
|
|
|
|
label: _('General'),
|
2019-12-21 20:16:50 +05:30
|
|
|
icon: 'general',
|
|
|
|
description:
|
|
|
|
'Setup your company information, email, country and fiscal year',
|
2020-01-02 22:40:18 +05:30
|
|
|
fieldname: 'companySetup'
|
2019-12-21 20:16:50 +05:30
|
|
|
},
|
|
|
|
{
|
2020-01-02 22:40:18 +05:30
|
|
|
key: 'System',
|
|
|
|
label: _('System'),
|
2019-12-21 20:16:50 +05:30
|
|
|
icon: 'general',
|
|
|
|
description:
|
|
|
|
'Setup system defaults like date format and currency precision',
|
2020-01-02 22:40:18 +05:30
|
|
|
fieldname: 'systemSetup',
|
|
|
|
action() {
|
|
|
|
openSettings('System');
|
|
|
|
}
|
2019-12-21 20:16:50 +05:30
|
|
|
},
|
|
|
|
{
|
2020-01-02 22:40:18 +05:30
|
|
|
key: 'Invoice',
|
|
|
|
label: _('Invoice'),
|
2019-12-21 20:16:50 +05:30
|
|
|
icon: 'invoice',
|
|
|
|
description:
|
2020-01-02 22:40:18 +05:30
|
|
|
'Customize your invoices by adding a logo and address details',
|
|
|
|
fieldname: 'invoiceSetup',
|
|
|
|
action() {
|
|
|
|
openSettings('Invoice');
|
|
|
|
}
|
2019-12-21 20:16:50 +05:30
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
2020-01-02 22:40:18 +05:30
|
|
|
label: _('Accounts'),
|
2019-12-21 20:16:50 +05:30
|
|
|
|
|
|
|
items: [
|
|
|
|
{
|
2020-01-02 22:40:18 +05:30
|
|
|
key: 'Review Accounts',
|
|
|
|
label: _('Review Accounts'),
|
2019-12-21 20:16:50 +05:30
|
|
|
icon: 'review-ac',
|
|
|
|
description:
|
|
|
|
'Review your chart of accounts, add any account or tax heads as needed',
|
2020-04-30 16:40:03 +05:30
|
|
|
action: () => {
|
|
|
|
this.$router.push('/chart-of-accounts');
|
|
|
|
this.updateChecks({ chartOfAccountsReviewed: 1 });
|
|
|
|
},
|
|
|
|
fieldname: 'chartOfAccountsReviewed',
|
|
|
|
documentation:
|
|
|
|
'https://frappebooks.com/docs/setting-up#1-enter-bank-accounts'
|
2019-12-21 20:16:50 +05:30
|
|
|
},
|
|
|
|
{
|
2020-01-02 22:40:18 +05:30
|
|
|
key: 'Opening Balances',
|
|
|
|
label: _('Opening Balances'),
|
2019-12-21 20:16:50 +05:30
|
|
|
icon: 'opening-ac',
|
|
|
|
description:
|
2020-04-30 16:40:03 +05:30
|
|
|
'Setup your opening balances before performing any accounting entries',
|
|
|
|
documentation:
|
|
|
|
'https://frappebooks.com/docs/setting-up#5-setup-opening-balances'
|
2019-12-21 20:16:50 +05:30
|
|
|
},
|
|
|
|
{
|
2020-01-02 22:40:18 +05:30
|
|
|
key: 'Add Taxes',
|
|
|
|
label: _('Add Taxes'),
|
2019-12-21 20:16:50 +05:30
|
|
|
icon: 'percentage',
|
|
|
|
description:
|
|
|
|
'Setup your tax templates for your sales or purchase transactions',
|
2020-04-30 16:40:03 +05:30
|
|
|
action: () => this.$router.push('/list/Tax'),
|
|
|
|
documentation:
|
|
|
|
'https://frappebooks.com/docs/setting-up#2-add-taxes'
|
2019-12-21 20:16:50 +05:30
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
2020-01-02 22:40:18 +05:30
|
|
|
label: _('Sales'),
|
2019-12-21 20:16:50 +05:30
|
|
|
|
|
|
|
items: [
|
|
|
|
{
|
2020-01-02 22:40:18 +05:30
|
|
|
key: 'Add Sales Items',
|
|
|
|
label: _('Add Items'),
|
2019-12-21 20:16:50 +05:30
|
|
|
icon: 'item',
|
|
|
|
description:
|
|
|
|
'Add products or services that you sell to your customers',
|
2020-01-02 22:40:18 +05:30
|
|
|
action: () => this.$router.push('/list/Item'),
|
2020-04-30 16:40:03 +05:30
|
|
|
fieldname: 'itemCreated',
|
|
|
|
documentation:
|
|
|
|
'https://frappebooks.com/docs/setting-up#3-add-items'
|
2019-12-21 20:16:50 +05:30
|
|
|
},
|
|
|
|
{
|
2020-01-02 22:40:18 +05:30
|
|
|
key: 'Add Customers',
|
|
|
|
label: _('Add Customers'),
|
2019-12-21 20:16:50 +05:30
|
|
|
icon: 'customer',
|
|
|
|
description: 'Add a few customers to create your first invoice',
|
2020-01-02 22:40:18 +05:30
|
|
|
action: () => this.$router.push('/list/Customer'),
|
2020-04-30 16:40:03 +05:30
|
|
|
fieldname: 'customerCreated',
|
|
|
|
documentation:
|
|
|
|
'https://frappebooks.com/docs/setting-up#4-add-customers'
|
2019-12-21 20:16:50 +05:30
|
|
|
},
|
|
|
|
{
|
2020-01-02 22:40:18 +05:30
|
|
|
key: 'Create Invoice',
|
|
|
|
label: _('Create Invoice'),
|
2019-12-21 20:16:50 +05:30
|
|
|
icon: 'sales-invoice',
|
|
|
|
description:
|
|
|
|
'Create your first invoice and mail it to your customer',
|
2020-01-02 22:40:18 +05:30
|
|
|
action: () => this.$router.push('/list/SalesInvoice'),
|
2020-04-30 16:40:03 +05:30
|
|
|
fieldname: 'invoiceCreated',
|
|
|
|
documentation: 'https://frappebooks.com/docs/invoices'
|
2019-12-21 20:16:50 +05:30
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
2020-01-02 22:40:18 +05:30
|
|
|
label: _('Purchase'),
|
2019-12-21 20:16:50 +05:30
|
|
|
|
|
|
|
items: [
|
|
|
|
{
|
2020-01-02 22:40:18 +05:30
|
|
|
key: 'Add Purchase Items',
|
|
|
|
label: _('Add Items'),
|
2019-12-21 20:16:50 +05:30
|
|
|
icon: 'item',
|
|
|
|
description:
|
|
|
|
'Add products or services that you buy from your suppliers',
|
2020-01-02 22:40:18 +05:30
|
|
|
action: () => this.$router.push('/list/Item'),
|
|
|
|
fieldname: 'itemCreated'
|
2019-12-21 20:16:50 +05:30
|
|
|
},
|
|
|
|
{
|
2020-01-02 22:40:18 +05:30
|
|
|
key: 'Add Suppliers',
|
|
|
|
label: _('Add Suppliers'),
|
2019-12-21 20:16:50 +05:30
|
|
|
icon: 'supplier',
|
|
|
|
description: 'Add a few suppliers to create your first bill',
|
2020-01-02 22:40:18 +05:30
|
|
|
action: () => this.$router.push('/list/Supplier'),
|
|
|
|
fieldname: 'supplierCreated'
|
2019-12-21 20:16:50 +05:30
|
|
|
},
|
|
|
|
{
|
2020-01-02 22:40:18 +05:30
|
|
|
key: 'Create Bill',
|
|
|
|
label: _('Create Bill'),
|
2019-12-21 20:16:50 +05:30
|
|
|
icon: 'purchase-invoice',
|
|
|
|
description:
|
|
|
|
'Create your first bill and mail it to your supplier',
|
2020-01-02 22:40:18 +05:30
|
|
|
action: () => this.$router.push('/list/PurchaseInvoice'),
|
2020-04-30 16:40:03 +05:30
|
|
|
fieldname: 'billCreated',
|
|
|
|
documentation: 'https://frappebooks.com/docs/bills'
|
2019-12-21 20:16:50 +05:30
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
2020-01-02 22:40:18 +05:30
|
|
|
];
|
|
|
|
}
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
activeCard: null
|
2019-12-21 20:16:50 +05:30
|
|
|
};
|
|
|
|
},
|
2020-01-02 22:40:18 +05:30
|
|
|
async activated() {
|
|
|
|
frappe.GetStarted = await frappe.getSingle('GetStarted');
|
|
|
|
this.checkForCompletedTasks();
|
|
|
|
},
|
2019-12-21 20:16:50 +05:30
|
|
|
methods: {
|
2020-01-02 22:40:18 +05:30
|
|
|
async checkForCompletedTasks() {
|
|
|
|
let toUpdate = {};
|
|
|
|
if (frappe.GetStarted.onboardingCompleted) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let printSettings = await frappe.getSingle('PrintSettings');
|
|
|
|
if (printSettings.logo && printSettings.address) {
|
|
|
|
toUpdate.invoiceSetup = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!frappe.GetStarted.itemCreated) {
|
|
|
|
let { count } = (
|
|
|
|
await frappe.db.knex('Item').count('name as count')
|
|
|
|
)[0];
|
|
|
|
if (count > 0) {
|
|
|
|
toUpdate.itemCreated = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!frappe.GetStarted.invoiceCreated) {
|
|
|
|
let { count } = (
|
|
|
|
await frappe.db.knex('SalesInvoice').count('name as count')
|
|
|
|
)[0];
|
|
|
|
if (count > 0) {
|
|
|
|
toUpdate.invoiceCreated = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!frappe.GetStarted.customerCreated) {
|
|
|
|
let { count } = (
|
|
|
|
await frappe.db
|
|
|
|
.knex('Party')
|
|
|
|
.where('customer', 1)
|
|
|
|
.count('name as count')
|
|
|
|
)[0];
|
|
|
|
if (count > 0) {
|
|
|
|
toUpdate.customerCreated = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!frappe.GetStarted.billCreated) {
|
|
|
|
let { count } = (
|
|
|
|
await frappe.db.knex('PurchaseInvoice').count('name as count')
|
|
|
|
)[0];
|
|
|
|
if (count > 0) {
|
|
|
|
toUpdate.billCreated = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!frappe.GetStarted.supplierCreated) {
|
|
|
|
let { count } = (
|
|
|
|
await frappe.db
|
|
|
|
.knex('Party')
|
|
|
|
.where('supplier', 1)
|
|
|
|
.count('name as count')
|
|
|
|
)[0];
|
|
|
|
if (count > 0) {
|
|
|
|
toUpdate.supplierCreated = 1;
|
|
|
|
}
|
|
|
|
}
|
2020-04-30 16:40:03 +05:30
|
|
|
await this.updateChecks(toUpdate);
|
|
|
|
},
|
|
|
|
async updateChecks(toUpdate) {
|
2020-01-02 22:40:18 +05:30
|
|
|
await frappe.GetStarted.update(toUpdate);
|
|
|
|
frappe.GetStarted = await frappe.getSingle('GetStarted');
|
|
|
|
},
|
2020-04-30 16:40:03 +05:30
|
|
|
visitLink(link) {
|
|
|
|
if (link) {
|
|
|
|
require('electron').shell.openExternal(link);
|
|
|
|
}
|
|
|
|
},
|
2020-01-02 22:40:18 +05:30
|
|
|
isCompleted(item) {
|
|
|
|
return frappe.GetStarted.get(item.fieldname) || 0;
|
|
|
|
},
|
|
|
|
getIconComponent(item) {
|
|
|
|
let completed = frappe.GetStarted[item.fieldname] || 0;
|
|
|
|
let name = completed ? 'green-check' : item.icon;
|
|
|
|
let size = completed ? '24' : '18';
|
2019-12-21 20:16:50 +05:30
|
|
|
return {
|
|
|
|
name,
|
|
|
|
render(h) {
|
|
|
|
return h(Icon, {
|
|
|
|
props: Object.assign(
|
|
|
|
{
|
|
|
|
name,
|
2020-01-02 22:40:18 +05:30
|
|
|
size
|
2019-12-21 20:16:50 +05:30
|
|
|
},
|
|
|
|
this.$attrs
|
|
|
|
)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
</script>
|