diff --git a/models/doctype/JournalEntry/JournalEntry.js b/models/doctype/JournalEntry/JournalEntry.js index 6f7dd513..9c0be3e1 100644 --- a/models/doctype/JournalEntry/JournalEntry.js +++ b/models/doctype/JournalEntry/JournalEntry.js @@ -24,48 +24,48 @@ export default { 'Excise Entry', 'Write Off Entry', 'Opening Entry', - 'Depreciation Entry' + 'Depreciation Entry', ], - required: 1 + required: 1, }, { fieldname: 'date', label: 'Date', fieldtype: 'Date', - default: DateTime.local().toISODate() + default: () => DateTime.local().toISODate(), }, { fieldname: 'accounts', label: 'Account Entries', fieldtype: 'Table', childtype: 'JournalEntryAccount', - required: true + required: true, }, { fieldname: 'referenceNumber', label: 'Reference Number', - fieldtype: 'Data' + fieldtype: 'Data', }, { fieldname: 'referenceDate', label: 'Reference Date', - fieldtype: 'Date' + fieldtype: 'Date', }, { fieldname: 'userRemark', label: 'User Remark', fieldtype: 'Text', - placeholder: 'User Remark' - } + placeholder: 'User Remark', + }, ], actions: [ { label: 'Revert', - condition: doc => doc.submitted, + condition: (doc) => doc.submitted, action(doc) { doc.revert(); - } + }, }, - ledgerLink - ] + ledgerLink, + ], }; diff --git a/models/doctype/Payment/Payment.js b/models/doctype/Payment/Payment.js index 227924ee..c326c66d 100644 --- a/models/doctype/Payment/Payment.js +++ b/models/doctype/Payment/Payment.js @@ -15,13 +15,13 @@ export default { label: 'Party', fieldtype: 'Link', target: 'Party', - required: 1 + required: 1, }, { fieldname: 'date', label: 'Posting Date', fieldtype: 'Date', - default: new Date().toISOString() + default: () => new Date().toISOString(), }, { fieldname: 'account', @@ -37,14 +37,14 @@ export default { return { accountType: ['in', ['Bank', 'Cash']], isGroup: 0 }; } } - } + }, }, { fieldname: 'paymentType', label: 'Payment Type', fieldtype: 'Select', options: ['', 'Receive', 'Pay'], - required: 1 + required: 1, }, { fieldname: 'paymentAccount', @@ -62,11 +62,11 @@ export default { } } }, - formula: doc => { + formula: (doc) => { if (doc.paymentMethod === 'Cash') { return 'Cash'; } - } + }, }, { fieldname: 'paymentMethod', @@ -74,37 +74,36 @@ export default { placeholder: 'Payment Method', fieldtype: 'Select', options: ['', 'Cash', 'Cheque', 'Transfer'], - required: 1 + required: 1, }, { fieldname: 'referenceId', label: 'Ref. / Cheque No.', placeholder: 'Ref. / Cheque No.', fieldtype: 'Data', - required: 1 // TODO: UNIQUE + required: (doc) => doc.paymentMethod !== 'Cash', // TODO: UNIQUE }, { fieldname: 'referenceDate', label: 'Ref. Date', placeholder: 'Ref. Date', - fieldtype: 'Date' + fieldtype: 'Date', }, { fieldname: 'clearanceDate', label: 'Clearance Date', placeholder: 'Clearance Date', fieldtype: 'Date', - hidden: doc => { - return doc.paymentMethod === 'Cash' ? 1 : 0; - } + hidden: (doc) => doc.paymentMethod === 'Cash', }, { fieldname: 'amount', label: 'Amount', fieldtype: 'Currency', required: 1, - formula: doc => doc.getSum('for', 'amount'), + formula: (doc) => doc.getSum('for', 'amount'), validate(value, doc) { + if (doc.for.length === 0) return; const amount = doc.getSum('for', 'amount'); if (value > amount) { @@ -119,24 +118,27 @@ export default { } else if (value === 0) { throw new frappe.errors.ValidationError( frappe._( - `Payment amount cannot be ${frappe.format(value, 'Currency')}. Amount has been reset to max viable amount.` + `Payment amount cannot be ${frappe.format( + value, + 'Currency' + )}. Amount has been reset to max viable amount.` ) ); } - } + }, }, { fieldname: 'writeoff', label: 'Write Off / Refund', - fieldtype: 'Currency' + fieldtype: 'Currency', }, { fieldname: 'for', - label: 'Payment For', + label: 'Payment Reference', fieldtype: 'Table', childtype: 'PaymentFor', - required: 1 - } + required: 0, + }, ], quickEditFields: [ @@ -151,58 +153,68 @@ export default { 'clearanceDate', 'amount', 'writeoff', - 'for' + 'for', ], layout: [ { columns: [ { - fields: ['party', 'account'] + fields: ['party', 'account'], }, { - fields: ['date', 'paymentAccount'] - } - ] + fields: ['date', 'paymentAccount'], + }, + ], }, { columns: [ { - fields: ['paymentMethod'] + fields: ['paymentMethod'], }, { - fields: ['paymentType'] + fields: ['paymentType'], }, { - fields: ['referenceId'] - } - ] + fields: ['referenceId'], + }, + ], }, { columns: [ { - fields: ['referenceDate'] + fields: ['referenceDate'], }, { - fields: ['clearanceDate'] - } - ] + fields: ['clearanceDate'], + }, + ], }, { columns: [ { - fields: ['for'] - } - ] + fields: ['for'], + }, + ], }, { columns: [ { - fields: ['amount', 'writeoff'] - } - ] - } + fields: ['amount', 'writeoff'], + }, + ], + }, + ], + actions: [ + { + label: 'Revert', + condition: (doc) => doc.submitted, + action(doc) { + doc.revert(); + }, + }, + utils.ledgerLink, ], - links: [utils.ledgerLink] + links: [utils.ledgerLink], }; diff --git a/models/doctype/Payment/PaymentServer.js b/models/doctype/Payment/PaymentServer.js index 441f25e0..7ffe4aaf 100644 --- a/models/doctype/Payment/PaymentServer.js +++ b/models/doctype/Payment/PaymentServer.js @@ -20,8 +20,8 @@ export default class PaymentServer extends BaseDocument { } async beforeSubmit() { - if (!this.for.length) { - throw new Error(`No reference for the payment.`); + if (!this.for || !this.for.length) { + return; } for (let row of this.for) { if (!['SalesInvoice', 'PurchaseInvoice'].includes(row.referenceType)) { @@ -36,9 +36,14 @@ export default class PaymentServer extends BaseDocument { outstandingAmount = baseGrandTotal; } if (this.amount <= 0 || this.amount > outstandingAmount) { - throw new Error( - `Payment amount (${this.amount}) should be greater than 0 and less than Outstanding amount (${outstandingAmount})` + let message = frappe._( + `Payment amount (${this.amount}) should be less than Outstanding amount (${outstandingAmount}).` ); + if (this.amount <= 0) { + const amt = this.amount < 0 ? ` (${this.amount})` : ''; + message = frappe._(`Payment amount${amt} should be greater than 0.`); + } + throw new frappe.errors.ValidationError(message); } else { // update outstanding amounts in invoice and party let newOutstanding = outstandingAmount - this.amount; @@ -61,4 +66,4 @@ export default class PaymentServer extends BaseDocument { // Maybe revert outstanding amount of invoice too? } -}; +} diff --git a/models/doctype/PurchaseInvoice/PurchaseInvoice.js b/models/doctype/PurchaseInvoice/PurchaseInvoice.js index fcde430e..e3c48ee6 100644 --- a/models/doctype/PurchaseInvoice/PurchaseInvoice.js +++ b/models/doctype/PurchaseInvoice/PurchaseInvoice.js @@ -26,7 +26,7 @@ export default { fieldname: 'date', label: 'Date', fieldtype: 'Date', - default: new Date().toISOString().slice(0, 10) + default: () => new Date().toISOString().slice(0, 10) }, { fieldname: 'supplier', diff --git a/models/doctype/SalesInvoice/SalesInvoice.js b/models/doctype/SalesInvoice/SalesInvoice.js index c5fac95a..ae60e393 100644 --- a/models/doctype/SalesInvoice/SalesInvoice.js +++ b/models/doctype/SalesInvoice/SalesInvoice.js @@ -19,20 +19,20 @@ export default { fieldname: 'name', fieldtype: 'Data', required: 1, - readOnly: 1 + readOnly: 1, }, { fieldname: 'date', label: 'Date', fieldtype: 'Date', - default: new Date().toISOString().slice(0, 10) + default: () => new Date().toISOString().slice(0, 10), }, { fieldname: 'customer', label: 'Customer', fieldtype: 'Link', target: 'Customer', - required: 1 + required: 1, }, { fieldname: 'account', @@ -40,90 +40,90 @@ export default { fieldtype: 'Link', target: 'Account', disableCreation: true, - formula: doc => doc.getFrom('Party', doc.customer, 'defaultAccount'), + formula: (doc) => doc.getFrom('Party', doc.customer, 'defaultAccount'), getFilters: () => { return { isGroup: 0, - accountType: 'Receivable' + accountType: 'Receivable', }; - } + }, }, { fieldname: 'currency', label: 'Customer Currency', fieldtype: 'Link', target: 'Currency', - formula: doc => doc.getFrom('Party', doc.customer, 'currency'), - formulaDependsOn: ['customer'] + formula: (doc) => doc.getFrom('Party', doc.customer, 'currency'), + formulaDependsOn: ['customer'], }, { fieldname: 'exchangeRate', label: 'Exchange Rate', fieldtype: 'Float', - formula: doc => doc.getExchangeRate(), - readOnly: true + formula: (doc) => doc.getExchangeRate(), + readOnly: true, }, { fieldname: 'items', label: 'Items', fieldtype: 'Table', childtype: 'SalesInvoiceItem', - required: true + required: true, }, { fieldname: 'netTotal', label: 'Net Total', fieldtype: 'Currency', - formula: doc => doc.getSum('items', 'amount'), + formula: (doc) => doc.getSum('items', 'amount'), readOnly: 1, - getCurrency: doc => doc.currency + getCurrency: (doc) => doc.currency, }, { fieldname: 'baseNetTotal', label: 'Net Total (Company Currency)', fieldtype: 'Currency', - formula: doc => doc.netTotal * doc.exchangeRate, - readOnly: 1 + formula: (doc) => doc.netTotal * doc.exchangeRate, + readOnly: 1, }, { fieldname: 'taxes', label: 'Taxes', fieldtype: 'Table', childtype: 'TaxSummary', - formula: doc => doc.getTaxSummary(), - readOnly: 1 + formula: (doc) => doc.getTaxSummary(), + readOnly: 1, }, { fieldname: 'grandTotal', label: 'Grand Total', fieldtype: 'Currency', - formula: doc => doc.getGrandTotal(), + formula: (doc) => doc.getGrandTotal(), readOnly: 1, - getCurrency: doc => doc.currency + getCurrency: (doc) => doc.currency, }, { fieldname: 'baseGrandTotal', label: 'Grand Total (Company Currency)', fieldtype: 'Currency', - formula: doc => doc.grandTotal * doc.exchangeRate, - readOnly: 1 + formula: (doc) => doc.grandTotal * doc.exchangeRate, + readOnly: 1, }, { fieldname: 'outstandingAmount', label: 'Outstanding Amount', fieldtype: 'Currency', - formula: doc => { + formula: (doc) => { if (doc.submitted) return; return doc.baseGrandTotal; }, - readOnly: 1 + readOnly: 1, }, { fieldname: 'terms', label: 'Notes', - fieldtype: 'Text' - } + fieldtype: 'Text', + }, ], - actions: getActions('SalesInvoice') + actions: getActions('SalesInvoice'), }; diff --git a/patches/patches.txt b/patches/patches.txt index e69de29b..bddd2fe4 100644 --- a/patches/patches.txt +++ b/patches/patches.txt @@ -0,0 +1 @@ +v0_0_3/makePaymentRefIdNullable \ No newline at end of file diff --git a/patches/v0_0_3/makePaymentRefIdNullable.js b/patches/v0_0_3/makePaymentRefIdNullable.js new file mode 100644 index 00000000..bab77c3f --- /dev/null +++ b/patches/v0_0_3/makePaymentRefIdNullable.js @@ -0,0 +1,28 @@ +import frappe from 'frappejs'; + +export default async function execute() { + // Since sqlite has no ALTER TABLE to change column meta + // the table has to be _Prestiged_. + const tableInfo = await frappe.db.sql('pragma table_info("Payment")'); + const referenceId = tableInfo.find(({ name }) => name === 'referenceId'); + if (!referenceId || !referenceId.notnull) { + return; + } + + await frappe.db.createTable('Payment', '__Payment'); + await frappe.db.sql('insert into __Payment select * from Payment'); + + const mainCount = await frappe.db.knex + .table('Payment') + .count('name as count'); + const replCount = await frappe.db.knex + .table('__Payment') + .count('name as count'); + + if (mainCount[0].count === replCount[0].count) { + await frappe.db.knex.schema.dropTable('Payment'); + await frappe.db.knex.schema.renameTable('__Payment', 'Payment'); + } else { + await frappe.db.knex.schema.dropTable('__Payment'); + } +} diff --git a/src/components/TwoColumnForm.vue b/src/components/TwoColumnForm.vue index dd711d25..b10f2c2e 100644 --- a/src/components/TwoColumnForm.vue +++ b/src/components/TwoColumnForm.vue @@ -8,7 +8,8 @@ size="small" :df="df" :value="doc[df.fieldname]" - @change="value => onChange(df, value)" + :read-only="submitted" + @change="(value) => onChange(df, value)" />