mirror of
https://github.com/frappe/books.git
synced 2024-12-22 19:09:01 +00:00
refactor: rename "Payment For" to "References"
- formatting - change default values to function defaults - add migration script for the Payment table
This commit is contained in:
parent
09d4b305eb
commit
8f64d95055
@ -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,
|
||||
],
|
||||
};
|
||||
|
@ -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,36 +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: (doc) => doc.paymentMethod !== 'Cash' // 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) => doc.paymentMethod === 'Cash'
|
||||
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;
|
||||
if (doc.for.length === 0) return;
|
||||
const amount = doc.getSum('for', 'amount');
|
||||
|
||||
if (value > amount) {
|
||||
@ -118,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: 0,
|
||||
}
|
||||
},
|
||||
],
|
||||
|
||||
quickEditFields: [
|
||||
@ -150,58 +153,58 @@ 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'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
links: [utils.ledgerLink]
|
||||
links: [utils.ledgerLink],
|
||||
};
|
||||
|
@ -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)) {
|
||||
|
@ -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',
|
||||
|
@ -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'),
|
||||
};
|
||||
|
@ -0,0 +1 @@
|
||||
v0_0_3/makePaymentRefIdNullable
|
28
patches/v0_0_3/makePaymentRefIdNullable.js
Normal file
28
patches/v0_0_3/makePaymentRefIdNullable.js
Normal file
@ -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');
|
||||
}
|
||||
}
|
@ -6,11 +6,11 @@ const requirePatch = require.context('../patches', true, /\w+\.(js)$/);
|
||||
export default async function runMigrate() {
|
||||
let patchOrder = patchesTxt.split('\n');
|
||||
let allPatches = {};
|
||||
requirePatch.keys().forEach(fileName => {
|
||||
requirePatch.keys().forEach((fileName) => {
|
||||
if (fileName === './index.js') return;
|
||||
let method;
|
||||
try {
|
||||
method = requirePatch(fileName);
|
||||
method = requirePatch(fileName).default;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
method = null;
|
||||
|
Loading…
Reference in New Issue
Block a user