2
0
mirror of https://github.com/frappe/books.git synced 2025-02-02 03:58:26 +00:00

[Fixes] #98 UI Issues 05-08-2019

This commit is contained in:
thefalconx33 2019-08-14 13:13:49 +05:30
parent 88021193fc
commit 54e115b030
49 changed files with 868 additions and 402 deletions

View File

@ -271,7 +271,7 @@
"currency_fraction_units": 100,
"currency_name": "Belize Dollar",
"currency_symbol": "$",
"date_format": "mm-dd-yyyy",
"date_format": "MM-dd-yyyy",
"number_format": "#,###.##",
"timezones": [
"America/Belize"
@ -356,7 +356,7 @@
"currency_fraction": "Centavo",
"currency_fraction_units": 100,
"currency_symbol": "R$",
"date_format": "dd/mm/yyyy",
"date_format": "dd/MM/yyyy",
"number_format": "#.###,##",
"timezones": [
"America/Araguaina",
@ -463,7 +463,7 @@
"currency_fraction_units": 100,
"currency_name": "Canadian Dollar",
"currency_symbol": "$",
"date_format": "mm-dd-yyyy",
"date_format": "MM-dd-yyyy",
"number_format": "#,###.##",
"timezones": [
"America/Atikokan",
@ -563,7 +563,7 @@
"code": "cn",
"currency": "CNY",
"currency_name": "Yuan Renminbi",
"date_format": "yyyy-mm-dd",
"date_format": "yyyy-MM-dd",
"number_format": "#,###.##",
"timezones": [
"Asia/Chongqing",
@ -884,7 +884,7 @@
"currency_fraction_units": 100,
"currency_symbol": "\u20ac",
"number_format": "# ###,##",
"date_format": "dd/mm/yyyy",
"date_format": "dd/MM/yyyy",
"timezones": [
"Europe/Paris"
]
@ -1136,7 +1136,7 @@
"currency_fraction_units": 100,
"currency_name": "Forint",
"currency_symbol": "Ft",
"date_format": "yyyy-mm-dd",
"date_format": "yyyy-MM-dd",
"number_format": "#.###",
"timezones": [
"Europe/Budapest"
@ -1161,6 +1161,7 @@
"currency_fraction_units": 100,
"currency_name": "Indian Rupee",
"currency_symbol": "\u20b9",
"date_format": "dd/MM/yyyy",
"number_format": "#,##,###.##",
"timezones": [
"Asia/Kolkata"
@ -1247,7 +1248,7 @@
"currency_fraction_units": 100,
"currency_symbol": "\u20ac",
"number_format": "#.###,##",
"date_format": "dd/mm/yyyy",
"date_format": "dd/MM/yyyy",
"timezones": [
"Europe/Rome"
],
@ -1471,7 +1472,7 @@
"currency_fraction_units": 100,
"currency_name": "Lithuanian Litas",
"currency_symbol": "Lt",
"date_format": "yyyy-mm-dd",
"date_format": "yyyy-MM-dd",
"number_format": "# ###,##",
"timezones": [
"Europe/Vilnius"
@ -1674,7 +1675,7 @@
"currency_fraction_units": 100,
"currency_name": "Tugrik",
"currency_symbol": "\u20ae",
"date_format": "yyyy-mm-dd",
"date_format": "yyyy-MM-dd",
"number_format": "#,###.##",
"timezones": [
"Asia/Choibalsan",
@ -1911,7 +1912,7 @@
"currency_fraction": "Cent",
"currency_fraction_units": 100,
"currency_symbol": "$",
"date_format": "mm-dd-yyyy",
"date_format": "MM-dd-yyyy",
"number_format": "#,###.##",
"timezones": [
"Pacific/Palau"
@ -1974,7 +1975,7 @@
"currency_fraction_units": 100,
"currency_name": "Philippine Peso",
"currency_symbol": "\u20b1",
"date_format": "mm-dd-yyyy",
"date_format": "MM-dd-yyyy",
"number_format": "#,###.##",
"timezones": [
"Asia/Manila"
@ -2278,7 +2279,7 @@
"currency_fraction_units": 100,
"currency_name": "Rand",
"currency_symbol": "R",
"date_format": "yyyy-mm-dd",
"date_format": "yyyy-MM-dd",
"number_format": "# ###.##",
"timezones": [
"Africa/Johannesburg"
@ -2398,7 +2399,7 @@
"Taiwan": {
"code": "tw",
"currency": "TWD",
"date_format": "yyyy-mm-dd",
"date_format": "yyyy-MM-dd",
"number_format": "#,###.##"
},
"Tajikistan": {
@ -2591,7 +2592,7 @@
"smallest_currency_fraction_value": 0.05,
"currency_name": "US Dollar",
"currency_symbol": "$",
"date_format": "mm-dd-yyyy",
"date_format": "MM-dd-yyyy",
"number_format": "#,###.##",
"timezones": [
"America/Adak",

View File

@ -13,26 +13,33 @@ module.exports = {
fieldtype: 'Data',
required: 1
},
{
fieldname: 'rootType',
label: 'Root Type',
fieldtype: 'Select',
options: [
'Select...',
'Asset',
'Liability',
'Equity',
'Income',
'Expense'
],
required: 1
},
{
fieldname: 'parentAccount',
label: 'Parent Account',
fieldtype: 'Link',
target: 'Account',
getFilters: (query, doc) => {
console.log(doc);
return {
isGroup: 1,
rootType: doc.rootType
const filter = {
isGroup: 1
};
doc.rootType ? (filter.rootType = doc.rootType) : '';
return filter;
}
},
{
fieldname: 'rootType',
label: 'Root Type',
fieldtype: 'Select',
options: ['', 'Asset', 'Liability', 'Equity', 'Income', 'Expense'],
required: 1
},
{
fieldname: 'accountType',
label: 'Account Type',

View File

@ -1,89 +1,95 @@
module.exports = {
"name": "Address",
"doctype": "DocType",
"isSingle": 0,
"keywordFields": [
"name"
],
name: 'Address',
doctype: 'DocType',
isSingle: 0,
keywordFields: ['name'],
pageSettings: {
hideTitle: true
},
// "naming": "autoincrement",
"fields": [
fields: [
{
"fieldname": "name",
"label": "Address Title",
"fieldtype": "Data",
"required": 1
fieldname: 'name',
label: 'Address Title',
fieldtype: 'Data',
defaultValue: 'Work',
required: 1
},
{
"fieldname": "addressType",
"label": "Address Type",
"fieldtype": "Select",
"options": [
"Billing", "Shipping", "Office",
"Personal", "Plant", "Postal",
"Shop", "Subsidary", "Warehouse",
"Current", "Permanent", "Other"
fieldname: 'addressType',
label: 'Address Type',
fieldtype: 'Select',
options: [
'Billing',
'Shipping',
'Office',
'Personal',
'Plant',
'Postal',
'Shop',
'Subsidary',
'Warehouse',
'Current',
'Permanent',
'Other'
]
},
{
"fieldname": "addressLine1",
"label": "Address Line 1",
"fieldtype": "Data",
"required": 1
fieldname: 'addressLine1',
label: 'Address Line 1',
fieldtype: 'Data',
required: 1
},
{
"fieldname": "addressLine2",
"label": "Address Line 2",
"fieldtype": "Data"
fieldname: 'addressLine2',
label: 'Address Line 2',
fieldtype: 'Data'
},
{
"fieldname": "city",
"label": "City / Town",
"fieldtype": "Data",
"required": 1
fieldname: 'city',
label: 'City / Town',
fieldtype: 'Data',
required: 1
},
{
"fieldname": "state",
"label": "State",
"fieldtype": "Data"
fieldname: 'state',
label: 'State',
fieldtype: 'Data'
},
{
"fieldname": "country",
"label": "Country",
"fieldtype": "Data",
"required": 1
fieldname: 'country',
label: 'Country',
fieldtype: 'Data',
required: 1
},
{
"fieldname": "postalCode",
"label": "Postal Code",
"fieldtype": "Data"
fieldname: 'postalCode',
label: 'Postal Code',
fieldtype: 'Data'
},
{
"fieldname": "emailAddress",
"label": "Email Address",
"fieldtype": "Data"
fieldname: 'emailAddress',
label: 'Email Address',
fieldtype: 'Data'
},
{
"fieldname": "phone",
"label": "Phone",
"fieldtype": "Data"
fieldname: 'phone',
label: 'Phone',
fieldtype: 'Data'
},
{
"fieldname": "fax",
"label": "Fax",
"fieldtype": "Data"
fieldname: 'fax',
label: 'Fax',
fieldtype: 'Data'
},
{
"fieldname": "isPreferredBilling",
"label": "Preferred Billing Address",
"fieldtype": "Check"
fieldname: 'isPreferredBilling',
label: 'Preferred Billing Address',
fieldtype: 'Check'
},
{
"fieldname": "isShippingBilling",
"label": "Preferred Shipping Address",
"fieldtype": "Check"
fieldname: 'isShippingBilling',
label: 'Preferred Shipping Address',
fieldtype: 'Check'
}
],
@ -98,7 +104,9 @@ module.exports = {
return ['name', 'addressType'];
},
getRowHTML(list, data) {
return `<div class="col-11">${list.getNameHTML(data)} (${data.addressType})</div>`;
return `<div class="col-11">${list.getNameHTML(data)} (${
data.addressType
})</div>`;
}
},
@ -108,17 +116,26 @@ module.exports = {
columns: [
{
fields: [
"name", "addressType", "addressLine1",
"addressLine2", "city", "country", "state",
"postalCode"
'name',
'addressType',
'addressLine1',
'addressLine2',
'city',
'country',
'state',
'postalCode'
]
},
{
fields: [
"emailAddress", "phone", "fax", "isPreferredBilling", "isShippingBilling"
'emailAddress',
'phone',
'fax',
'isPreferredBilling',
'isShippingBilling'
]
}
]
}
]
}
};

View File

@ -0,0 +1,16 @@
module.exports = {
name: 'Color',
doctype: 'DocType',
fields: [
{
fieldname: 'name',
fieldtype: 'Data',
label: 'Color'
},
{
fieldname: 'hexvalue',
fieldtype: 'Data',
label: 'Hex Value'
}
]
};

View File

@ -12,13 +12,15 @@ module.exports = {
{
fieldname: 'type',
fieldtype: 'Select',
options: ['', 'Bar', 'Line', 'Percentage'],
label: 'Chart Type'
options: ['Bar', 'Line', 'Percentage'],
label: 'Chart Type',
defaultValue: 'Bar'
},
{
fieldname: 'color',
fieldtype: 'Data',
label: 'Color'
fieldtype: 'Link',
label: 'Color',
target: 'Color'
}
]
};

View File

@ -4,11 +4,6 @@ module.exports = {
doctype: 'DocType',
isSingle: 1,
fields: [
{
fieldname: 'name',
fieldtype: 'Data',
label: 'Dashboard Name'
},
{
fieldname: 'charts',
fieldtype: 'Table',

View File

@ -6,7 +6,7 @@
</div>
</div>
<div ref="printComponent" class="col-8 bg-white mt-4 mx-auto border shadow">
<div class="print-format" style="padding: 3.5rem;">
<div class="print-format" style="padding: 3.5rem; font-size: 8pt !important;">
<div>
<h3 class="text-center">GSTR3B-Form</h3>
<h5>GSTIN: &nbsp; {{ jsonData.gstin }}</h5>
@ -292,7 +292,6 @@ export default {
<style>
.print-format {
font-size: 8pt !important;
}
.disabled {
background-color: #d9d9d9;

View File

@ -101,5 +101,49 @@ module.exports = {
}
]
}
],
links: [
{
label: 'New Sales Invoice',
condition: form => !form.doc._notInserted,
action: async form => {
const invoice = await frappe.getNewDoc('SalesInvoice');
invoice.items = [
{
item: form.doc.name,
rate: form.doc.rate,
tax: form.doc.tax
}
];
invoice.on('afterInsert', async () => {
form.$formModal.close();
form.$router.push({
path: `/edit/PurchaseInvoice/${invoice.name}`
});
});
await form.$formModal.open(invoice);
}
},
{
label: 'New Purchase Invoice',
condition: form => !form.doc._notInserted,
action: async form => {
const invoice = await frappe.getNewDoc('PurchaseInvoice');
invoice.items = [
{
item: form.doc.name,
rate: form.doc.rate,
tax: form.doc.tax
}
];
invoice.on('afterInsert', async () => {
form.$formModal.close();
form.$router.push({
path: `/edit/PurchaseInvoice/${invoice.name}`
});
});
await form.$formModal.open(invoice);
}
}
]
};

View File

@ -2,88 +2,79 @@ const frappe = require('frappejs');
const utils = require('../../../accounting/utils');
module.exports = {
name: "JournalEntry",
doctype: "DocType",
label: 'Journal Entry',
name: 'JournalEntry',
doctype: 'DocType',
isSingle: 0,
isChild: 0,
isSubmittable: 1,
keywordFields: ["name"],
keywordFields: ['name'],
showTitle: true,
settings: "JournalEntrySettings",
settings: 'JournalEntrySettings',
fields: [
{
fieldname: "date",
label: "Date",
fieldtype: "Date"
},
{
fieldname: "entryType",
label: "Entry Type",
fieldtype: "Select",
fieldname: 'entryType',
label: 'Entry Type',
fieldtype: 'Select',
options: [
"Journal Entry",
"Bank Entry",
"Cash Entry",
"Credit Card Entry",
"Debit Note",
"Credit Note",
"Contra Entry",
"Excise Entry",
"Write Off Entry",
"Opening Entry",
"Depreciation Entry"
'Journal Entry',
'Bank Entry',
'Cash Entry',
'Credit Card Entry',
'Debit Note',
'Credit Note',
'Contra Entry',
'Excise Entry',
'Write Off Entry',
'Opening Entry',
'Depreciation Entry'
],
required: 1
},
{
fieldname: "accounts",
label: "Account Entries",
fieldtype: "Table",
childtype: "JournalEntryAccount",
fieldname: 'date',
label: 'Date',
fieldtype: 'Date'
},
{
fieldname: 'accounts',
label: 'Account Entries',
fieldtype: 'Table',
childtype: 'JournalEntryAccount',
required: true
},
{
fieldname: "referenceNumber",
label: "Reference Number",
fieldtype: "Data",
fieldname: 'referenceNumber',
label: 'Reference Number',
fieldtype: 'Data'
},
{
fieldname: "referenceDate",
label: "Reference Date",
fieldtype: "Date",
fieldname: 'referenceDate',
label: 'Reference Date',
fieldtype: 'Date'
},
{
fieldname: "userRemark",
label: "User Remark",
fieldtype: "Text",
fieldname: 'userRemark',
label: 'User Remark',
fieldtype: 'Text'
}
],
layout: [
// section 1
{
columns: [
{ fields: [ "date" ] },
{ fields: [ "entryType" ] },
]
columns: [{ fields: ['entryType'] }, { fields: ['date'] }]
},
// section 2
{
columns: [
{ fields: ["accounts"]},
]
columns: [{ fields: ['accounts'] }]
},
// section 3
{
columns: [
{ fields: [ "referenceNumber"] },
{ fields: [ "referenceDate"] }
]
columns: [{ fields: ['referenceNumber'] }, { fields: ['referenceDate'] }]
},
// section 4
{
columns: [{ fields: [ "userRemark" ] }],
columns: [{ fields: ['userRemark'] }]
}
]
}
};

View File

@ -3,7 +3,6 @@ module.exports = {
label: 'Party',
doctype: 'DocType',
isSingle: 0,
istable: 0,
keywordFields: ['name'],
fields: [
{
@ -42,22 +41,64 @@ module.exports = {
}
],
getFormTitle(doc) {
if (doc.customer) return 'Customer';
return 'Supplier';
},
getListTitle(doc) {
if (doc.customer) return 'Customer';
return 'Supplier';
},
links: [
{
label: 'New Sales Invoice',
condition: form => form.doc.customer,
action: async form => {
const invoice = await frappe.getNewDoc('SalesInvoice');
invoice.customer = form.doc.name;
invoice.account = form.doc.defaultAccount;
invoice.on('afterInsert', async () => {
form.$formModal.close();
form.$router.push({
path: `/edit/SalesInvoice/${invoice.name}`
});
});
await form.$formModal.open(invoice);
}
},
{
label: 'Sales Invoices',
condition: form => form.doc.customer,
action: form => {
form.$router.push({
path: `/report/sales-register?&customer=${form.doc.name}`
path: `/list/SalesInvoice?customer=${form.doc.name}`
});
}
},
{
label: 'New Purchase Invoice',
condition: form => form.doc.supplier,
action: async form => {
const invoice = await frappe.getNewDoc('PurchaseInvoice');
invoice.supplier = form.doc.name;
invoice.account = form.doc.defaultAccount;
invoice.on('afterInsert', async () => {
form.$formModal.close();
form.$router.push({
path: `/edit/PurchaseInvoice/${invoice.name}`
});
});
await form.$formModal.open(invoice);
}
},
{
label: 'Purchase Invoices',
condition: form => form.doc.supplier,
action: form => {
form.$router.push({
path: `/report/purchase-register?&supplier=${form.doc.name}`
path: `/list/PurchaseInvoice?supplier=${form.doc.name}`
});
}
},

View File

@ -0,0 +1,7 @@
import { _ } from 'frappejs/utils';
export default {
doctype: 'Party',
title: filters => (filters.customer ? 'Customer' : 'Supplier'),
columns: ['name', 'defaultAccount', 'address']
};

View File

@ -9,12 +9,6 @@ module.exports = {
keywordFields: [],
settings: 'PaymentSettings',
fields: [
{
fieldname: 'date',
label: 'Posting Date',
fieldtype: 'Date'
// default: new Date().toISOString().substring(0, 10)
},
{
fieldname: 'party',
label: 'Party',
@ -22,6 +16,12 @@ module.exports = {
target: 'Party',
required: 1
},
{
fieldname: 'date',
label: 'Posting Date',
fieldtype: 'Date',
defaultValue: new Date().toISOString()
},
{
fieldname: 'account',
label: 'From Account',
@ -95,7 +95,10 @@ module.exports = {
fieldtype: 'Currency',
required: 1,
disabled: true,
formula: doc => doc.getSum('for', 'amount')
formula: doc => {
console.log(doc.getSum('for', 'amount'));
return frappe.format(doc.getSum('for', 'amount'), 'Currency');
}
},
{
fieldname: 'writeoff',
@ -115,10 +118,10 @@ module.exports = {
{
columns: [
{
fields: ['date', 'account']
fields: ['party', 'account']
},
{
fields: ['party', 'paymentAccount']
fields: ['date', 'paymentAccount']
}
]
},

View File

@ -7,7 +7,11 @@ export default {
columns: [
'party',
{
label: 'Payment',
label: 'Status',
fieldname: 'status',
fieldtype: 'Select',
size: 'small',
options: ['Status...', 'Reconciled', 'Not Reconciled'],
getValue(doc) {
if (
doc.submitted === 1 &&
@ -27,10 +31,9 @@ export default {
return indicators.ORANGE;
}
},
'account',
'amount',
'paymentType',
'date',
'clearanceDate',
'name'
'amount'
]
};

View File

@ -1,28 +1,31 @@
module.exports = {
name: "PaymentFor",
label: "Payment For",
name: 'PaymentFor',
label: 'Payment For',
isSingle: 0,
isChild: 1,
keywordFields: [],
fields: [
{
fieldname: "referenceType",
label: "Reference Type",
fieldtype: "Data",
fieldname: 'referenceType',
label: 'Reference Type',
fieldtype: 'Data',
required: 1
},
{
fieldname: "referenceName",
label: "Reference Name",
fieldtype: "DynamicLink",
references: "referenceType",
fieldname: 'referenceName',
label: 'Reference Name',
fieldtype: 'DynamicLink',
references: 'referenceType',
required: 1
},
{
fieldname: "amount",
label: "Amount",
fieldtype: "Currency",
required: 1
fieldname: 'amount',
label: 'Amount',
fieldtype: 'Currency',
formula: (row, doc) => {
doc.getFrom(doc.referenceType, doc.referenceName, 'grandTotal');
},
required: 1
}
]
}
};

View File

@ -16,7 +16,8 @@ module.exports = {
{
fieldname: 'date',
label: 'Date',
fieldtype: 'Date'
fieldtype: 'Date',
defaultValue: new Date().toISOString()
},
{
fieldname: 'supplier',

View File

@ -8,6 +8,10 @@ export default {
'supplier',
{
label: 'Status',
fieldname: 'status',
fieldtype: 'Select',
size: 'small',
options: ['Status...', 'Paid', 'Pending'],
getValue(doc) {
if (doc.submitted === 1 && doc.outstandingAmount === 0.0) {
return 'Paid';
@ -21,8 +25,8 @@ export default {
return indicators.ORANGE;
}
},
'grandTotal',
'date',
'grandTotal',
'outstandingAmount'
]
};

View File

@ -19,8 +19,8 @@ module.exports = {
{
fieldname: 'date',
label: 'Date',
fieldtype: 'Date'
// default: (new Date()).toISOString()
fieldtype: 'Date',
defaultValue: new Date().toISOString()
},
{
fieldname: 'customer',
@ -70,7 +70,7 @@ module.exports = {
fieldname: 'netTotal',
label: 'Net Total',
fieldtype: 'Currency',
formula: doc => doc.getSum('items', 'amount'),
formula: doc => frappe.format(doc.getSum('items', 'amount'), 'Currency'),
disabled: true,
readOnly: 1
},

View File

@ -68,13 +68,14 @@ module.exports = class SalesInvoice extends BaseDocument {
getGrandTotal() {
this.makeTaxSummary();
let grandTotal = this.netTotal;
let grandTotal = frappe.parseNumber(this.netTotal);
if (this.taxes) {
for (let row of this.taxes) {
grandTotal += row.amount;
}
}
grandTotal = Math.floor(grandTotal * 100) / 100;
return grandTotal;
return frappe.format(grandTotal, 'Currency');
}
};

View File

@ -8,6 +8,10 @@ export default {
'customer',
{
label: 'Status',
fieldname: 'status',
fieldtype: 'Select',
size: 'small',
options: ['Status..', 'Paid', 'Pending'],
getValue(doc) {
if (doc.submitted === 1 && doc.outstandingAmount === 0.0) {
return 'Paid';
@ -21,8 +25,8 @@ export default {
return indicators.ORANGE;
}
},
'grandTotal',
'date',
'grandTotal',
'outstandingAmount'
]
};

View File

@ -17,10 +17,18 @@
@changeColor="changeColor($event)"
@changeTemplate="changeTemplate($event)"
@changeFont="changeFont($event)"
@updateTemplateView="updateTemplateView"
/>
</div>
<div class="col-8 bg-white mt-4 mx-auto border shadow" ref="printComponent">
<component :themeColor="themeColor" :font="font" :is="template" v-if="doc" :doc="doc" />
<component
:themeColor="themeColor"
:font="font"
:is="template"
v-if="doc"
:doc="doc"
:key="usedForReRender"
/>
</div>
</div>
</div>
@ -48,7 +56,8 @@ export default {
showInvoiceCustomizer: false,
themeColor: undefined,
template: undefined,
font: undefined
font: undefined,
usedForReRender: 0
};
},
async created() {
@ -76,14 +85,17 @@ export default {
await this.loadInvoice();
this.showInvoiceCustomizer = !this.showInvoiceCustomizer;
},
async changeColor(color) {
changeColor(color) {
this.themeColor = color;
},
async changeTemplate(template) {
changeTemplate(template) {
this.template = invoiceTemplates[template];
},
async changeFont(font) {
changeFont(font) {
this.font = font;
},
updateTemplateView() {
this.usedForReRender += 1;
}
}
};

View File

@ -20,7 +20,7 @@ module.exports = {
fieldtype: 'Select',
options: ['Basic I', 'Basic II', 'Modern'],
required: 1,
default: 'Basic I'
defaultValue: 'Basic I'
},
{
fieldname: 'font',
@ -28,14 +28,14 @@ module.exports = {
fieldtype: 'Select',
options: ['Montserrat', 'Open Sans', 'Oxygen', 'Merriweather'],
required: 1,
default: 'Montserrat'
defaultValue: 'Montserrat'
},
{
fieldname: 'themeColor',
label: 'Theme Color',
fieldtype: 'Data',
required: 1,
default: '#000000',
defaultValue: '#000000',
hidden: 1
}
]

View File

@ -3,6 +3,7 @@ module.exports = {
SetupWizard: require('./doctype/SetupWizard/SetupWizard'),
DashboardSettings: require('./doctype/DashboardSettings/DashboardSettings'),
DashboardChart: require('./doctype/DashboardChart/DashboardChart'),
Color: require('./doctype/Color/Color'),
Account: require('./doctype/Account/Account.js'),
AccountingSettings: require('./doctype/AccountingSettings/AccountingSettings'),
CompanySettings: require('./doctype/CompanySettings/CompanySettings'),

View File

@ -2,6 +2,8 @@ const frappe = require('frappejs');
class BankReconciliation {
async run(params) {
if (!Object.keys(params).length) return [];
const filters = {};
if (params.paymentAccount) filters.paymentAccount = params.paymentAccount;
if (params.party) filters.party = params.party;

View File

@ -6,7 +6,9 @@ module.exports = {
{
fieldtype: 'Link',
target: 'Account',
label: 'Payement Account',
size: 'small',
placeholder: 'Payment Account',
label: 'Payment Account',
fieldname: 'paymentAccount',
getFilters: () => {
return {
@ -18,20 +20,36 @@ module.exports = {
{
fieldtype: 'Link',
target: 'Party',
size: 'small',
label: 'Party',
placeholder: 'Party',
fieldname: 'party'
},
{
fieldtype: 'Date',
size: 'small',
placeholder: 'From Date',
label: 'From Date',
fieldname: 'fromDate'
},
{
fieldtype: 'Date',
size: 'small',
placeholder: 'To Date',
label: 'To Date',
fieldname: 'toDate'
}
],
linkFields: [
{
label: 'Clear Filters',
type: 'secondary',
action: async report => {
await report.getReportData({});
report.usedToReRender += 1;
}
}
],
getColumns() {
return [
{

View File

@ -2,6 +2,8 @@ const frappe = require('frappejs');
class GeneralLedger {
async run(params) {
if (!Object.keys(params).length) return [];
const filters = {};
if (params.account) filters.account = params.account;
if (params.party) filters.party = params.party;

View File

@ -5,12 +5,15 @@ const viewConfig = {
filterFields: [
{
fieldtype: 'Select',
options: ['', 'SalesInvoice', 'Payment', 'PurchaseInvoice'],
options: ['Select...', 'SalesInvoice', 'Payment', 'PurchaseInvoice'],
size: 'small',
label: 'Reference Type',
fieldname: 'referenceType'
},
{
fieldtype: 'DynamicLink',
size: 'small',
placeholder: 'Reference Name',
references: 'referenceType',
label: 'Reference Name',
fieldname: 'referenceName'
@ -18,6 +21,8 @@ const viewConfig = {
{
fieldtype: 'Link',
target: 'Account',
size: 'small',
placeholder: 'Account',
label: 'Account',
fieldname: 'account'
},
@ -25,21 +30,35 @@ const viewConfig = {
fieldtype: 'Link',
target: 'Party',
label: 'Party',
size: 'small',
placeholder: 'Party',
fieldname: 'party'
},
{
fieldtype: 'Date',
size: 'small',
placeholder: 'From Date',
label: 'From Date',
fieldname: 'fromDate'
},
{
fieldtype: 'Date',
size: 'small',
placeholder: 'To Date',
label: 'To Date',
fieldname: 'toDate'
}
],
method: 'general-ledger',
linkFields: [
{
label: 'Clear Filters',
type: 'secondary',
action: async report => {
await report.getReportData({});
report.usedToReRender += 1;
}
},
{
label: 'Export',
type: 'primary',
@ -70,13 +89,6 @@ const viewConfig = {
props: await getReportDetails()
});
}
},
{
label: 'Clear Filters',
type: 'secondary',
action: async report => {
await report.$router.push(`/report/general-ledger`);
}
}
],
getColumns() {

View File

@ -10,29 +10,29 @@ module.exports = {
'B2C-Large',
'B2C-Small',
'Nil Rated, Exempted and Non GST supplies'
]
],
size: 'small'
},
{
fieldtype: 'Data',
label: 'Place',
size: 'small',
placeholder: 'Place',
fieldname: 'place'
},
{
fieldtype: 'Date',
label: 'From Date',
size: 'small',
placeholder: 'From Date',
fieldname: 'fromDate'
},
{
fieldtype: 'Date',
label: 'To Date',
size: 'small',
placeholder: 'To Date',
fieldname: 'toDate'
},
{
fieldtype: 'Select',
label: 'Report Type',
fieldname: 'reportType',
options: ['', 'GSTR-1', 'GSTR-2', 'GSTR-3B'],
hidden: 1
}
],
linkFields: [
@ -66,6 +66,14 @@ module.exports = {
props: await getReportDetails()
});
}
},
{
label: 'Clear Filters',
type: 'secondary',
action: async report => {
await report.getReportData({});
report.usedToReRender += 1;
}
}
],

View File

@ -2,6 +2,8 @@ const BaseGSTR = require('./BaseGSTR');
class GSTR1 extends BaseGSTR {
async run(params) {
if (!Object.keys(params).length) return [];
let filters = {};
if (params.toDate || params.fromDate) {
filters.date = [];

View File

@ -2,6 +2,8 @@ const BaseGSTR = require('./BaseGSTR');
class GSTR2 extends BaseGSTR {
async run(params) {
if (!Object.keys(params).length) return [];
let filters = {};
if (params.toDate || params.fromDate) {
filters.date = [];

View File

@ -2,6 +2,8 @@ const frappe = require('frappejs');
class PurchaseRegister {
async run({ fromDate, toDate, supplier }) {
if (!fromDate && !toDate && !supplier) return { rows: [] };
let filters = {};
if (supplier) {
filters.supplier = supplier;

View File

@ -8,6 +8,8 @@ module.exports = {
target: 'Party',
label: 'Supplier Name',
fieldname: 'supplier',
size: 'small',
placeholder: 'Supplier Name',
getFilters: query => {
if (query)
return {
@ -23,10 +25,29 @@ module.exports = {
{
fieldtype: 'Date',
fieldname: 'fromDate',
size: 'small',
placeholder: 'From Date',
label: 'From Date',
required: 1
},
{ fieldtype: 'Date', fieldname: 'toDate', label: 'To Date', required: 1 }
{
fieldtype: 'Date',
size: 'small',
placeholder: 'To Date',
fieldname: 'toDate',
label: 'To Date',
required: 1
}
],
linkFields: [
{
label: 'Clear Filters',
type: 'secondary',
action: async report => {
await report.getReportData({});
report.usedToReRender += 1;
}
}
],
getColumns() {
return [

View File

@ -2,6 +2,8 @@ const frappe = require('frappejs');
class SalesRegister {
async run({ fromDate, toDate, customer }) {
if (!fromDate && !toDate && !customer) return { rows: [] };
let filters = {};
if (customer) {
filters.customer = customer;

View File

@ -7,6 +7,8 @@ module.exports = {
fieldtype: 'Link',
target: 'Party',
label: 'Customer Name',
size: 'small',
placeholder: 'Customer Name',
fieldname: 'customer',
getFilters: query => {
if (query)
@ -23,10 +25,29 @@ module.exports = {
{
fieldtype: 'Date',
fieldname: 'fromDate',
size: 'small',
placeholder: 'From Date',
label: 'From Date',
required: 1
},
{ fieldtype: 'Date', fieldname: 'toDate', label: 'To Date', required: 1 }
{
fieldtype: 'Date',
size: 'small',
placeholder: 'To Date',
fieldname: 'toDate',
label: 'To Date',
required: 1
}
],
linkFields: [
{
label: 'Clear Filters',
type: 'secondary',
action: async report => {
await report.getReportData({});
report.usedToReRender += 1;
}
}
],
getColumns() {
return [

View File

@ -5,6 +5,9 @@ const {
module.exports = class TrialBalance {
async run({ fromDate, toDate }) {
if (!fromDate && !toDate) {
return { rows: [] };
}
const promises = ['Asset', 'Expense', 'Income', 'Liability', 'Equity'].map(
rootType => {
return getTrialBalance({ rootType, fromDate, toDate });

View File

@ -8,9 +8,28 @@ module.exports = {
fieldtype: 'Date',
fieldname: 'fromDate',
label: 'From Date',
size: 'small',
placeholder: 'From Date',
required: 1
},
{ fieldtype: 'Date', fieldname: 'toDate', label: 'To Date', required: 1 }
{
fieldtype: 'Date',
size: 'small',
placeholder: 'To Date',
fieldname: 'toDate',
label: 'To Date',
required: 1
}
],
linkFields: [
{
label: 'Clear Filters',
type: 'secondary',
action: async report => {
await report.getReportData({});
report.usedToReRender += 1;
}
}
],
getColumns(data) {
const columns = [

View File

@ -12,7 +12,10 @@
<div class="row">
<div class="col-12 mt-4">
<form-layout :doc="doc" :fields="fields" @updateDoc="saveDoc" />
<sketch-picker v-model="color" />
<sketch-picker v-model="color" class="shadow-none" />
<div class="mt-3">
<f-button secondary @click="openCompanySettings">{{ _('Company Settings') }}</f-button>
</div>
</div>
</div>
</div>
@ -56,6 +59,14 @@ export default {
this.doc.themeColor = this.color.hex;
await this.doc.update();
this.$emit('closeInvoiceCustomizer');
},
async openCompanySettings() {
const settings = await frappe.getSingle('CompanySettings');
settings.on('afterSave', async () => {
this.$formModal.close();
this.$emit('updateTemplateView');
});
this.$formModal.open(settings);
}
},
watch: {

View File

@ -4,13 +4,17 @@
>
<h5 class="m-0" v-if="title">{{ title }}</h5>
<div v-if="breadcrumbs">
<a v-for="(item, index) in clickableBreadcrumbs" :key="index" :href="item.route">
<h5 class="breadCrumbRoute">
{{ item.title }}
<feather-icon name="chevron-right" style="color: #212529 !important;"></feather-icon>
</h5>
<span v-for="(item, index) in breadcrumbs" :key="index">
<a v-if="item.route.length != 0" :href="item.route">
<h5 class="breadCrumbRoute">{{ item.title }}</h5>
</a>
<h5 class="breadCrumbRoute">{{ lastBreadcrumb.title }}</h5>
<h5 v-else class="breadCrumbRoute">{{ item.title }}</h5>
<feather-icon
v-if="index != breadcrumbs.length - 1"
name="chevron-right"
style="color: #212529 !important;"
></feather-icon>
</span>
</div>
<div class="col-4 p-1">
<SearchBar />
@ -40,7 +44,7 @@ export default {
.page-header {
position: sticky;
top: 0;
z-index: 1;
z-index: 10;
}
.breadCrumbRoute {
display: inline;

View File

@ -64,8 +64,29 @@ export default {
this.companyName = await sidebarConfig.getTitle();
this.dbFileName = await sidebarConfig.getDbName();
this.groups = sidebarConfig.getGroups();
this.setActive();
},
methods: {
setActive() {
let currentRoute = this.$route.fullPath;
// check each group items
this.groups.forEach(title => {
// filter items which contains the current route
sidebarConfig.getItems(title).filter(item => {
// check for substring 'list' 'SalesInvoice' etc.
let found = true;
currentRoute.split('/').forEach(str => {
if (str.length) {
item.route.indexOf(str) != -1 ? '' : (found = false);
}
});
if (found) {
this.toggleGroup(title);
}
return found;
});
});
},
isCurrentRoute(route) {
if (this.activeGroup) return false;
return this.$route.fullPath === route;
@ -100,6 +121,7 @@ export default {
}
.page-sidebar {
height: 100vh;
min-width: 208px;
}
.sidebar-item {

View File

@ -74,17 +74,75 @@ import Toasted from 'vue-toasted';
});
await doc.update();
const systemSettings = await frappe.getSingle('SystemSettings');
await systemSettings.set({
dateFormat: countryList[country]['date_format'] || 'yyyy-MM-dd'
});
await systemSettings.update();
await setupAccountsAndDashboard(bankName);
await setupRegionalChanges(country);
frappe.events.trigger('show-desk');
});
async function setupAccountsAndDashboard(bankName) {
await frappe.call({
method: 'import-coa'
});
const accountDoc = await frappe.newDoc({
doctype: 'Account'
});
Object.assign(accountDoc, {
name: bankName,
rootType: 'Asset',
parentAccount: 'Bank Accounts',
accountType: 'Bank'
});
accountDoc.insert();
const dashboardSettings = await frappe.getSingle('DashboardSettings');
const accounts = await frappe.db.getAll({
doctype: 'Account',
filters: { parentAccount: ['in', ['', undefined, null]] }
});
const colors = [
{ name: 'Red', hexvalue: '#d32f2f' },
{ name: 'Green', hexvalue: '#388e3c' },
{ name: 'Blue', hexvalue: '#0288d1' },
{ name: 'Yellow', hexvalue: '#cddc39' }
];
colors.forEach(async color => {
const c = await frappe.newDoc({ doctype: 'Color' });
c.set(color);
c.insert();
});
let charts = [];
accounts.forEach(account => {
charts.push({
account: account.name,
type: 'Bar',
color: colors[Math.floor(Math.random() * 4)].name
});
});
await dashboardSettings.set({
charts
});
await dashboardSettings.update();
}
async function setupRegionalChanges(country) {
const generateRegionalTaxes = require('../models/doctype/Tax/RegionalChanges');
await generateRegionalTaxes(country);
if (country === 'India') {
frappe.models.Party = require('../models/doctype/Party/RegionalChanges');
await frappe.db.migrate();
}
frappe.events.trigger('show-desk');
});
}
async function connectToLocalDatabase(filepath) {
try {

View File

@ -32,7 +32,7 @@ export default {
this.chartData.push({
title: c.account,
type: c.type.toLowerCase(),
color: c.color,
color: await frappe.db.getValue('Color', c.color, 'hexvalue'),
data: {
labels,
datasets

View File

@ -56,14 +56,8 @@ export default {
if (this.doc)
return [
{
title: this.meta.label || this.doctype,
route: '#/list/' + this.doctype
},
{
title: this.doc._notInserted
? 'New ' + (this.meta.label || this.doctype)
: this.doc.name,
route: ''
title: this.getFormTitle(),
route: '#/list/' + this.getListTitle()
}
];
},
@ -75,6 +69,13 @@ export default {
}
},
created() {
if (!this.defaults) {
this.defaults = {};
}
this.meta.fields.map(field => {
if (field.defaultValue)
this.defaults[field.fieldname] = field.defaultValue;
});
this.loadDoc();
},
methods: {
@ -94,9 +95,9 @@ export default {
this.doc.set('name', '');
}
if (this.defaultValues) {
for (let fieldname in this.defaultValues) {
const value = this.defaultValues[fieldname];
if (this.defaults) {
for (let fieldname in this.defaults) {
const value = this.defaults[fieldname];
this.doc.set(fieldname, value);
}
}
@ -105,9 +106,25 @@ export default {
this.doc.on('change', this.setLinks);
} catch (e) {
this.notFound = true;
this.$router.push(
`/list/${this.doctype === 'Party' ? 'Customer' : this.doctype}`
); //if reloaded while insert new Item,Invoice etc form.
}
},
getFormTitle() {
try {
// For different list/form based on same doctype since they will have different title
return (
this.meta.getFormTitle(this.doc) || this.meta.label || this.doctype
);
} catch (e) {
return this.meta.label || this.doctype;
}
},
getListTitle() {
try {
// For different list/form based on same doctype
// Since they will have different list route
return this.meta.getListTitle(this.doc);
} catch (e) {
return this.doctype;
}
},
async save() {

View File

@ -1,12 +1,19 @@
<template>
<div class="list-container">
<list-row class="text-muted rounded-top bg-light">
<list-cell v-for="column in columns" :key="column.label">{{ column.label }}</list-cell>
<list-cell
v-for="column in columns"
:key="column.label"
:class="['Float', 'Currency'].includes(column.fieldtype) ? 'text-right':''"
>{{ column.label }}</list-cell>
</list-row>
<list-row v-for="doc in data" :key="doc.name" @click.native="openForm(doc.name)">
<list-cell v-for="column in columns" :key="column.label" class="d-flex align-items-center">
<indicator v-if="column.getIndicator" :color="column.getIndicator(doc)" class="mr-2" />
<span>{{ frappe.format(column.getValue(doc), column.fieldtype || {}) }}</span>
<span
style="width: 100%"
:class="['Float', 'Currency'].includes(column.fieldtype) ? 'text-right':''"
>{{ frappe.format(column.getValue(doc), column.fieldtype || {}) }}</span>
</list-cell>
</list-row>
</div>
@ -18,28 +25,31 @@ import ListCell from './ListCell';
export default {
name: 'List',
props: ['listConfig'],
props: ['listConfig', 'filters'],
components: {
ListRow,
ListCell
},
watch: {
listConfig(oldValue, newValue) {
if (
oldValue.doctype !== newValue.doctype ||
// To differntiate Customer and Supplier List based on same Party Doctype
oldValue.title !== newValue.title
) {
if (oldValue.doctype !== newValue.doctype) {
this.setupColumnsAndData();
}
}
},
data() {
return {
columns: [],
data: []
};
},
computed: {
columns() {
return this.prepareColumns();
},
meta() {
return frappe.getMeta(this.listConfig.doctype);
}
},
async mounted() {
await this.setupColumnsAndData();
frappe.listView.on('filterList', this.updateData.bind(this));
@ -47,28 +57,40 @@ export default {
methods: {
async setupColumnsAndData() {
this.doctype = this.listConfig.doctype;
this.meta = frappe.getMeta(this.doctype);
await this.prepareColumns();
await this.updateData();
},
openForm(name) {
this.$router.push(`/edit/${this.doctype}/${name}`);
},
async updateData(keywords) {
let filters = this.listConfig.filters || null;
if (keywords) {
if (!filters) filters = {};
filters.keywords = ['like', keywords];
}
async updateData(filters) {
if (!filters) filters = this.getFilters();
// since passing filters as URL params which is String
filters = this.formatFilters(filters);
this.data = await frappe.db.getAll({
doctype: this.doctype,
fields: ['*'],
filters
});
},
getFilters() {
let filters = {};
Object.assign(filters, this.listConfig.filters || {});
Object.assign(filters, this.filters);
return filters;
},
formatFilters(filters) {
for (let key in filters) {
let value = filters[key];
this.meta.fields.forEach(field => {
if (field.fieldname === key) {
filters[key] = frappe.format(value, field.fieldtype);
}
});
}
return filters;
},
prepareColumns() {
this.columns = this.listConfig.columns
return this.listConfig.columns
.map(col => {
if (typeof col === 'string') {
const field = this.meta.getField(col);

View File

@ -0,0 +1,45 @@
<template>
<div :key="usedToReRender">
<div
class="mr-2 d-flex"
v-for="filter in Object.keys(currentFilters)"
:key="filter"
style="user-select: none; "
>
<span
class="p-0 pl-2 py-1 badge badge-light border lead d-flex align-items-center font-weight-normal"
>
{{ filter }} = "{{ currentFilters[filter] }}"
<feather-icon class="mb-1 mx-2" name="x" @click.native="removeFilter(filter)" />
</span>
</div>
</div>
</template>
<script>
export default {
name: 'ListFilters',
props: ['filters'],
data() {
return {
currentFilters: this.filters,
usedToReRender: 0
};
},
computed: {
filterValues() {
return this.currentFilters;
}
},
methods: {
removeFilter(filter) {
delete this.currentFilters[filter];
frappe.listView.trigger('filterList', this.currentFilters);
this.usedToReRender += 1;
}
}
};
</script>
<style scoped>
</style>

View File

@ -1,26 +1,23 @@
<template>
<div class="row">
<div class="col-6 d-flex">
<!-- <search-bar class="mr-2" @change="keyword => filterList(keyword)" /> -->
<div class="d-flex mt-2">
<div style="flex: 1;">
<list-filters :filters="filters"></list-filters>
</div>
<div class="col-6 d-flex flex-row-reverse">
<f-button primary @click="$emit('newClick')">{{ _('New {0}', listConfig.title) }}</f-button>
<div class="d-flex flex-column-reverse" style="padding-bottom: 1rem;">
<f-button primary @click="$emit('newClick')">{{ _('New {0}', title) }}</f-button>
</div>
</div>
</template>
<script>
import SearchBar from '@/components/SearchBar';
import ListFilters from './ListFilters';
export default {
name: 'ListToolbar',
props: ['listConfig'],
props: ['title', 'filters'],
components: {
SearchBar
},
methods: {
filterList(keyword) {
frappe.listView.trigger('filterList', keyword);
}
ListFilters
}
};
</script>

View File

@ -1,14 +1,9 @@
<template>
<div class="bg-white">
<page-header :title="listConfig.title" />
<page-header :title="title" />
<div class="px-4 py-3">
<list-toolbar
:listConfig="listConfig"
@newClick="openNewForm"
@filterList="keyword => filterList(keyword)"
class="mb-4"
/>
<list :listConfig="listConfig" />
<list-toolbar :title="title" :filters="filters" @newClick="openNewForm" class="mb-2" />
<list :listConfig="listConfig" :filters="filters" />
</div>
</div>
</template>
@ -22,7 +17,7 @@ import listConfigs from './listConfig';
export default {
name: 'ListView',
props: ['listName'],
props: ['listName', 'filters'],
components: {
PageHeader,
ListToolbar,
@ -38,6 +33,9 @@ export default {
if (this.listConfig.filters) {
doc.set(this.listConfig.filters);
}
if (this.filters) {
doc.set(this.filters);
}
this.$router.push(`/edit/${doctype}/${doc.name}`);
doc.on('afterInsert', () => {
this.$router.push(`/edit/${doctype}/${doc.name}`);
@ -58,6 +56,13 @@ export default {
});
this.$router.go(-1);
}
},
title() {
try {
return this.listConfig.title(this.filters);
} catch (e) {
return this.listConfig.title;
}
}
}
};

View File

@ -1,11 +1,11 @@
<template>
<div>
<div class="px-3">
<div class="row pb-4 d-flex">
<div>
<div class="pb-4 d-flex">
<page-header :breadcrumbs="breadcrumbs" style="flex-grow: 1;" />
<report-links class="d-flex flex-row-reverse" v-if="linksExists" :links="links"></report-links>
</div>
<div class="row pb-4 pl-1">
<div class="pl-1">
<report-filters
class="col-12"
v-if="shouldRenderFields"
@ -13,9 +13,10 @@
:filterDoc="filterDoc"
:filterDefaults="filters"
@change="getReportData"
:key="usedToReRender"
></report-filters>
</div>
<div class="pt-2 pr-2 pl-2" ref="datatable" v-once></div>
<div class="pt-2 px-4" ref="datatable" v-once></div>
</div>
<not-found v-if="!reportConfig" />
</div>
@ -34,6 +35,7 @@ export default {
data() {
return {
currentFilters: this.filters,
usedToReRender: 0,
filterDoc: undefined,
links: []
};
@ -43,7 +45,7 @@ export default {
return [
{
title: 'Reports',
route: '#/reportList'
route: ''
},
{
title: this.reportConfig.title,
@ -94,8 +96,15 @@ export default {
}
if (this.datatable) {
if (rows.length) this.datatable.refresh(rows, columns);
if (rows.length) {
this.datatable.refresh(rows, columns);
} else {
// remove all rows form datatable
this.datatable.wrapper.innerHTML = '';
this.datatable = undefined;
}
} else {
if (rows.length) {
this.datatable = new DataTable(this.$refs.datatable, {
columns: columns,
data: rows,
@ -103,6 +112,7 @@ export default {
cellHeight: 35
});
}
}
return [rows, columns];
},
setLinks() {

View File

@ -1,9 +1,9 @@
<template>
<div>
<page-header title="Settings" />
<div class="row">
<div class="col-12 bg-white border p-5">
<div class="col-9 col-lg-6 ml-1">
<div>
<div class="col-9 col-lg-7 col-xl-6 mx-2 mt-4">
<div>
<setting-section doctype="AccountingSettings" />
<hr class="mt-4" />
<setting-section doctype="CompanySettings" />

View File

@ -15,7 +15,7 @@
:doc="doc"
:fields="fields"
:layout="layout"
:currentSection="currentSection"
:currentSection="compCurrentSection"
/>
<div class="d-flex justify-content-between">
<div>
@ -80,6 +80,9 @@ export default {
}
},
computed: {
compCurrentSection() {
return this.currentSection;
},
fields() {
return this.meta.fields;
},

View File

@ -29,7 +29,13 @@ const routes = [
path: '/list/:listName',
name: 'ListView',
component: ListView,
props: true
props: route => {
const { listName } = route.params;
return {
listName,
filters: route.query
};
}
},
{
path: '/edit/:doctype/:name',