merged
This commit is contained in:
commit
8c747ce5cf
@ -7,8 +7,8 @@ context('Form', () => {
|
|||||||
it('create a new opportunity', () => {
|
it('create a new opportunity', () => {
|
||||||
cy.visit('/desk#Form/Opportunity/New Opportunity 1');
|
cy.visit('/desk#Form/Opportunity/New Opportunity 1');
|
||||||
cy.get('.page-title').should('contain', 'Not Saved');
|
cy.get('.page-title').should('contain', 'Not Saved');
|
||||||
cy.fill_field('enquiry_from', 'Customer', 'Select');
|
cy.fill_field('opportunity_from', 'Customer', 'Select');
|
||||||
cy.fill_field('customer', 'Test Customer', 'Link').blur();
|
cy.fill_field('party_name', 'Test Customer', 'Link').blur();
|
||||||
cy.get('.primary-action').click();
|
cy.get('.primary-action').click();
|
||||||
cy.get('.page-title').should('contain', 'Open');
|
cy.get('.page-title').should('contain', 'Open');
|
||||||
cy.get('.form-inner-toolbar button:contains("Lost")').click({ force: true });
|
cy.get('.form-inner-toolbar button:contains("Lost")').click({ force: true });
|
||||||
@ -29,4 +29,3 @@ context('Form', () => {
|
|||||||
cy.get('.page-title').should('contain', 'Lost');
|
cy.get('.page-title').should('contain', 'Lost');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import frappe
|
|||||||
from erpnext.hooks import regional_overrides
|
from erpnext.hooks import regional_overrides
|
||||||
from frappe.utils import getdate
|
from frappe.utils import getdate
|
||||||
|
|
||||||
__version__ = '11.1.20'
|
__version__ = '11.1.39'
|
||||||
|
|
||||||
def get_default_company(user=None):
|
def get_default_company(user=None):
|
||||||
'''Get default company for user'''
|
'''Get default company for user'''
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"country_code": "de",
|
"country_code": "de",
|
||||||
"name": "Germany - Kontenplan SKR04",
|
"name": "SKR04 ohne Kontonummern",
|
||||||
"tree": {
|
"tree": {
|
||||||
"Bilanz - Aktiva": {
|
"Bilanz - Aktiva": {
|
||||||
"Anlageverm\u00f6gen": {
|
"Anlageverm\u00f6gen": {
|
||||||
@ -1383,8 +1383,7 @@
|
|||||||
"Sonstige Zinsen und \u00e4hnliche Ertr\u00e4ge 1": {
|
"Sonstige Zinsen und \u00e4hnliche Ertr\u00e4ge 1": {
|
||||||
"Diskontertr\u00e4ge": {},
|
"Diskontertr\u00e4ge": {},
|
||||||
"Diskontertr\u00e4ge aus verbundenen Unternehmen": {},
|
"Diskontertr\u00e4ge aus verbundenen Unternehmen": {},
|
||||||
"Laufende Ertr\u00e4ge aus Anteilen an Kapitalgesellschaften 100% / 50% steuerfrei": {},
|
"Laufende Ertr\u00e4ge aus Anteilen an Kapitalgesellschaften 100% / 50% steuerfrei": {},
|
||||||
"Laufende Ertr\u00e4ge aus Anteilen an Kapitalgesellschaften 100% / 50% steuerfrei": {},
|
|
||||||
"Sonstige Zinsen und \u00e4hnliche Ertr\u00e4ge 2": {},
|
"Sonstige Zinsen und \u00e4hnliche Ertr\u00e4ge 2": {},
|
||||||
"Sonstige Zinsen und \u00e4hnliche Ertr\u00e4ge aus verbundenen Unternehmen": {},
|
"Sonstige Zinsen und \u00e4hnliche Ertr\u00e4ge aus verbundenen Unternehmen": {},
|
||||||
"Sonstige Zinsertr\u00e4ge": {},
|
"Sonstige Zinsertr\u00e4ge": {},
|
||||||
@ -1703,4 +1702,4 @@
|
|||||||
"root_type": "Asset"
|
"root_type": "Asset"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -38,24 +38,24 @@
|
|||||||
"Kas": {
|
"Kas": {
|
||||||
"Kas Mata Uang Lain": {
|
"Kas Mata Uang Lain": {
|
||||||
"Kas USD": {
|
"Kas USD": {
|
||||||
"account_number": "1112.0010",
|
"account_number": "1112.001",
|
||||||
"account_type": "Cash"
|
"account_type": "Cash"
|
||||||
},
|
},
|
||||||
"account_number": "1112.000"
|
"account_number": "1112.000"
|
||||||
},
|
},
|
||||||
"Kas Rupiah": {
|
"Kas Rupiah": {
|
||||||
"Kas Besar": {
|
"Kas Besar": {
|
||||||
"account_number": "1111.0020",
|
"account_number": "1111.002",
|
||||||
"account_type": "Cash"
|
"account_type": "Cash"
|
||||||
},
|
},
|
||||||
"Kas Kecil": {
|
"Kas Kecil": {
|
||||||
"account_number": "1111.0010",
|
"account_number": "1111.001",
|
||||||
"account_type": "Cash"
|
"account_type": "Cash"
|
||||||
},
|
},
|
||||||
"account_number": "1111.000",
|
"account_number": "1111.000",
|
||||||
"account_type": "Cash"
|
"account_type": "Cash"
|
||||||
},
|
},
|
||||||
"account_number": "1110.0000"
|
"account_number": "1110.000"
|
||||||
},
|
},
|
||||||
"Pendapatan Yang Akan di Terima": {
|
"Pendapatan Yang Akan di Terima": {
|
||||||
"Pendapatan Yang di Terima": {
|
"Pendapatan Yang di Terima": {
|
||||||
@ -98,7 +98,7 @@
|
|||||||
},
|
},
|
||||||
"account_number": "1130.000"
|
"account_number": "1130.000"
|
||||||
},
|
},
|
||||||
"account_number": "1100.0000"
|
"account_number": "1100.000"
|
||||||
},
|
},
|
||||||
"Aktiva Tetap": {
|
"Aktiva Tetap": {
|
||||||
"Aktiva": {
|
"Aktiva": {
|
||||||
@ -121,20 +121,20 @@
|
|||||||
"Investasi": {
|
"Investasi": {
|
||||||
"Investasi": {
|
"Investasi": {
|
||||||
"Deposito": {
|
"Deposito": {
|
||||||
"account_number": "1231.003",
|
"account_number": "1231.300",
|
||||||
"is_group": 1
|
"is_group": 1
|
||||||
},
|
},
|
||||||
"Investai Saham": {
|
"Investasi Saham": {
|
||||||
"Investasi Saham": {
|
"Investasi Saham": {
|
||||||
"account_number": "1231.0011"
|
"account_number": "1231.101"
|
||||||
},
|
},
|
||||||
"account_number": "1231.001"
|
"account_number": "1231.100"
|
||||||
},
|
},
|
||||||
"Investasi Perumahan": {
|
"Investasi Perumahan": {
|
||||||
"Investasi Perumahan": {
|
"Investasi Perumahan": {
|
||||||
"account_number": "1231.0021"
|
"account_number": "1231.201"
|
||||||
},
|
},
|
||||||
"account_number": "1231.002"
|
"account_number": "1231.200"
|
||||||
},
|
},
|
||||||
"account_number": "1231.000"
|
"account_number": "1231.000"
|
||||||
},
|
},
|
||||||
@ -142,7 +142,7 @@
|
|||||||
},
|
},
|
||||||
"account_number": "1200.000"
|
"account_number": "1200.000"
|
||||||
},
|
},
|
||||||
"account_number": "1000.0000",
|
"account_number": "1000.000",
|
||||||
"root_type": "Asset"
|
"root_type": "Asset"
|
||||||
},
|
},
|
||||||
"Beban": {
|
"Beban": {
|
||||||
@ -684,4 +684,4 @@
|
|||||||
"root_type": "Income"
|
"root_type": "Income"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('Account Subtype', {
|
||||||
|
refresh: function() {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
134
erpnext/accounts/doctype/account_subtype/account_subtype.json
Normal file
134
erpnext/accounts/doctype/account_subtype/account_subtype.json
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 1,
|
||||||
|
"allow_rename": 1,
|
||||||
|
"autoname": "field:account_subtype",
|
||||||
|
"beta": 0,
|
||||||
|
"creation": "2018-10-25 15:46:08.054586",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "account_subtype",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Account Subtype",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
|
"hide_heading": 0,
|
||||||
|
"hide_toolbar": 0,
|
||||||
|
"idx": 0,
|
||||||
|
"image_view": 0,
|
||||||
|
"in_create": 0,
|
||||||
|
"is_submittable": 0,
|
||||||
|
"issingle": 0,
|
||||||
|
"istable": 0,
|
||||||
|
"max_attachments": 0,
|
||||||
|
"modified": "2018-10-25 15:47:03.841390",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Account Subtype",
|
||||||
|
"name_case": "",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 0,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Accounts Manager",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 0,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Accounts User",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 0,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 0,
|
||||||
|
"track_seen": 0,
|
||||||
|
"track_views": 0
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and contributors
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class ProjectTask(Document):
|
class AccountSubtype(Document):
|
||||||
pass
|
pass
|
@ -0,0 +1,23 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// rename this file from _test_[name] to test_[name] to activate
|
||||||
|
// and remove above this line
|
||||||
|
|
||||||
|
QUnit.test("test: Account Subtype", function (assert) {
|
||||||
|
let done = assert.async();
|
||||||
|
|
||||||
|
// number of asserts
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
frappe.run_serially([
|
||||||
|
// insert a new Account Subtype
|
||||||
|
() => frappe.tests.make('Account Subtype', [
|
||||||
|
// values to be set
|
||||||
|
{key: 'value'}
|
||||||
|
]),
|
||||||
|
() => {
|
||||||
|
assert.equal(cur_frm.doc.key, 'value');
|
||||||
|
},
|
||||||
|
() => done()
|
||||||
|
]);
|
||||||
|
|
||||||
|
});
|
@ -0,0 +1,9 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestAccountSubtype(unittest.TestCase):
|
||||||
|
pass
|
0
erpnext/accounts/doctype/account_type/__init__.py
Normal file
0
erpnext/accounts/doctype/account_type/__init__.py
Normal file
8
erpnext/accounts/doctype/account_type/account_type.js
Normal file
8
erpnext/accounts/doctype/account_type/account_type.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('Account Type', {
|
||||||
|
refresh: function() {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
134
erpnext/accounts/doctype/account_type/account_type.json
Normal file
134
erpnext/accounts/doctype/account_type/account_type.json
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 1,
|
||||||
|
"allow_rename": 1,
|
||||||
|
"autoname": "field:account_type",
|
||||||
|
"beta": 0,
|
||||||
|
"creation": "2018-10-25 15:45:45.789963",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "account_type",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Account Type",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
|
"hide_heading": 0,
|
||||||
|
"hide_toolbar": 0,
|
||||||
|
"idx": 0,
|
||||||
|
"image_view": 0,
|
||||||
|
"in_create": 0,
|
||||||
|
"is_submittable": 0,
|
||||||
|
"issingle": 0,
|
||||||
|
"istable": 0,
|
||||||
|
"max_attachments": 0,
|
||||||
|
"modified": "2018-10-25 15:46:51.042604",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Account Type",
|
||||||
|
"name_case": "",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 0,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Accounts Manager",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 0,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Accounts User",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 0,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 0,
|
||||||
|
"track_seen": 0,
|
||||||
|
"track_views": 0
|
||||||
|
}
|
9
erpnext/accounts/doctype/account_type/account_type.py
Normal file
9
erpnext/accounts/doctype/account_type/account_type.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class AccountType(Document):
|
||||||
|
pass
|
23
erpnext/accounts/doctype/account_type/test_account_type.js
Normal file
23
erpnext/accounts/doctype/account_type/test_account_type.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// rename this file from _test_[name] to test_[name] to activate
|
||||||
|
// and remove above this line
|
||||||
|
|
||||||
|
QUnit.test("test: Account Type", function (assert) {
|
||||||
|
let done = assert.async();
|
||||||
|
|
||||||
|
// number of asserts
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
frappe.run_serially([
|
||||||
|
// insert a new Account Type
|
||||||
|
() => frappe.tests.make('Account Type', [
|
||||||
|
// values to be set
|
||||||
|
{key: 'value'}
|
||||||
|
]),
|
||||||
|
() => {
|
||||||
|
assert.equal(cur_frm.doc.key, 'value');
|
||||||
|
},
|
||||||
|
() => done()
|
||||||
|
]);
|
||||||
|
|
||||||
|
});
|
@ -0,0 +1,9 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestAccountType(unittest.TestCase):
|
||||||
|
pass
|
@ -9,6 +9,26 @@ frappe.ui.form.on('Accounting Dimension', {
|
|||||||
frappe.set_route("List", frm.doc.document_type);
|
frappe.set_route("List", frm.doc.document_type);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let button = frm.doc.disabled ? "Enable" : "Disable";
|
||||||
|
|
||||||
|
frm.add_custom_button(__(button), function() {
|
||||||
|
|
||||||
|
frm.set_value('disabled', 1 - frm.doc.disabled);
|
||||||
|
|
||||||
|
frappe.call({
|
||||||
|
method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.disable_dimension",
|
||||||
|
args: {
|
||||||
|
doc: frm.doc
|
||||||
|
},
|
||||||
|
freeze: true,
|
||||||
|
callback: function(r) {
|
||||||
|
let message = frm.doc.disabled ? "Dimension Disabled" : "Dimension Enabled";
|
||||||
|
frm.save();
|
||||||
|
frappe.show_alert({message:__(message), indicator:'green'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
document_type: function(frm) {
|
document_type: function(frm) {
|
||||||
@ -21,13 +41,4 @@ frappe.ui.form.on('Accounting Dimension', {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
disabled: function(frm) {
|
|
||||||
frappe.call({
|
|
||||||
method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.disable_dimension",
|
|
||||||
args: {
|
|
||||||
doc: frm.doc
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
@ -38,7 +38,8 @@
|
|||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "disabled",
|
"fieldname": "disabled",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Disable"
|
"label": "Disable",
|
||||||
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
@ -53,7 +54,7 @@
|
|||||||
"label": "Mandatory For Profit and Loss Account"
|
"label": "Mandatory For Profit and Loss Account"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2019-05-27 18:18:17.792726",
|
"modified": "2019-07-07 18:56:19.517450",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounting Dimension",
|
"name": "Accounting Dimension",
|
||||||
|
@ -121,11 +121,11 @@ def delete_accounting_dimension(doc):
|
|||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def disable_dimension(doc):
|
def disable_dimension(doc):
|
||||||
if frappe.flags.in_test:
|
if frappe.flags.in_test:
|
||||||
frappe.enqueue(start_dimension_disabling, doc=doc)
|
toggle_disabling(doc=doc)
|
||||||
else:
|
else:
|
||||||
start_dimension_disabling(doc=doc)
|
frappe.enqueue(toggle_disabling, doc=doc)
|
||||||
|
|
||||||
def start_dimension_disabling(doc):
|
def toggle_disabling(doc):
|
||||||
doc = json.loads(doc)
|
doc = json.loads(doc)
|
||||||
|
|
||||||
if doc.get('disabled'):
|
if doc.get('disabled'):
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
class AccountingPeriod(Document):
|
class AccountingPeriod(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
@ -16,7 +17,7 @@ class AccountingPeriod(Document):
|
|||||||
def autoname(self):
|
def autoname(self):
|
||||||
company_abbr = frappe.get_cached_value('Company', self.company, "abbr")
|
company_abbr = frappe.get_cached_value('Company', self.company, "abbr")
|
||||||
self.name = " - ".join([self.period_name, company_abbr])
|
self.name = " - ".join([self.period_name, company_abbr])
|
||||||
|
|
||||||
def validate_overlap(self):
|
def validate_overlap(self):
|
||||||
existing_accounting_period = frappe.db.sql("""select name from `tabAccounting Period`
|
existing_accounting_period = frappe.db.sql("""select name from `tabAccounting Period`
|
||||||
where (
|
where (
|
||||||
@ -33,7 +34,7 @@ class AccountingPeriod(Document):
|
|||||||
}, as_dict=True)
|
}, as_dict=True)
|
||||||
|
|
||||||
if len(existing_accounting_period) > 0:
|
if len(existing_accounting_period) > 0:
|
||||||
frappe.throw("Accounting Period overlaps with {0}".format(existing_accounting_period[0].get("name")))
|
frappe.throw(_("Accounting Period overlaps with {0}".format(existing_accounting_period[0].get("name"))))
|
||||||
|
|
||||||
def get_doctypes_for_closing(self):
|
def get_doctypes_for_closing(self):
|
||||||
docs_for_closing = []
|
docs_for_closing = []
|
||||||
|
@ -1,203 +1,203 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-06-24 15:49:57",
|
"creation": "2013-06-24 15:49:57",
|
||||||
"description": "Settings for Accounts",
|
"description": "Settings for Accounts",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Other",
|
"document_type": "Other",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"auto_accounting_for_stock",
|
"auto_accounting_for_stock",
|
||||||
"acc_frozen_upto",
|
"acc_frozen_upto",
|
||||||
"frozen_accounts_modifier",
|
"frozen_accounts_modifier",
|
||||||
"determine_address_tax_category_from",
|
"determine_address_tax_category_from",
|
||||||
"column_break_4",
|
"column_break_4",
|
||||||
"credit_controller",
|
"credit_controller",
|
||||||
"check_supplier_invoice_uniqueness",
|
"check_supplier_invoice_uniqueness",
|
||||||
"make_payment_via_journal_entry",
|
"make_payment_via_journal_entry",
|
||||||
"unlink_payment_on_cancellation_of_invoice",
|
"unlink_payment_on_cancellation_of_invoice",
|
||||||
"unlink_advance_payment_on_cancelation_of_order",
|
"unlink_advance_payment_on_cancelation_of_order",
|
||||||
"book_asset_depreciation_entry_automatically",
|
"book_asset_depreciation_entry_automatically",
|
||||||
"allow_cost_center_in_entry_of_bs_account",
|
"allow_cost_center_in_entry_of_bs_account",
|
||||||
"add_taxes_from_item_tax_template",
|
"add_taxes_from_item_tax_template",
|
||||||
"automatically_fetch_payment_terms",
|
"automatically_fetch_payment_terms",
|
||||||
"print_settings",
|
"print_settings",
|
||||||
"show_inclusive_tax_in_print",
|
"show_inclusive_tax_in_print",
|
||||||
"column_break_12",
|
"column_break_12",
|
||||||
"show_payment_schedule_in_print",
|
"show_payment_schedule_in_print",
|
||||||
"currency_exchange_section",
|
"currency_exchange_section",
|
||||||
"allow_stale",
|
"allow_stale",
|
||||||
"stale_days",
|
"stale_days",
|
||||||
"report_settings_sb",
|
"report_settings_sb",
|
||||||
"use_custom_cash_flow"
|
"use_custom_cash_flow"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"description": "If enabled, the system will post accounting entries for inventory automatically.",
|
"description": "If enabled, the system will post accounting entries for inventory automatically.",
|
||||||
"fieldname": "auto_accounting_for_stock",
|
"fieldname": "auto_accounting_for_stock",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Make Accounting Entry For Every Stock Movement"
|
"label": "Make Accounting Entry For Every Stock Movement"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Accounting entry frozen up to this date, nobody can do / modify entry except role specified below.",
|
"description": "Accounting entry frozen up to this date, nobody can do / modify entry except role specified below.",
|
||||||
"fieldname": "acc_frozen_upto",
|
"fieldname": "acc_frozen_upto",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Accounts Frozen Upto"
|
"label": "Accounts Frozen Upto"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Users with this role are allowed to set frozen accounts and create / modify accounting entries against frozen accounts",
|
"description": "Users with this role are allowed to set frozen accounts and create / modify accounting entries against frozen accounts",
|
||||||
"fieldname": "frozen_accounts_modifier",
|
"fieldname": "frozen_accounts_modifier",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Role Allowed to Set Frozen Accounts & Edit Frozen Entries",
|
"label": "Role Allowed to Set Frozen Accounts & Edit Frozen Entries",
|
||||||
"options": "Role"
|
"options": "Role"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "Billing Address",
|
"default": "Billing Address",
|
||||||
"description": "Address used to determine Tax Category in transactions.",
|
"description": "Address used to determine Tax Category in transactions.",
|
||||||
"fieldname": "determine_address_tax_category_from",
|
"fieldname": "determine_address_tax_category_from",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Determine Address Tax Category From",
|
"label": "Determine Address Tax Category From",
|
||||||
"options": "Billing Address\nShipping Address"
|
"options": "Billing Address\nShipping Address"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_4",
|
"fieldname": "column_break_4",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Role that is allowed to submit transactions that exceed credit limits set.",
|
"description": "Role that is allowed to submit transactions that exceed credit limits set.",
|
||||||
"fieldname": "credit_controller",
|
"fieldname": "credit_controller",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Credit Controller",
|
"label": "Credit Controller",
|
||||||
"options": "Role"
|
"options": "Role"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "check_supplier_invoice_uniqueness",
|
"fieldname": "check_supplier_invoice_uniqueness",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Check Supplier Invoice Number Uniqueness"
|
"label": "Check Supplier Invoice Number Uniqueness"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "make_payment_via_journal_entry",
|
"fieldname": "make_payment_via_journal_entry",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Make Payment via Journal Entry"
|
"label": "Make Payment via Journal Entry"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"fieldname": "unlink_payment_on_cancellation_of_invoice",
|
"fieldname": "unlink_payment_on_cancellation_of_invoice",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Unlink Payment on Cancellation of Invoice"
|
"label": "Unlink Payment on Cancellation of Invoice"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"fieldname": "unlink_advance_payment_on_cancelation_of_order",
|
"fieldname": "unlink_advance_payment_on_cancelation_of_order",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Unlink Advance Payment on Cancelation of Order"
|
"label": "Unlink Advance Payment on Cancelation of Order"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"fieldname": "book_asset_depreciation_entry_automatically",
|
"fieldname": "book_asset_depreciation_entry_automatically",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Book Asset Depreciation Entry Automatically"
|
"label": "Book Asset Depreciation Entry Automatically"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "allow_cost_center_in_entry_of_bs_account",
|
"fieldname": "allow_cost_center_in_entry_of_bs_account",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Allow Cost Center In Entry of Balance Sheet Account"
|
"label": "Allow Cost Center In Entry of Balance Sheet Account"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"fieldname": "add_taxes_from_item_tax_template",
|
"fieldname": "add_taxes_from_item_tax_template",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Automatically Add Taxes and Charges from Item Tax Template"
|
"label": "Automatically Add Taxes and Charges from Item Tax Template"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "print_settings",
|
"fieldname": "print_settings",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Print Settings"
|
"label": "Print Settings"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "show_inclusive_tax_in_print",
|
"fieldname": "show_inclusive_tax_in_print",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Show Inclusive Tax In Print"
|
"label": "Show Inclusive Tax In Print"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_12",
|
"fieldname": "column_break_12",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "show_payment_schedule_in_print",
|
"fieldname": "show_payment_schedule_in_print",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Show Payment Schedule in Print"
|
"label": "Show Payment Schedule in Print"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "currency_exchange_section",
|
"fieldname": "currency_exchange_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Currency Exchange Settings"
|
"label": "Currency Exchange Settings"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"fieldname": "allow_stale",
|
"fieldname": "allow_stale",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Allow Stale Exchange Rates"
|
"label": "Allow Stale Exchange Rates"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"depends_on": "eval:doc.allow_stale==0",
|
"depends_on": "eval:doc.allow_stale==0",
|
||||||
"fieldname": "stale_days",
|
"fieldname": "stale_days",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"label": "Stale Days"
|
"label": "Stale Days"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "report_settings_sb",
|
"fieldname": "report_settings_sb",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Report Settings"
|
"label": "Report Settings"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"description": "Only select if you have setup Cash Flow Mapper documents",
|
"description": "Only select if you have setup Cash Flow Mapper documents",
|
||||||
"fieldname": "use_custom_cash_flow",
|
"fieldname": "use_custom_cash_flow",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Use Custom Cash Flow Format"
|
"label": "Use Custom Cash Flow Format"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "automatically_fetch_payment_terms",
|
"fieldname": "automatically_fetch_payment_terms",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Automatically Fetch Payment Terms"
|
"label": "Automatically Fetch Payment Terms"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "icon-cog",
|
"icon": "icon-cog",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"modified": "2019-04-28 18:20:55.789946",
|
"modified": "2019-04-28 18:20:55.789946",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Accounts Settings",
|
"name": "Accounts Settings",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"role": "Accounts Manager",
|
"role": "Accounts Manager",
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"role": "Sales User"
|
"role": "Sales User"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"role": "Purchase User"
|
"role": "Purchase User"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"sort_order": "ASC",
|
"sort_order": "ASC",
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
@ -2,7 +2,29 @@
|
|||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on('Bank', {
|
frappe.ui.form.on('Bank', {
|
||||||
|
onload: function(frm) {
|
||||||
|
add_fields_to_mapping_table(frm);
|
||||||
|
},
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
|
add_fields_to_mapping_table(frm);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let add_fields_to_mapping_table = function (frm) {
|
||||||
|
let options = [];
|
||||||
|
|
||||||
|
frappe.model.with_doctype("Bank Transaction", function() {
|
||||||
|
let meta = frappe.get_meta("Bank Transaction");
|
||||||
|
meta.fields.forEach(value => {
|
||||||
|
if (!["Section Break", "Column Break"].includes(value.fieldtype)) {
|
||||||
|
options.push(value.fieldname);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
frappe.meta.get_docfield("Bank Transaction Mapping", "bank_transaction_field",
|
||||||
|
frm.doc.name).options = options;
|
||||||
|
|
||||||
|
frm.fields_dict.bank_transaction_mapping.grid.refresh();
|
||||||
|
};
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
"allow_guest_to_view": 0,
|
"allow_guest_to_view": 0,
|
||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
@ -15,6 +16,7 @@
|
|||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
@ -42,6 +44,134 @@
|
|||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
|
"unique": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 1,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "data_import_configuration_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Data Import Configuration",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "bank_transaction_mapping",
|
||||||
|
"fieldtype": "Table",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Bank Transaction Mapping",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Bank Transaction Mapping",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "section_break_4",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "plaid_access_token",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 1,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Plaid Access Token",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 1,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -55,7 +185,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-04-07 17:00:21.246202",
|
"modified": "2018-11-27 16:12:13.938776",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Bank",
|
"name": "Bank",
|
||||||
@ -64,7 +194,6 @@
|
|||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
"amend": 0,
|
||||||
"apply_user_permissions": 0,
|
|
||||||
"cancel": 0,
|
"cancel": 0,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
@ -90,5 +219,6 @@
|
|||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_changes": 1,
|
"track_changes": 1,
|
||||||
"track_seen": 0
|
"track_seen": 0,
|
||||||
|
"track_views": 0
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on('Bank Account', {
|
frappe.ui.form.on('Bank Account', {
|
||||||
@ -29,5 +29,13 @@ frappe.ui.form.on('Bank Account', {
|
|||||||
else {
|
else {
|
||||||
frappe.contacts.render_address_and_contact(frm);
|
frappe.contacts.render_address_and_contact(frm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (frm.doc.integration_id) {
|
||||||
|
frm.add_custom_button(__("Unlink external integrations"), function() {
|
||||||
|
frappe.confirm(__("This action will unlink this account from any external service integrating ERPNext with your bank accounts. It cannot be undone. Are you certain ?"), function() {
|
||||||
|
frm.set_value("integration_id", "");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -13,16 +13,47 @@ class BankAccount(Document):
|
|||||||
"""Load address and contacts in `__onload`"""
|
"""Load address and contacts in `__onload`"""
|
||||||
load_address_and_contact(self)
|
load_address_and_contact(self)
|
||||||
|
|
||||||
|
def autoname(self):
|
||||||
|
self.name = self.account_name + " - " + self.bank
|
||||||
|
|
||||||
def on_trash(self):
|
def on_trash(self):
|
||||||
delete_contact_and_address('BankAccount', self.name)
|
delete_contact_and_address('BankAccount', self.name)
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_company()
|
self.validate_company()
|
||||||
|
self.validate_iban()
|
||||||
|
|
||||||
def validate_company(self):
|
def validate_company(self):
|
||||||
if self.is_company_account and not self.company:
|
if self.is_company_account and not self.company:
|
||||||
frappe.throw(_("Company is manadatory for company account"))
|
frappe.throw(_("Company is manadatory for company account"))
|
||||||
|
|
||||||
|
def validate_iban(self):
|
||||||
|
'''
|
||||||
|
Algorithm: https://en.wikipedia.org/wiki/International_Bank_Account_Number#Validating_the_IBAN
|
||||||
|
'''
|
||||||
|
# IBAN field is optional
|
||||||
|
if not self.iban:
|
||||||
|
return
|
||||||
|
|
||||||
|
def encode_char(c):
|
||||||
|
# Position in the alphabet (A=1, B=2, ...) plus nine
|
||||||
|
return str(9 + ord(c) - 64)
|
||||||
|
|
||||||
|
# remove whitespaces, upper case to get the right number from ord()
|
||||||
|
iban = ''.join(self.iban.split(' ')).upper()
|
||||||
|
|
||||||
|
# Move country code and checksum from the start to the end
|
||||||
|
flipped = iban[4:] + iban[:4]
|
||||||
|
|
||||||
|
# Encode characters as numbers
|
||||||
|
encoded = [encode_char(c) if ord(c) >= 65 and ord(c) <= 90 else c for c in flipped]
|
||||||
|
|
||||||
|
to_check = int(''.join(encoded))
|
||||||
|
|
||||||
|
if to_check % 97 != 1:
|
||||||
|
frappe.throw(_('IBAN is not valid'))
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_bank_account(doctype, docname):
|
def make_bank_account(doctype, docname):
|
||||||
doc = frappe.new_doc("Bank Account")
|
doc = frappe.new_doc("Bank Account")
|
||||||
|
@ -4,9 +4,46 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
from frappe import ValidationError
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
# test_records = frappe.get_test_records('Bank Account')
|
# test_records = frappe.get_test_records('Bank Account')
|
||||||
|
|
||||||
class TestBankAccount(unittest.TestCase):
|
class TestBankAccount(unittest.TestCase):
|
||||||
pass
|
|
||||||
|
def test_validate_iban(self):
|
||||||
|
valid_ibans = [
|
||||||
|
'GB82 WEST 1234 5698 7654 32',
|
||||||
|
'DE91 1000 0000 0123 4567 89',
|
||||||
|
'FR76 3000 6000 0112 3456 7890 189'
|
||||||
|
]
|
||||||
|
|
||||||
|
invalid_ibans = [
|
||||||
|
# wrong checksum (3rd place)
|
||||||
|
'GB72 WEST 1234 5698 7654 32',
|
||||||
|
'DE81 1000 0000 0123 4567 89',
|
||||||
|
'FR66 3000 6000 0112 3456 7890 189'
|
||||||
|
]
|
||||||
|
|
||||||
|
bank_account = frappe.get_doc({'doctype':'Bank Account'})
|
||||||
|
|
||||||
|
try:
|
||||||
|
bank_account.validate_iban()
|
||||||
|
except AttributeError:
|
||||||
|
msg = _('BankAccount.validate_iban() failed for empty IBAN')
|
||||||
|
self.fail(msg=msg)
|
||||||
|
|
||||||
|
for iban in valid_ibans:
|
||||||
|
bank_account.iban = iban
|
||||||
|
try:
|
||||||
|
bank_account.validate_iban()
|
||||||
|
except ValidationError:
|
||||||
|
msg = _('BankAccount.validate_iban() failed for valid IBAN {}'.format(iban))
|
||||||
|
self.fail(msg=msg)
|
||||||
|
|
||||||
|
for not_iban in invalid_ibans:
|
||||||
|
bank_account.iban = not_iban
|
||||||
|
msg = _('BankAccount.validate_iban() accepted invalid IBAN {}'.format(not_iban))
|
||||||
|
with self.assertRaises(ValidationError, msg=msg):
|
||||||
|
bank_account.validate_iban()
|
||||||
|
@ -103,7 +103,7 @@ class BankReconciliation(Document):
|
|||||||
for d in self.get('payment_entries'):
|
for d in self.get('payment_entries'):
|
||||||
if d.clearance_date:
|
if d.clearance_date:
|
||||||
if not d.payment_document:
|
if not d.payment_document:
|
||||||
frappe.throw(_("Row #{0}: Payment document is required to complete the trasaction"))
|
frappe.throw(_("Row #{0}: Payment document is required to complete the transaction"))
|
||||||
|
|
||||||
if d.cheque_date and getdate(d.clearance_date) < getdate(d.cheque_date):
|
if d.cheque_date and getdate(d.clearance_date) < getdate(d.cheque_date):
|
||||||
frappe.throw(_("Row #{0}: Clearance date {1} cannot be before Cheque Date {2}")
|
frappe.throw(_("Row #{0}: Clearance date {1} cannot be before Cheque Date {2}")
|
||||||
@ -113,10 +113,8 @@ class BankReconciliation(Document):
|
|||||||
if not d.clearance_date:
|
if not d.clearance_date:
|
||||||
d.clearance_date = None
|
d.clearance_date = None
|
||||||
|
|
||||||
frappe.db.set_value(d.payment_document, d.payment_entry, "clearance_date", d.clearance_date)
|
payment_entry = frappe.get_doc(d.payment_document, d.payment_entry)
|
||||||
frappe.db.sql("""update `tab{0}` set clearance_date = %s, modified = %s
|
payment_entry.db_set('clearance_date', d.clearance_date)
|
||||||
where name=%s""".format(d.payment_document),
|
|
||||||
(d.clearance_date, nowdate(), d.payment_entry))
|
|
||||||
|
|
||||||
clearance_date_updated = True
|
clearance_date_updated = True
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ class BankStatementTransactionEntry(Document):
|
|||||||
|
|
||||||
def get_statement_headers(self):
|
def get_statement_headers(self):
|
||||||
if not self.bank_settings:
|
if not self.bank_settings:
|
||||||
frappe.throw("Bank Data mapper doesn't exist")
|
frappe.throw(_("Bank Data mapper doesn't exist"))
|
||||||
mapper_doc = frappe.get_doc("Bank Statement Settings", self.bank_settings)
|
mapper_doc = frappe.get_doc("Bank Statement Settings", self.bank_settings)
|
||||||
headers = {entry.mapped_header:entry.stmt_header for entry in mapper_doc.header_items}
|
headers = {entry.mapped_header:entry.stmt_header for entry in mapper_doc.header_items}
|
||||||
return headers
|
return headers
|
||||||
@ -57,7 +57,7 @@ class BankStatementTransactionEntry(Document):
|
|||||||
if self.bank_statement is None: return
|
if self.bank_statement is None: return
|
||||||
filename = self.bank_statement.split("/")[-1]
|
filename = self.bank_statement.split("/")[-1]
|
||||||
if (len(self.new_transaction_items + self.reconciled_transaction_items) > 0):
|
if (len(self.new_transaction_items + self.reconciled_transaction_items) > 0):
|
||||||
frappe.throw("Transactions already retreived from the statement")
|
frappe.throw(_("Transactions already retreived from the statement"))
|
||||||
|
|
||||||
date_format = frappe.get_value("Bank Statement Settings", self.bank_settings, "date_format")
|
date_format = frappe.get_value("Bank Statement Settings", self.bank_settings, "date_format")
|
||||||
if (date_format is None):
|
if (date_format is None):
|
||||||
@ -314,7 +314,7 @@ class BankStatementTransactionEntry(Document):
|
|||||||
try:
|
try:
|
||||||
reconcile_against_document(lst)
|
reconcile_against_document(lst)
|
||||||
except:
|
except:
|
||||||
frappe.throw("Exception occurred while reconciling {0}".format(payment.reference_name))
|
frappe.throw(_("Exception occurred while reconciling {0}".format(payment.reference_name)))
|
||||||
|
|
||||||
def submit_payment_entries(self):
|
def submit_payment_entries(self):
|
||||||
for payment in self.new_transaction_items:
|
for payment in self.new_transaction_items:
|
||||||
@ -414,7 +414,7 @@ def get_transaction_entries(filename, headers):
|
|||||||
elif (filename.lower().endswith("xls")):
|
elif (filename.lower().endswith("xls")):
|
||||||
rows = get_rows_from_xls_file(filename)
|
rows = get_rows_from_xls_file(filename)
|
||||||
else:
|
else:
|
||||||
frappe.throw("Only .csv and .xlsx files are supported currently")
|
frappe.throw(_("Only .csv and .xlsx files are supported currently"))
|
||||||
|
|
||||||
stmt_headers = headers.values()
|
stmt_headers = headers.values()
|
||||||
for row in rows:
|
for row in rows:
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('Bank Transaction', {
|
||||||
|
onload(frm) {
|
||||||
|
frm.set_query('payment_document', 'payment_entries', function() {
|
||||||
|
return {
|
||||||
|
"filters": {
|
||||||
|
"name": ["in", ["Payment Entry", "Journal Entry", "Sales Invoice", "Purchase Invoice", "Expense Claim"]]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
frappe.ui.form.on('Bank Transaction Payments', {
|
||||||
|
payment_entries_remove: function(frm, cdt, cdn) {
|
||||||
|
update_clearance_date(frm, cdt, cdn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const update_clearance_date = (frm, cdt, cdn) => {
|
||||||
|
if (frm.doc.docstatus === 1) {
|
||||||
|
frappe.xcall('erpnext.accounts.doctype.bank_transaction.bank_transaction.unclear_reference_payment',
|
||||||
|
{doctype: cdt, docname: cdn})
|
||||||
|
.then(e => {
|
||||||
|
if (e == "success") {
|
||||||
|
frappe.show_alert({message:__("Document {0} successfully uncleared", [e]), indicator:'green'});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
833
erpnext/accounts/doctype/bank_transaction/bank_transaction.json
Normal file
833
erpnext/accounts/doctype/bank_transaction/bank_transaction.json
Normal file
@ -0,0 +1,833 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 1,
|
||||||
|
"allow_rename": 0,
|
||||||
|
"autoname": "naming_series:",
|
||||||
|
"beta": 0,
|
||||||
|
"creation": "2018-10-22 18:19:02.784533",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "ACC-BTN-.YYYY.-",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "naming_series",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"hidden": 1,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Series",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 1,
|
||||||
|
"options": "ACC-BTN-.YYYY.-",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 1,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 1,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Date",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "column_break_2",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "Pending",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "status",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 1,
|
||||||
|
"label": "Status",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "\nPending\nSettled\nUnreconciled\nReconciled",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "bank_account",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 1,
|
||||||
|
"label": "Bank Account",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Bank Account",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"default": "",
|
||||||
|
"fetch_from": "bank_account.company",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "company",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 1,
|
||||||
|
"label": "Company",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Company",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "section_break_4",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "debit",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Debit",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "credit",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Credit",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "column_break_7",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "currency",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Currency",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Currency",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "section_break_10",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "description",
|
||||||
|
"fieldtype": "Small Text",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Description",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "section_break_14",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "reference_number",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Reference Number",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "transaction_id",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Transaction ID",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 1,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "payment_entries",
|
||||||
|
"fieldtype": "Table",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Payment Entries",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Bank Transaction Payments",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "section_break_18",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "allocated_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Allocated Amount",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "amended_from",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Amended From",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 1,
|
||||||
|
"options": "Bank Transaction",
|
||||||
|
"permlevel": 0,
|
||||||
|
"print_hide": 1,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "column_break_17",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"depends_on": "",
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "unallocated_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Unallocated Amount",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
|
"hide_heading": 0,
|
||||||
|
"hide_toolbar": 0,
|
||||||
|
"idx": 0,
|
||||||
|
"image_view": 0,
|
||||||
|
"in_create": 0,
|
||||||
|
"is_submittable": 1,
|
||||||
|
"issingle": 0,
|
||||||
|
"istable": 0,
|
||||||
|
"max_attachments": 0,
|
||||||
|
"modified": "2019-05-11 05:27:55.244721",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Bank Transaction",
|
||||||
|
"name_case": "",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"cancel": 1,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"cancel": 1,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Accounts Manager",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 1,
|
||||||
|
"write": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"amend": 0,
|
||||||
|
"cancel": 0,
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"if_owner": 0,
|
||||||
|
"import": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "Accounts User",
|
||||||
|
"set_user_permissions": 0,
|
||||||
|
"share": 1,
|
||||||
|
"submit": 1,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quick_entry": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
|
"sort_field": "date",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"title_field": "bank_account",
|
||||||
|
"track_changes": 0,
|
||||||
|
"track_seen": 0,
|
||||||
|
"track_views": 0
|
||||||
|
}
|
106
erpnext/accounts/doctype/bank_transaction/bank_transaction.py
Normal file
106
erpnext/accounts/doctype/bank_transaction/bank_transaction.py
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from erpnext.controllers.status_updater import StatusUpdater
|
||||||
|
from frappe.utils import flt
|
||||||
|
from six.moves import reduce
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
|
class BankTransaction(StatusUpdater):
|
||||||
|
def after_insert(self):
|
||||||
|
self.unallocated_amount = abs(flt(self.credit) - flt(self.debit))
|
||||||
|
|
||||||
|
def on_submit(self):
|
||||||
|
self.clear_linked_payment_entries()
|
||||||
|
self.set_status()
|
||||||
|
|
||||||
|
def on_update_after_submit(self):
|
||||||
|
self.update_allocations()
|
||||||
|
self.clear_linked_payment_entries()
|
||||||
|
self.set_status(update=True)
|
||||||
|
|
||||||
|
def update_allocations(self):
|
||||||
|
if self.payment_entries:
|
||||||
|
allocated_amount = reduce(lambda x, y: flt(x) + flt(y), [x.allocated_amount for x in self.payment_entries])
|
||||||
|
else:
|
||||||
|
allocated_amount = 0
|
||||||
|
|
||||||
|
if allocated_amount:
|
||||||
|
frappe.db.set_value(self.doctype, self.name, "allocated_amount", flt(allocated_amount))
|
||||||
|
frappe.db.set_value(self.doctype, self.name, "unallocated_amount", abs(flt(self.credit) - flt(self.debit)) - flt(allocated_amount))
|
||||||
|
|
||||||
|
else:
|
||||||
|
frappe.db.set_value(self.doctype, self.name, "allocated_amount", 0)
|
||||||
|
frappe.db.set_value(self.doctype, self.name, "unallocated_amount", abs(flt(self.credit) - flt(self.debit)))
|
||||||
|
|
||||||
|
amount = self.debit or self.credit
|
||||||
|
if amount == self.allocated_amount:
|
||||||
|
frappe.db.set_value(self.doctype, self.name, "status", "Reconciled")
|
||||||
|
|
||||||
|
self.reload()
|
||||||
|
|
||||||
|
def clear_linked_payment_entries(self):
|
||||||
|
for payment_entry in self.payment_entries:
|
||||||
|
allocated_amount = get_total_allocated_amount(payment_entry)
|
||||||
|
paid_amount = get_paid_amount(payment_entry)
|
||||||
|
|
||||||
|
if paid_amount and allocated_amount:
|
||||||
|
if flt(allocated_amount[0]["allocated_amount"]) > flt(paid_amount):
|
||||||
|
frappe.throw(_("The total allocated amount ({0}) is greated than the paid amount ({1}).".format(flt(allocated_amount[0]["allocated_amount"]), flt(paid_amount))))
|
||||||
|
elif flt(allocated_amount[0]["allocated_amount"]) == flt(paid_amount):
|
||||||
|
if payment_entry.payment_document in ["Payment Entry", "Journal Entry", "Purchase Invoice", "Expense Claim"]:
|
||||||
|
self.clear_simple_entry(payment_entry)
|
||||||
|
|
||||||
|
elif payment_entry.payment_document == "Sales Invoice":
|
||||||
|
self.clear_sales_invoice(payment_entry)
|
||||||
|
|
||||||
|
def clear_simple_entry(self, payment_entry):
|
||||||
|
frappe.db.set_value(payment_entry.payment_document, payment_entry.payment_entry, "clearance_date", self.date)
|
||||||
|
|
||||||
|
def clear_sales_invoice(self, payment_entry):
|
||||||
|
frappe.db.set_value("Sales Invoice Payment", dict(parenttype=payment_entry.payment_document,
|
||||||
|
parent=payment_entry.payment_entry), "clearance_date", self.date)
|
||||||
|
|
||||||
|
def get_total_allocated_amount(payment_entry):
|
||||||
|
return frappe.db.sql("""
|
||||||
|
SELECT
|
||||||
|
SUM(btp.allocated_amount) as allocated_amount,
|
||||||
|
bt.name
|
||||||
|
FROM
|
||||||
|
`tabBank Transaction Payments` as btp
|
||||||
|
LEFT JOIN
|
||||||
|
`tabBank Transaction` bt ON bt.name=btp.parent
|
||||||
|
WHERE
|
||||||
|
btp.payment_document = %s
|
||||||
|
AND
|
||||||
|
btp.payment_entry = %s
|
||||||
|
AND
|
||||||
|
bt.docstatus = 1""", (payment_entry.payment_document, payment_entry.payment_entry), as_dict=True)
|
||||||
|
|
||||||
|
def get_paid_amount(payment_entry):
|
||||||
|
if payment_entry.payment_document in ["Payment Entry", "Sales Invoice", "Purchase Invoice"]:
|
||||||
|
return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "paid_amount")
|
||||||
|
|
||||||
|
elif payment_entry.payment_document == "Journal Entry":
|
||||||
|
return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "total_credit")
|
||||||
|
|
||||||
|
elif payment_entry.payment_document == "Expense Claim":
|
||||||
|
return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "total_amount_reimbursed")
|
||||||
|
|
||||||
|
else:
|
||||||
|
frappe.throw("Please reconcile {0}: {1} manually".format(payment_entry.payment_document, payment_entry.payment_entry))
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def unclear_reference_payment(doctype, docname):
|
||||||
|
if frappe.db.exists(doctype, docname):
|
||||||
|
doc = frappe.get_doc(doctype, docname)
|
||||||
|
if doctype == "Sales Invoice":
|
||||||
|
frappe.db.set_value("Sales Invoice Payment", dict(parenttype=doc.payment_document,
|
||||||
|
parent=doc.payment_entry), "clearance_date", None)
|
||||||
|
else:
|
||||||
|
frappe.db.set_value(doc.payment_document, doc.payment_entry, "clearance_date", None)
|
||||||
|
|
||||||
|
return doc.payment_entry
|
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
frappe.listview_settings['Bank Transaction'] = {
|
||||||
|
add_fields: ["unallocated_amount"],
|
||||||
|
get_indicator: function(doc) {
|
||||||
|
if(flt(doc.unallocated_amount)>0) {
|
||||||
|
return [__("Unreconciled"), "orange", "unallocated_amount,>,0"];
|
||||||
|
} else if(flt(doc.unallocated_amount)<=0) {
|
||||||
|
return [__("Reconciled"), "green", "unallocated_amount,=,0"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,80 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
import json
|
||||||
|
from frappe.utils import getdate
|
||||||
|
from frappe.utils.dateutils import parse_date
|
||||||
|
from six import iteritems
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def upload_bank_statement():
|
||||||
|
if getattr(frappe, "uploaded_file", None):
|
||||||
|
with open(frappe.uploaded_file, "rb") as upfile:
|
||||||
|
fcontent = upfile.read()
|
||||||
|
else:
|
||||||
|
from frappe.utils.file_manager import get_uploaded_content
|
||||||
|
fname, fcontent = get_uploaded_content()
|
||||||
|
|
||||||
|
if frappe.safe_encode(fname).lower().endswith("csv".encode('utf-8')):
|
||||||
|
from frappe.utils.csvutils import read_csv_content
|
||||||
|
rows = read_csv_content(fcontent, False)
|
||||||
|
|
||||||
|
elif frappe.safe_encode(fname).lower().endswith("xlsx".encode('utf-8')):
|
||||||
|
from frappe.utils.xlsxutils import read_xlsx_file_from_attached_file
|
||||||
|
rows = read_xlsx_file_from_attached_file(fcontent=fcontent)
|
||||||
|
|
||||||
|
columns = rows[0]
|
||||||
|
rows.pop(0)
|
||||||
|
data = rows
|
||||||
|
return {"columns": columns, "data": data}
|
||||||
|
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def create_bank_entries(columns, data, bank_account):
|
||||||
|
header_map = get_header_mapping(columns, bank_account)
|
||||||
|
|
||||||
|
success = 0
|
||||||
|
errors = 0
|
||||||
|
for d in json.loads(data):
|
||||||
|
if all(item is None for item in d) is True:
|
||||||
|
continue
|
||||||
|
fields = {}
|
||||||
|
for key, value in iteritems(header_map):
|
||||||
|
fields.update({key: d[int(value)-1]})
|
||||||
|
|
||||||
|
try:
|
||||||
|
bank_transaction = frappe.get_doc({
|
||||||
|
"doctype": "Bank Transaction"
|
||||||
|
})
|
||||||
|
bank_transaction.update(fields)
|
||||||
|
bank_transaction.date = getdate(parse_date(bank_transaction.date))
|
||||||
|
bank_transaction.bank_account = bank_account
|
||||||
|
bank_transaction.insert()
|
||||||
|
bank_transaction.submit()
|
||||||
|
success += 1
|
||||||
|
except Exception:
|
||||||
|
frappe.log_error(frappe.get_traceback())
|
||||||
|
errors += 1
|
||||||
|
|
||||||
|
return {"success": success, "errors": errors}
|
||||||
|
|
||||||
|
def get_header_mapping(columns, bank_account):
|
||||||
|
mapping = get_bank_mapping(bank_account)
|
||||||
|
|
||||||
|
header_map = {}
|
||||||
|
for column in json.loads(columns):
|
||||||
|
if column["content"] in mapping:
|
||||||
|
header_map.update({mapping[column["content"]]: column["colIndex"]})
|
||||||
|
|
||||||
|
return header_map
|
||||||
|
|
||||||
|
def get_bank_mapping(bank_account):
|
||||||
|
bank_name = frappe.db.get_value("Bank Account", bank_account, "bank")
|
||||||
|
bank = frappe.get_doc("Bank", bank_name)
|
||||||
|
|
||||||
|
mapping = {row.file_field:row.bank_transaction_field for row in bank.bank_transaction_mapping}
|
||||||
|
|
||||||
|
return mapping
|
@ -0,0 +1,23 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// rename this file from _test_[name] to test_[name] to activate
|
||||||
|
// and remove above this line
|
||||||
|
|
||||||
|
QUnit.test("test: Bank Transaction", function (assert) {
|
||||||
|
let done = assert.async();
|
||||||
|
|
||||||
|
// number of asserts
|
||||||
|
assert.expect(1);
|
||||||
|
|
||||||
|
frappe.run_serially([
|
||||||
|
// insert a new Bank Transaction
|
||||||
|
() => frappe.tests.make('Bank Transaction', [
|
||||||
|
// values to be set
|
||||||
|
{key: 'value'}
|
||||||
|
]),
|
||||||
|
() => {
|
||||||
|
assert.equal(cur_frm.doc.key, 'value');
|
||||||
|
},
|
||||||
|
() => done()
|
||||||
|
]);
|
||||||
|
|
||||||
|
});
|
@ -0,0 +1,290 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import frappe
|
||||||
|
import unittest
|
||||||
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
|
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
||||||
|
from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
|
||||||
|
from erpnext.accounts.page.bank_reconciliation.bank_reconciliation import reconcile, get_linked_payments
|
||||||
|
|
||||||
|
test_dependencies = ["Item", "Cost Center"]
|
||||||
|
|
||||||
|
class TestBankTransaction(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
add_transactions()
|
||||||
|
add_payments()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
for bt in frappe.get_all("Bank Transaction"):
|
||||||
|
doc = frappe.get_doc("Bank Transaction", bt.name)
|
||||||
|
doc.cancel()
|
||||||
|
doc.delete()
|
||||||
|
|
||||||
|
# Delete directly in DB to avoid validation errors for countries not allowing deletion
|
||||||
|
frappe.db.sql("""delete from `tabPayment Entry Reference`""")
|
||||||
|
frappe.db.sql("""delete from `tabPayment Entry`""")
|
||||||
|
|
||||||
|
frappe.flags.test_bank_transactions_created = False
|
||||||
|
frappe.flags.test_payments_created = False
|
||||||
|
|
||||||
|
# This test checks if ERPNext is able to provide a linked payment for a bank transaction based on the amount of the bank transaction.
|
||||||
|
def test_linked_payments(self):
|
||||||
|
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="Re 95282925234 FE/000002917 AT171513000281183046 Conrad Electronic"))
|
||||||
|
linked_payments = get_linked_payments(bank_transaction.name)
|
||||||
|
self.assertTrue(linked_payments[0].party == "Conrad Electronic")
|
||||||
|
|
||||||
|
# This test validates a simple reconciliation leading to the clearance of the bank transaction and the payment
|
||||||
|
def test_reconcile(self):
|
||||||
|
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="1512567 BG/000002918 OPSKATTUZWXXX AT776000000098709837 Herr G"))
|
||||||
|
payment = frappe.get_doc("Payment Entry", dict(party="Mr G", paid_amount=1200))
|
||||||
|
reconcile(bank_transaction.name, "Payment Entry", payment.name)
|
||||||
|
|
||||||
|
unallocated_amount = frappe.db.get_value("Bank Transaction", bank_transaction.name, "unallocated_amount")
|
||||||
|
self.assertTrue(unallocated_amount == 0)
|
||||||
|
|
||||||
|
clearance_date = frappe.db.get_value("Payment Entry", payment.name, "clearance_date")
|
||||||
|
self.assertTrue(clearance_date is not None)
|
||||||
|
|
||||||
|
# Check if ERPNext can correctly fetch a linked payment based on the party
|
||||||
|
def test_linked_payments_based_on_party(self):
|
||||||
|
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="1512567 BG/000003025 OPSKATTUZWXXX AT776000000098709849 Herr G"))
|
||||||
|
linked_payments = get_linked_payments(bank_transaction.name)
|
||||||
|
self.assertTrue(len(linked_payments)==1)
|
||||||
|
|
||||||
|
# Check if ERPNext can correctly filter a linked payments based on the debit/credit amount
|
||||||
|
def test_debit_credit_output(self):
|
||||||
|
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="Auszahlung Karte MC/000002916 AUTOMAT 698769 K002 27.10. 14:07"))
|
||||||
|
linked_payments = get_linked_payments(bank_transaction.name)
|
||||||
|
self.assertTrue(linked_payments[0].payment_type == "Pay")
|
||||||
|
|
||||||
|
# Check error if already reconciled
|
||||||
|
def test_already_reconciled(self):
|
||||||
|
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="1512567 BG/000002918 OPSKATTUZWXXX AT776000000098709837 Herr G"))
|
||||||
|
payment = frappe.get_doc("Payment Entry", dict(party="Mr G", paid_amount=1200))
|
||||||
|
reconcile(bank_transaction.name, "Payment Entry", payment.name)
|
||||||
|
|
||||||
|
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="1512567 BG/000002918 OPSKATTUZWXXX AT776000000098709837 Herr G"))
|
||||||
|
payment = frappe.get_doc("Payment Entry", dict(party="Mr G", paid_amount=1200))
|
||||||
|
self.assertRaises(frappe.ValidationError, reconcile, bank_transaction=bank_transaction.name, payment_doctype="Payment Entry", payment_name=payment.name)
|
||||||
|
|
||||||
|
# Raise an error if creditor transaction vs creditor payment
|
||||||
|
def test_invalid_creditor_reconcilation(self):
|
||||||
|
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="I2015000011 VD/000002514 ATWWXXX AT4701345000003510057 Bio"))
|
||||||
|
payment = frappe.get_doc("Payment Entry", dict(party="Conrad Electronic", paid_amount=690))
|
||||||
|
self.assertRaises(frappe.ValidationError, reconcile, bank_transaction=bank_transaction.name, payment_doctype="Payment Entry", payment_name=payment.name)
|
||||||
|
|
||||||
|
# Raise an error if debitor transaction vs debitor payment
|
||||||
|
def test_invalid_debitor_reconcilation(self):
|
||||||
|
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="Auszahlung Karte MC/000002916 AUTOMAT 698769 K002 27.10. 14:07"))
|
||||||
|
payment = frappe.get_doc("Payment Entry", dict(party="Fayva", paid_amount=109080))
|
||||||
|
self.assertRaises(frappe.ValidationError, reconcile, bank_transaction=bank_transaction.name, payment_doctype="Payment Entry", payment_name=payment.name)
|
||||||
|
|
||||||
|
# Raise an error if debitor transaction vs debitor payment
|
||||||
|
def test_clear_sales_invoice(self):
|
||||||
|
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="I2015000011 VD/000002514 ATWWXXX AT4701345000003510057 Bio"))
|
||||||
|
payment = frappe.get_doc("Sales Invoice", dict(customer="Fayva", status=["=", "Paid"]))
|
||||||
|
reconcile(bank_transaction.name, "Sales Invoice", payment.name)
|
||||||
|
|
||||||
|
self.assertEqual(frappe.db.get_value("Bank Transaction", bank_transaction.name, "unallocated_amount"), 0)
|
||||||
|
self.assertTrue(frappe.db.get_value("Sales Invoice Payment", dict(parent=payment.name), "clearance_date") is not None)
|
||||||
|
|
||||||
|
def add_transactions():
|
||||||
|
if frappe.flags.test_bank_transactions_created:
|
||||||
|
return
|
||||||
|
|
||||||
|
frappe.set_user("Administrator")
|
||||||
|
try:
|
||||||
|
frappe.get_doc({
|
||||||
|
"doctype": "Bank",
|
||||||
|
"bank_name":"Citi Bank",
|
||||||
|
}).insert()
|
||||||
|
except frappe.DuplicateEntryError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
frappe.get_doc({
|
||||||
|
"doctype": "Bank Account",
|
||||||
|
"account_name":"Checking Account",
|
||||||
|
"bank": "Citi Bank",
|
||||||
|
"account": "_Test Bank - _TC"
|
||||||
|
}).insert()
|
||||||
|
except frappe.DuplicateEntryError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
doc = frappe.get_doc({
|
||||||
|
"doctype": "Bank Transaction",
|
||||||
|
"description":"1512567 BG/000002918 OPSKATTUZWXXX AT776000000098709837 Herr G",
|
||||||
|
"date": "2018-10-23",
|
||||||
|
"debit": 1200,
|
||||||
|
"currency": "INR",
|
||||||
|
"bank_account": "Checking Account - Citi Bank"
|
||||||
|
}).insert()
|
||||||
|
doc.submit()
|
||||||
|
|
||||||
|
doc = frappe.get_doc({
|
||||||
|
"doctype": "Bank Transaction",
|
||||||
|
"description":"1512567 BG/000003025 OPSKATTUZWXXX AT776000000098709849 Herr G",
|
||||||
|
"date": "2018-10-23",
|
||||||
|
"debit": 1700,
|
||||||
|
"currency": "INR",
|
||||||
|
"bank_account": "Checking Account - Citi Bank"
|
||||||
|
}).insert()
|
||||||
|
doc.submit()
|
||||||
|
|
||||||
|
doc = frappe.get_doc({
|
||||||
|
"doctype": "Bank Transaction",
|
||||||
|
"description":"Re 95282925234 FE/000002917 AT171513000281183046 Conrad Electronic",
|
||||||
|
"date": "2018-10-26",
|
||||||
|
"debit": 690,
|
||||||
|
"currency": "INR",
|
||||||
|
"bank_account": "Checking Account - Citi Bank"
|
||||||
|
}).insert()
|
||||||
|
doc.submit()
|
||||||
|
|
||||||
|
doc = frappe.get_doc({
|
||||||
|
"doctype": "Bank Transaction",
|
||||||
|
"description":"Auszahlung Karte MC/000002916 AUTOMAT 698769 K002 27.10. 14:07",
|
||||||
|
"date": "2018-10-27",
|
||||||
|
"debit": 3900,
|
||||||
|
"currency": "INR",
|
||||||
|
"bank_account": "Checking Account - Citi Bank"
|
||||||
|
}).insert()
|
||||||
|
doc.submit()
|
||||||
|
|
||||||
|
doc = frappe.get_doc({
|
||||||
|
"doctype": "Bank Transaction",
|
||||||
|
"description":"I2015000011 VD/000002514 ATWWXXX AT4701345000003510057 Bio",
|
||||||
|
"date": "2018-10-27",
|
||||||
|
"credit": 109080,
|
||||||
|
"currency": "INR",
|
||||||
|
"bank_account": "Checking Account - Citi Bank"
|
||||||
|
}).insert()
|
||||||
|
doc.submit()
|
||||||
|
|
||||||
|
frappe.flags.test_bank_transactions_created = True
|
||||||
|
|
||||||
|
def add_payments():
|
||||||
|
if frappe.flags.test_payments_created:
|
||||||
|
return
|
||||||
|
|
||||||
|
frappe.set_user("Administrator")
|
||||||
|
|
||||||
|
try:
|
||||||
|
frappe.get_doc({
|
||||||
|
"doctype": "Supplier",
|
||||||
|
"supplier_group":"All Supplier Groups",
|
||||||
|
"supplier_type": "Company",
|
||||||
|
"supplier_name": "Conrad Electronic"
|
||||||
|
}).insert()
|
||||||
|
|
||||||
|
except frappe.DuplicateEntryError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
pi = make_purchase_invoice(supplier="Conrad Electronic", qty=1, rate=690)
|
||||||
|
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
|
||||||
|
pe.reference_no = "Conrad Oct 18"
|
||||||
|
pe.reference_date = "2018-10-24"
|
||||||
|
pe.insert()
|
||||||
|
pe.submit()
|
||||||
|
|
||||||
|
try:
|
||||||
|
frappe.get_doc({
|
||||||
|
"doctype": "Supplier",
|
||||||
|
"supplier_group":"All Supplier Groups",
|
||||||
|
"supplier_type": "Company",
|
||||||
|
"supplier_name": "Mr G"
|
||||||
|
}).insert()
|
||||||
|
except frappe.DuplicateEntryError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
pi = make_purchase_invoice(supplier="Mr G", qty=1, rate=1200)
|
||||||
|
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
|
||||||
|
pe.reference_no = "Herr G Oct 18"
|
||||||
|
pe.reference_date = "2018-10-24"
|
||||||
|
pe.insert()
|
||||||
|
pe.submit()
|
||||||
|
|
||||||
|
pi = make_purchase_invoice(supplier="Mr G", qty=1, rate=1700)
|
||||||
|
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
|
||||||
|
pe.reference_no = "Herr G Nov 18"
|
||||||
|
pe.reference_date = "2018-11-01"
|
||||||
|
pe.insert()
|
||||||
|
pe.submit()
|
||||||
|
|
||||||
|
try:
|
||||||
|
frappe.get_doc({
|
||||||
|
"doctype": "Supplier",
|
||||||
|
"supplier_group":"All Supplier Groups",
|
||||||
|
"supplier_type": "Company",
|
||||||
|
"supplier_name": "Poore Simon's"
|
||||||
|
}).insert()
|
||||||
|
except frappe.DuplicateEntryError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
frappe.get_doc({
|
||||||
|
"doctype": "Customer",
|
||||||
|
"customer_group":"All Customer Groups",
|
||||||
|
"customer_type": "Company",
|
||||||
|
"customer_name": "Poore Simon's"
|
||||||
|
}).insert()
|
||||||
|
except frappe.DuplicateEntryError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
pi = make_purchase_invoice(supplier="Poore Simon's", qty=1, rate=3900)
|
||||||
|
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
|
||||||
|
pe.reference_no = "Poore Simon's Oct 18"
|
||||||
|
pe.reference_date = "2018-10-28"
|
||||||
|
pe.insert()
|
||||||
|
pe.submit()
|
||||||
|
|
||||||
|
si = create_sales_invoice(customer="Poore Simon's", qty=1, rate=3900)
|
||||||
|
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
|
||||||
|
pe.reference_no = "Poore Simon's Oct 18"
|
||||||
|
pe.reference_date = "2018-10-28"
|
||||||
|
pe.insert()
|
||||||
|
pe.submit()
|
||||||
|
|
||||||
|
try:
|
||||||
|
frappe.get_doc({
|
||||||
|
"doctype": "Customer",
|
||||||
|
"customer_group":"All Customer Groups",
|
||||||
|
"customer_type": "Company",
|
||||||
|
"customer_name": "Fayva"
|
||||||
|
}).insert()
|
||||||
|
except frappe.DuplicateEntryError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
si = create_sales_invoice(customer="Fayva", qty=1, rate=109080)
|
||||||
|
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
|
||||||
|
pe.reference_no = "Fayva Oct 18"
|
||||||
|
pe.reference_date = "2018-10-29"
|
||||||
|
pe.insert()
|
||||||
|
pe.submit()
|
||||||
|
|
||||||
|
mode_of_payment = frappe.get_doc({
|
||||||
|
"doctype": "Mode of Payment",
|
||||||
|
"name": "Cash"
|
||||||
|
})
|
||||||
|
|
||||||
|
if not frappe.db.get_value('Mode of Payment Account', {'company': "_Test Company", 'parent': "Cash"}):
|
||||||
|
mode_of_payment.append("accounts", {
|
||||||
|
"company": "_Test Company",
|
||||||
|
"default_account": "_Test Bank - _TC"
|
||||||
|
})
|
||||||
|
mode_of_payment.save()
|
||||||
|
|
||||||
|
si = create_sales_invoice(customer="Fayva", qty=1, rate=109080, do_not_submit=1)
|
||||||
|
si.is_pos = 1
|
||||||
|
si.append("payments", {
|
||||||
|
"mode_of_payment": "Cash",
|
||||||
|
"account": "_Test Bank - _TC",
|
||||||
|
"amount": 109080
|
||||||
|
})
|
||||||
|
si.save()
|
||||||
|
si.submit()
|
||||||
|
|
||||||
|
frappe.flags.test_payments_created = True
|
@ -0,0 +1,107 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 0,
|
||||||
|
"allow_rename": 0,
|
||||||
|
"beta": 0,
|
||||||
|
"creation": "2018-10-24 15:24:56.713277",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "bank_transaction_field",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Field in Bank Transaction",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "file_field",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Column in Bank File",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
|
"hide_heading": 0,
|
||||||
|
"hide_toolbar": 0,
|
||||||
|
"idx": 0,
|
||||||
|
"image_view": 0,
|
||||||
|
"in_create": 0,
|
||||||
|
"is_submittable": 0,
|
||||||
|
"issingle": 0,
|
||||||
|
"istable": 1,
|
||||||
|
"max_attachments": 0,
|
||||||
|
"modified": "2018-10-24 15:24:56.713277",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Bank Transaction Mapping",
|
||||||
|
"name_case": "",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"quick_entry": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 0,
|
||||||
|
"track_seen": 0,
|
||||||
|
"track_views": 0
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class BankTransactionMapping(Document):
|
||||||
|
pass
|
@ -0,0 +1,141 @@
|
|||||||
|
{
|
||||||
|
"allow_copy": 0,
|
||||||
|
"allow_events_in_timeline": 0,
|
||||||
|
"allow_guest_to_view": 0,
|
||||||
|
"allow_import": 0,
|
||||||
|
"allow_rename": 0,
|
||||||
|
"beta": 0,
|
||||||
|
"creation": "2018-11-28 08:55:40.815355",
|
||||||
|
"custom": 0,
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "DocType",
|
||||||
|
"document_type": "",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "payment_document",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Payment Document",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "DocType",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "payment_entry",
|
||||||
|
"fieldtype": "Dynamic Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Payment Entry",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "payment_document",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fieldname": "allocated_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 1,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Allocated Amount",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 1,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"has_web_view": 0,
|
||||||
|
"hide_heading": 0,
|
||||||
|
"hide_toolbar": 0,
|
||||||
|
"idx": 0,
|
||||||
|
"image_view": 0,
|
||||||
|
"in_create": 0,
|
||||||
|
"is_submittable": 0,
|
||||||
|
"issingle": 0,
|
||||||
|
"istable": 1,
|
||||||
|
"max_attachments": 0,
|
||||||
|
"modified": "2018-12-06 10:57:02.635141",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "Bank Transaction Payments",
|
||||||
|
"name_case": "",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"read_only": 0,
|
||||||
|
"read_only_onload": 0,
|
||||||
|
"show_name_in_global_search": 0,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1,
|
||||||
|
"track_seen": 0,
|
||||||
|
"track_views": 0
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class BankTransactionPayments(Document):
|
||||||
|
pass
|
@ -848,6 +848,39 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
"unique": 0
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"fetch_if_empty": 0,
|
||||||
|
"fieldname": "due_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Due Date",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"has_web_view": 0,
|
||||||
@ -861,7 +894,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2019-01-07 07:05:00.366399",
|
"modified": "2019-05-01 07:05:00.366399",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "GL Entry",
|
"name": "GL Entry",
|
||||||
|
@ -228,6 +228,10 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
|
|||||||
frappe.model.validate_missing(jvd, "account");
|
frappe.model.validate_missing(jvd, "account");
|
||||||
var party_account_field = jvd.reference_type==="Sales Invoice" ? "debit_to": "credit_to";
|
var party_account_field = jvd.reference_type==="Sales Invoice" ? "debit_to": "credit_to";
|
||||||
out.filters.push([jvd.reference_type, party_account_field, "=", jvd.account]);
|
out.filters.push([jvd.reference_type, party_account_field, "=", jvd.account]);
|
||||||
|
|
||||||
|
if (in_list(['Debit Note', 'Credit Note'], doc.voucher_type)) {
|
||||||
|
out.filters.push([jvd.reference_type, "is_return", "=", 1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(in_list(["Sales Order", "Purchase Order"], jvd.reference_type)) {
|
if(in_list(["Sales Order", "Purchase Order"], jvd.reference_type)) {
|
||||||
|
@ -331,7 +331,8 @@ class JournalEntry(AccountsController):
|
|||||||
for reference_name, total in iteritems(self.reference_totals):
|
for reference_name, total in iteritems(self.reference_totals):
|
||||||
reference_type = self.reference_types[reference_name]
|
reference_type = self.reference_types[reference_name]
|
||||||
|
|
||||||
if reference_type in ("Sales Invoice", "Purchase Invoice"):
|
if (reference_type in ("Sales Invoice", "Purchase Invoice") and
|
||||||
|
self.voucher_type not in ['Debit Note', 'Credit Note']):
|
||||||
invoice = frappe.db.get_value(reference_type, reference_name,
|
invoice = frappe.db.get_value(reference_type, reference_name,
|
||||||
["docstatus", "outstanding_amount"], as_dict=1)
|
["docstatus", "outstanding_amount"], as_dict=1)
|
||||||
|
|
||||||
@ -497,6 +498,7 @@ class JournalEntry(AccountsController):
|
|||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": d.account,
|
"account": d.account,
|
||||||
"party_type": d.party_type,
|
"party_type": d.party_type,
|
||||||
|
"due_date": self.due_date,
|
||||||
"party": d.party,
|
"party": d.party,
|
||||||
"against": d.against_account,
|
"against": d.against_account,
|
||||||
"debit": flt(d.debit, d.precision("debit")),
|
"debit": flt(d.debit, d.precision("debit")),
|
||||||
|
@ -302,7 +302,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
},
|
},
|
||||||
() => frm.set_value("party_balance", r.message.party_balance),
|
() => frm.set_value("party_balance", r.message.party_balance),
|
||||||
() => frm.set_value("party_name", r.message.party_name),
|
() => frm.set_value("party_name", r.message.party_name),
|
||||||
() => frm.events.get_outstanding_documents(frm),
|
() => frm.clear_table("references"),
|
||||||
() => frm.events.hide_unhide_fields(frm),
|
() => frm.events.hide_unhide_fields(frm),
|
||||||
() => frm.events.set_dynamic_labels(frm),
|
() => frm.events.set_dynamic_labels(frm),
|
||||||
() => {
|
() => {
|
||||||
@ -323,9 +323,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
|
|
||||||
frm.events.set_account_currency_and_balance(frm, frm.doc.paid_from,
|
frm.events.set_account_currency_and_balance(frm, frm.doc.paid_from,
|
||||||
"paid_from_account_currency", "paid_from_account_balance", function(frm) {
|
"paid_from_account_currency", "paid_from_account_balance", function(frm) {
|
||||||
if (frm.doc.payment_type == "Receive") {
|
if (frm.doc.payment_type == "Pay") {
|
||||||
frm.events.get_outstanding_documents(frm);
|
|
||||||
} else if (frm.doc.payment_type == "Pay") {
|
|
||||||
frm.events.paid_amount(frm);
|
frm.events.paid_amount(frm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -337,9 +335,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
|
|
||||||
frm.events.set_account_currency_and_balance(frm, frm.doc.paid_to,
|
frm.events.set_account_currency_and_balance(frm, frm.doc.paid_to,
|
||||||
"paid_to_account_currency", "paid_to_account_balance", function(frm) {
|
"paid_to_account_currency", "paid_to_account_balance", function(frm) {
|
||||||
if(frm.doc.payment_type == "Pay") {
|
if (frm.doc.payment_type == "Receive") {
|
||||||
frm.events.get_outstanding_documents(frm);
|
|
||||||
} else if (frm.doc.payment_type == "Receive") {
|
|
||||||
if(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) {
|
if(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) {
|
||||||
if(frm.doc.source_exchange_rate) {
|
if(frm.doc.source_exchange_rate) {
|
||||||
frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate);
|
frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate);
|
||||||
@ -533,26 +529,87 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
frm.events.set_unallocated_amount(frm);
|
frm.events.set_unallocated_amount(frm);
|
||||||
},
|
},
|
||||||
|
|
||||||
get_outstanding_documents: function(frm) {
|
get_outstanding_invoice: function(frm) {
|
||||||
|
const today = frappe.datetime.get_today();
|
||||||
|
const fields = [
|
||||||
|
{fieldtype:"Section Break", label: __("Posting Date")},
|
||||||
|
{fieldtype:"Date", label: __("From Date"),
|
||||||
|
fieldname:"from_posting_date", default:frappe.datetime.add_days(today, -30)},
|
||||||
|
{fieldtype:"Column Break"},
|
||||||
|
{fieldtype:"Date", label: __("To Date"), fieldname:"to_posting_date", default:today},
|
||||||
|
{fieldtype:"Section Break", label: __("Due Date")},
|
||||||
|
{fieldtype:"Date", label: __("From Date"), fieldname:"from_due_date"},
|
||||||
|
{fieldtype:"Column Break"},
|
||||||
|
{fieldtype:"Date", label: __("To Date"), fieldname:"to_due_date"},
|
||||||
|
{fieldtype:"Section Break", label: __("Outstanding Amount")},
|
||||||
|
{fieldtype:"Float", label: __("Greater Than Amount"),
|
||||||
|
fieldname:"outstanding_amt_greater_than", default: 0},
|
||||||
|
{fieldtype:"Column Break"},
|
||||||
|
{fieldtype:"Float", label: __("Less Than Amount"), fieldname:"outstanding_amt_less_than"},
|
||||||
|
{fieldtype:"Section Break"},
|
||||||
|
{fieldtype:"Check", label: __("Allocate Payment Amount"), fieldname:"allocate_payment_amount", default:1},
|
||||||
|
];
|
||||||
|
|
||||||
|
frappe.prompt(fields, function(filters){
|
||||||
|
frappe.flags.allocate_payment_amount = true;
|
||||||
|
frm.events.validate_filters_data(frm, filters);
|
||||||
|
frm.events.get_outstanding_documents(frm, filters);
|
||||||
|
}, __("Filters"), __("Get Outstanding Invoices"));
|
||||||
|
},
|
||||||
|
|
||||||
|
validate_filters_data: function(frm, filters) {
|
||||||
|
const fields = {
|
||||||
|
'Posting Date': ['from_posting_date', 'to_posting_date'],
|
||||||
|
'Due Date': ['from_posting_date', 'to_posting_date'],
|
||||||
|
'Advance Amount': ['from_posting_date', 'to_posting_date'],
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let key in fields) {
|
||||||
|
let from_field = fields[key][0];
|
||||||
|
let to_field = fields[key][1];
|
||||||
|
|
||||||
|
if (filters[from_field] && !filters[to_field]) {
|
||||||
|
frappe.throw(__("Error: {0} is mandatory field",
|
||||||
|
[to_field.replace(/_/g, " ")]
|
||||||
|
));
|
||||||
|
} else if (filters[from_field] && filters[from_field] > filters[to_field]) {
|
||||||
|
frappe.throw(__("{0}: {1} must be less than {2}",
|
||||||
|
[key, from_field.replace(/_/g, " "), to_field.replace(/_/g, " ")]
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
get_outstanding_documents: function(frm, filters) {
|
||||||
frm.clear_table("references");
|
frm.clear_table("references");
|
||||||
|
|
||||||
if(!frm.doc.party) return;
|
if(!frm.doc.party) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
frm.events.check_mandatory_to_fetch(frm);
|
frm.events.check_mandatory_to_fetch(frm);
|
||||||
var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
|
var company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
|
||||||
|
|
||||||
|
var args = {
|
||||||
|
"posting_date": frm.doc.posting_date,
|
||||||
|
"company": frm.doc.company,
|
||||||
|
"party_type": frm.doc.party_type,
|
||||||
|
"payment_type": frm.doc.payment_type,
|
||||||
|
"party": frm.doc.party,
|
||||||
|
"party_account": frm.doc.payment_type=="Receive" ? frm.doc.paid_from : frm.doc.paid_to,
|
||||||
|
"cost_center": frm.doc.cost_center
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let key in filters) {
|
||||||
|
args[key] = filters[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
frappe.flags.allocate_payment_amount = filters['allocate_payment_amount'];
|
||||||
|
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
method: 'erpnext.accounts.doctype.payment_entry.payment_entry.get_outstanding_reference_documents',
|
method: 'erpnext.accounts.doctype.payment_entry.payment_entry.get_outstanding_reference_documents',
|
||||||
args: {
|
args: {
|
||||||
args: {
|
args:args
|
||||||
"posting_date": frm.doc.posting_date,
|
|
||||||
"company": frm.doc.company,
|
|
||||||
"party_type": frm.doc.party_type,
|
|
||||||
"payment_type": frm.doc.payment_type,
|
|
||||||
"party": frm.doc.party,
|
|
||||||
"party_account": frm.doc.payment_type=="Receive" ? frm.doc.paid_from : frm.doc.paid_to,
|
|
||||||
"cost_center": frm.doc.cost_center
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
callback: function(r, rt) {
|
callback: function(r, rt) {
|
||||||
if(r.message) {
|
if(r.message) {
|
||||||
@ -608,25 +665,11 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
|
|
||||||
frm.events.allocate_party_amount_against_ref_docs(frm,
|
frm.events.allocate_party_amount_against_ref_docs(frm,
|
||||||
(frm.doc.payment_type=="Receive" ? frm.doc.paid_amount : frm.doc.received_amount));
|
(frm.doc.payment_type=="Receive" ? frm.doc.paid_amount : frm.doc.received_amount));
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
allocate_payment_amount: function(frm) {
|
|
||||||
if(frm.doc.payment_type == 'Internal Transfer'){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if(frm.doc.references.length == 0){
|
|
||||||
frm.events.get_outstanding_documents(frm);
|
|
||||||
}
|
|
||||||
if(frm.doc.payment_type == 'Internal Transfer') {
|
|
||||||
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount);
|
|
||||||
} else {
|
|
||||||
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
allocate_party_amount_against_ref_docs: function(frm, paid_amount) {
|
allocate_party_amount_against_ref_docs: function(frm, paid_amount) {
|
||||||
var total_positive_outstanding_including_order = 0;
|
var total_positive_outstanding_including_order = 0;
|
||||||
var total_negative_outstanding = 0;
|
var total_negative_outstanding = 0;
|
||||||
@ -677,7 +720,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
|
|
||||||
$.each(frm.doc.references || [], function(i, row) {
|
$.each(frm.doc.references || [], function(i, row) {
|
||||||
row.allocated_amount = 0 //If allocate payment amount checkbox is unchecked, set zero to allocate amount
|
row.allocated_amount = 0 //If allocate payment amount checkbox is unchecked, set zero to allocate amount
|
||||||
if(frm.doc.allocate_payment_amount){
|
if(frappe.flags.allocate_payment_amount){
|
||||||
if(row.outstanding_amount > 0 && allocated_positive_outstanding > 0) {
|
if(row.outstanding_amount > 0 && allocated_positive_outstanding > 0) {
|
||||||
if(row.outstanding_amount >= allocated_positive_outstanding) {
|
if(row.outstanding_amount >= allocated_positive_outstanding) {
|
||||||
row.allocated_amount = allocated_positive_outstanding;
|
row.allocated_amount = allocated_positive_outstanding;
|
||||||
@ -958,7 +1001,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
if(frm.doc.payment_type != "Internal") {
|
if(frm.doc.payment_type != "Internal") {
|
||||||
frm.events.get_outstanding_documents(frm);
|
frm.clear_table("references");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
"target_exchange_rate",
|
"target_exchange_rate",
|
||||||
"base_received_amount",
|
"base_received_amount",
|
||||||
"section_break_14",
|
"section_break_14",
|
||||||
"allocate_payment_amount",
|
"get_outstanding_invoice",
|
||||||
"references",
|
"references",
|
||||||
"section_break_34",
|
"section_break_34",
|
||||||
"total_allocated_amount",
|
"total_allocated_amount",
|
||||||
@ -325,19 +325,15 @@
|
|||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
|
||||||
"collapsible_depends_on": "references",
|
|
||||||
"depends_on": "eval:(doc.party && doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)",
|
"depends_on": "eval:(doc.party && doc.paid_from && doc.paid_to && doc.paid_amount && doc.received_amount)",
|
||||||
"fieldname": "section_break_14",
|
"fieldname": "section_break_14",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Reference"
|
"label": "Reference"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "1",
|
"fieldname": "get_outstanding_invoice",
|
||||||
"depends_on": "eval:in_list(['Pay', 'Receive'], doc.payment_type)",
|
"fieldtype": "Button",
|
||||||
"fieldname": "allocate_payment_amount",
|
"label": "Get Outstanding Invoice"
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Allocate Payment Amount"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "references",
|
"fieldname": "references",
|
||||||
@ -570,7 +566,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-05-25 22:02:40.575822",
|
"modified": "2019-05-27 15:53:21.108857",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Payment Entry",
|
"name": "Payment Entry",
|
||||||
|
@ -535,6 +535,20 @@ class PaymentEntry(AccountsController):
|
|||||||
"amount": self.total_allocated_amount * (tax_details['tax']['rate'] / 100)
|
"amount": self.total_allocated_amount * (tax_details['tax']['rate'] / 100)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def set_gain_or_loss(self, account_details=None):
|
||||||
|
if not self.difference_amount:
|
||||||
|
self.set_difference_amount()
|
||||||
|
|
||||||
|
row = {
|
||||||
|
'amount': self.difference_amount
|
||||||
|
}
|
||||||
|
|
||||||
|
if account_details:
|
||||||
|
row.update(account_details)
|
||||||
|
|
||||||
|
self.append('deductions', row)
|
||||||
|
self.set_unallocated_amount()
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_outstanding_reference_documents(args):
|
def get_outstanding_reference_documents(args):
|
||||||
|
|
||||||
@ -560,8 +574,8 @@ def get_outstanding_reference_documents(args):
|
|||||||
# Get negative outstanding sales /purchase invoices
|
# Get negative outstanding sales /purchase invoices
|
||||||
negative_outstanding_invoices = []
|
negative_outstanding_invoices = []
|
||||||
if args.get("party_type") not in ["Student", "Employee"] and not args.get("voucher_no"):
|
if args.get("party_type") not in ["Student", "Employee"] and not args.get("voucher_no"):
|
||||||
negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"),
|
negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"), args.get("party"),
|
||||||
args.get("party"), args.get("party_account"), party_account_currency, company_currency)
|
args.get("party_account"), args.get("company"), party_account_currency, company_currency)
|
||||||
|
|
||||||
# Get positive outstanding sales /purchase invoices/ Fees
|
# Get positive outstanding sales /purchase invoices/ Fees
|
||||||
condition = ""
|
condition = ""
|
||||||
@ -571,10 +585,23 @@ def get_outstanding_reference_documents(args):
|
|||||||
|
|
||||||
# Add cost center condition
|
# Add cost center condition
|
||||||
if args.get("cost_center") and get_allow_cost_center_in_entry_of_bs_account():
|
if args.get("cost_center") and get_allow_cost_center_in_entry_of_bs_account():
|
||||||
condition += " and cost_center='%s'" % args.get("cost_center")
|
condition += " and cost_center='%s'" % args.get("cost_center")
|
||||||
|
|
||||||
|
date_fields_dict = {
|
||||||
|
'posting_date': ['from_posting_date', 'to_posting_date'],
|
||||||
|
'due_date': ['from_due_date', 'to_due_date']
|
||||||
|
}
|
||||||
|
|
||||||
|
for fieldname, date_fields in date_fields_dict.items():
|
||||||
|
if args.get(date_fields[0]) and args.get(date_fields[1]):
|
||||||
|
condition += " and {0} between '{1}' and '{2}'".format(fieldname,
|
||||||
|
args.get(date_fields[0]), args.get(date_fields[1]))
|
||||||
|
|
||||||
|
if args.get("company"):
|
||||||
|
condition += " and company = {0}".format(frappe.db.escape(args.get("company")))
|
||||||
|
|
||||||
outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
|
outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
|
||||||
args.get("party_account"), condition=condition)
|
args.get("party_account"), filters=args, condition=condition, limit=100)
|
||||||
|
|
||||||
for d in outstanding_invoices:
|
for d in outstanding_invoices:
|
||||||
d["exchange_rate"] = 1
|
d["exchange_rate"] = 1
|
||||||
@ -592,12 +619,19 @@ def get_outstanding_reference_documents(args):
|
|||||||
orders_to_be_billed = []
|
orders_to_be_billed = []
|
||||||
if (args.get("party_type") != "Student"):
|
if (args.get("party_type") != "Student"):
|
||||||
orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"),
|
orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"),
|
||||||
args.get("party"), party_account_currency, company_currency)
|
args.get("party"), args.get("company"), party_account_currency, company_currency, filters=args)
|
||||||
|
|
||||||
return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
|
data = negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
|
||||||
|
|
||||||
|
if not data:
|
||||||
|
frappe.msgprint(_("No outstanding invoices found for the {0} <b>{1}</b>.")
|
||||||
|
.format(args.get("party_type").lower(), args.get("party")))
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
def get_orders_to_be_billed(posting_date, party_type, party, party_account_currency, company_currency, cost_center=None):
|
def get_orders_to_be_billed(posting_date, party_type, party,
|
||||||
|
company, party_account_currency, company_currency, cost_center=None, filters=None):
|
||||||
if party_type == "Customer":
|
if party_type == "Customer":
|
||||||
voucher_type = 'Sales Order'
|
voucher_type = 'Sales Order'
|
||||||
elif party_type == "Supplier":
|
elif party_type == "Supplier":
|
||||||
@ -627,6 +661,7 @@ def get_orders_to_be_billed(posting_date, party_type, party, party_account_curre
|
|||||||
where
|
where
|
||||||
{party_type} = %s
|
{party_type} = %s
|
||||||
and docstatus = 1
|
and docstatus = 1
|
||||||
|
and company = %s
|
||||||
and ifnull(status, "") != "Closed"
|
and ifnull(status, "") != "Closed"
|
||||||
and {ref_field} > advance_paid
|
and {ref_field} > advance_paid
|
||||||
and abs(100 - per_billed) > 0.01
|
and abs(100 - per_billed) > 0.01
|
||||||
@ -638,10 +673,14 @@ def get_orders_to_be_billed(posting_date, party_type, party, party_account_curre
|
|||||||
"voucher_type": voucher_type,
|
"voucher_type": voucher_type,
|
||||||
"party_type": scrub(party_type),
|
"party_type": scrub(party_type),
|
||||||
"condition": condition
|
"condition": condition
|
||||||
}), party, as_dict=True)
|
}), (party, company), as_dict=True)
|
||||||
|
|
||||||
order_list = []
|
order_list = []
|
||||||
for d in orders:
|
for d in orders:
|
||||||
|
if not (d.outstanding_amount >= filters.get("outstanding_amt_greater_than")
|
||||||
|
and d.outstanding_amount <= filters.get("outstanding_amt_less_than")):
|
||||||
|
continue
|
||||||
|
|
||||||
d["voucher_type"] = voucher_type
|
d["voucher_type"] = voucher_type
|
||||||
# This assumes that the exchange rate required is the one in the SO
|
# This assumes that the exchange rate required is the one in the SO
|
||||||
d["exchange_rate"] = get_exchange_rate(party_account_currency, company_currency, posting_date)
|
d["exchange_rate"] = get_exchange_rate(party_account_currency, company_currency, posting_date)
|
||||||
@ -649,7 +688,8 @@ def get_orders_to_be_billed(posting_date, party_type, party, party_account_curre
|
|||||||
|
|
||||||
return order_list
|
return order_list
|
||||||
|
|
||||||
def get_negative_outstanding_invoices(party_type, party, party_account, party_account_currency, company_currency, cost_center=None):
|
def get_negative_outstanding_invoices(party_type, party, party_account,
|
||||||
|
company, party_account_currency, company_currency, cost_center=None):
|
||||||
voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice"
|
voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice"
|
||||||
supplier_condition = ""
|
supplier_condition = ""
|
||||||
if voucher_type == "Purchase Invoice":
|
if voucher_type == "Purchase Invoice":
|
||||||
@ -670,7 +710,8 @@ def get_negative_outstanding_invoices(party_type, party, party_account, party_ac
|
|||||||
from
|
from
|
||||||
`tab{voucher_type}`
|
`tab{voucher_type}`
|
||||||
where
|
where
|
||||||
{party_type} = %s and {party_account} = %s and docstatus = 1 and outstanding_amount < 0
|
{party_type} = %s and {party_account} = %s and docstatus = 1 and
|
||||||
|
company = %s and outstanding_amount < 0
|
||||||
{supplier_condition}
|
{supplier_condition}
|
||||||
order by
|
order by
|
||||||
posting_date, name
|
posting_date, name
|
||||||
@ -682,7 +723,7 @@ def get_negative_outstanding_invoices(party_type, party, party_account, party_ac
|
|||||||
"party_type": scrub(party_type),
|
"party_type": scrub(party_type),
|
||||||
"party_account": "debit_to" if party_type == "Customer" else "credit_to",
|
"party_account": "debit_to" if party_type == "Customer" else "credit_to",
|
||||||
"cost_center": cost_center
|
"cost_center": cost_center
|
||||||
}), (party, party_account), as_dict=True)
|
}), (party, party_account, company), as_dict=True)
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@ -910,7 +951,6 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
|||||||
pe.paid_to_account_currency = party_account_currency if payment_type=="Pay" else bank.account_currency
|
pe.paid_to_account_currency = party_account_currency if payment_type=="Pay" else bank.account_currency
|
||||||
pe.paid_amount = paid_amount
|
pe.paid_amount = paid_amount
|
||||||
pe.received_amount = received_amount
|
pe.received_amount = received_amount
|
||||||
pe.allocate_payment_amount = 1
|
|
||||||
pe.letter_head = doc.get("letter_head")
|
pe.letter_head = doc.get("letter_head")
|
||||||
|
|
||||||
if pe.party_type in ["Customer", "Supplier"]:
|
if pe.party_type in ["Customer", "Supplier"]:
|
||||||
|
@ -16,6 +16,20 @@ frappe.ui.form.on("Payment Reconciliation Payment", {
|
|||||||
})[0].outstanding_amount;
|
})[0].outstanding_amount;
|
||||||
|
|
||||||
frappe.model.set_value(cdt, cdn, "allocated_amount", Math.min(invoice_amount, row.amount));
|
frappe.model.set_value(cdt, cdn, "allocated_amount", Math.min(invoice_amount, row.amount));
|
||||||
|
|
||||||
|
frm.call({
|
||||||
|
doc: frm.doc,
|
||||||
|
method: 'get_difference_amount',
|
||||||
|
args: {
|
||||||
|
child_row: row
|
||||||
|
},
|
||||||
|
callback: function(r, rt) {
|
||||||
|
if(r.message) {
|
||||||
|
frappe.model.set_value(cdt, cdn,
|
||||||
|
"difference_amount", r.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -104,6 +118,91 @@ erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.ext
|
|||||||
|
|
||||||
reconcile: function() {
|
reconcile: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
|
var show_dialog = me.frm.doc.payments.filter(d => d.difference_amount && !d.difference_account);
|
||||||
|
|
||||||
|
if (show_dialog && show_dialog.length) {
|
||||||
|
|
||||||
|
this.data = [];
|
||||||
|
const dialog = new frappe.ui.Dialog({
|
||||||
|
title: __("Select Difference Account"),
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
fieldname: "payments", fieldtype: "Table", label: __("Payments"),
|
||||||
|
data: this.data, in_place_edit: true,
|
||||||
|
get_data: () => {
|
||||||
|
return this.data;
|
||||||
|
},
|
||||||
|
fields: [{
|
||||||
|
fieldtype:'Data',
|
||||||
|
fieldname:"docname",
|
||||||
|
in_list_view: 1,
|
||||||
|
hidden: 1
|
||||||
|
}, {
|
||||||
|
fieldtype:'Data',
|
||||||
|
fieldname:"reference_name",
|
||||||
|
label: __("Voucher No"),
|
||||||
|
in_list_view: 1,
|
||||||
|
read_only: 1
|
||||||
|
}, {
|
||||||
|
fieldtype:'Link',
|
||||||
|
options: 'Account',
|
||||||
|
in_list_view: 1,
|
||||||
|
label: __("Difference Account"),
|
||||||
|
fieldname: 'difference_account',
|
||||||
|
reqd: 1,
|
||||||
|
get_query: function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
company: me.frm.doc.company,
|
||||||
|
is_group: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
fieldtype:'Currency',
|
||||||
|
in_list_view: 1,
|
||||||
|
label: __("Difference Amount"),
|
||||||
|
fieldname: 'difference_amount',
|
||||||
|
read_only: 1
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
primary_action: function() {
|
||||||
|
const args = dialog.get_values()["payments"];
|
||||||
|
|
||||||
|
args.forEach(d => {
|
||||||
|
frappe.model.set_value("Payment Reconciliation Payment", d.docname,
|
||||||
|
"difference_account", d.difference_account);
|
||||||
|
});
|
||||||
|
|
||||||
|
me.reconcile_payment_entries();
|
||||||
|
dialog.hide();
|
||||||
|
},
|
||||||
|
primary_action_label: __('Reconcile Entries')
|
||||||
|
});
|
||||||
|
|
||||||
|
this.frm.doc.payments.forEach(d => {
|
||||||
|
if (d.difference_amount && !d.difference_account) {
|
||||||
|
dialog.fields_dict.payments.df.data.push({
|
||||||
|
'docname': d.name,
|
||||||
|
'reference_name': d.reference_name,
|
||||||
|
'difference_amount': d.difference_amount,
|
||||||
|
'difference_account': d.difference_account,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.data = dialog.fields_dict.payments.df.data;
|
||||||
|
dialog.fields_dict.payments.grid.refresh();
|
||||||
|
dialog.show();
|
||||||
|
} else {
|
||||||
|
this.reconcile_payment_entries();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
reconcile_payment_entries: function() {
|
||||||
|
var me = this;
|
||||||
|
|
||||||
return this.frm.call({
|
return this.frm.call({
|
||||||
doc: me.frm.doc,
|
doc: me.frm.doc,
|
||||||
method: 'reconcile',
|
method: 'reconcile',
|
||||||
|
@ -3,10 +3,11 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe, erpnext
|
import frappe, erpnext
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt, today
|
||||||
from frappe import msgprint, _
|
from frappe import msgprint, _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.accounts.utils import get_outstanding_invoices
|
from erpnext.accounts.utils import (get_outstanding_invoices,
|
||||||
|
update_reference_in_payment_entry, reconcile_against_document)
|
||||||
from erpnext.controllers.accounts_controller import get_advance_payment_entries
|
from erpnext.controllers.accounts_controller import get_advance_payment_entries
|
||||||
|
|
||||||
class PaymentReconciliation(Document):
|
class PaymentReconciliation(Document):
|
||||||
@ -20,14 +21,16 @@ class PaymentReconciliation(Document):
|
|||||||
payment_entries = self.get_payment_entries()
|
payment_entries = self.get_payment_entries()
|
||||||
journal_entries = self.get_jv_entries()
|
journal_entries = self.get_jv_entries()
|
||||||
|
|
||||||
self.add_payment_entries(payment_entries + journal_entries)
|
if self.party_type in ["Customer", "Supplier"]:
|
||||||
|
dr_or_cr_notes = self.get_dr_or_cr_notes()
|
||||||
|
|
||||||
|
self.add_payment_entries(payment_entries + journal_entries + dr_or_cr_notes)
|
||||||
|
|
||||||
def get_payment_entries(self):
|
def get_payment_entries(self):
|
||||||
order_doctype = "Sales Order" if self.party_type=="Customer" else "Purchase Order"
|
order_doctype = "Sales Order" if self.party_type=="Customer" else "Purchase Order"
|
||||||
|
|
||||||
payment_entries = get_advance_payment_entries(self.party_type, self.party,
|
payment_entries = get_advance_payment_entries(self.party_type, self.party,
|
||||||
self.receivable_payable_account, order_doctype, against_all_orders=True, limit=self.limit)
|
self.receivable_payable_account, order_doctype, against_all_orders=True, limit=self.limit)
|
||||||
|
|
||||||
return payment_entries
|
return payment_entries
|
||||||
|
|
||||||
def get_jv_entries(self):
|
def get_jv_entries(self):
|
||||||
@ -37,7 +40,7 @@ class PaymentReconciliation(Document):
|
|||||||
bank_account_condition = "t2.against_account like %(bank_cash_account)s" \
|
bank_account_condition = "t2.against_account like %(bank_cash_account)s" \
|
||||||
if self.bank_cash_account else "1=1"
|
if self.bank_cash_account else "1=1"
|
||||||
|
|
||||||
limit_cond = "limit %s" % (self.limit or 1000)
|
limit_cond = "limit %s" % self.limit if self.limit else ""
|
||||||
|
|
||||||
journal_entries = frappe.db.sql("""
|
journal_entries = frappe.db.sql("""
|
||||||
select
|
select
|
||||||
@ -72,6 +75,34 @@ class PaymentReconciliation(Document):
|
|||||||
|
|
||||||
return list(journal_entries)
|
return list(journal_entries)
|
||||||
|
|
||||||
|
def get_dr_or_cr_notes(self):
|
||||||
|
dr_or_cr = ("credit_in_account_currency"
|
||||||
|
if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit_in_account_currency")
|
||||||
|
|
||||||
|
reconciled_dr_or_cr = ("debit_in_account_currency"
|
||||||
|
if dr_or_cr == "credit_in_account_currency" else "credit_in_account_currency")
|
||||||
|
|
||||||
|
voucher_type = ('Sales Invoice'
|
||||||
|
if self.party_type == 'Customer' else "Purchase Invoice")
|
||||||
|
|
||||||
|
return frappe.db.sql(""" SELECT `tab{doc}`.name as reference_name, %(voucher_type)s as reference_type,
|
||||||
|
(sum(`tabGL Entry`.{dr_or_cr}) - sum(`tabGL Entry`.{reconciled_dr_or_cr})) as amount
|
||||||
|
FROM `tab{doc}`, `tabGL Entry`
|
||||||
|
WHERE
|
||||||
|
(`tab{doc}`.name = `tabGL Entry`.against_voucher or `tab{doc}`.name = `tabGL Entry`.voucher_no)
|
||||||
|
and `tab{doc}`.is_return = 1 and `tabGL Entry`.against_voucher_type = %(voucher_type)s
|
||||||
|
and `tab{doc}`.docstatus = 1 and `tabGL Entry`.party = %(party)s
|
||||||
|
and `tabGL Entry`.party_type = %(party_type)s and `tabGL Entry`.account = %(account)s
|
||||||
|
GROUP BY `tabSales Invoice`.name
|
||||||
|
Having
|
||||||
|
amount > 0
|
||||||
|
""".format(doc=voucher_type, dr_or_cr=dr_or_cr, reconciled_dr_or_cr=reconciled_dr_or_cr), {
|
||||||
|
'party': self.party,
|
||||||
|
'party_type': self.party_type,
|
||||||
|
'voucher_type': voucher_type,
|
||||||
|
'account': self.receivable_payable_account
|
||||||
|
}, as_dict=1)
|
||||||
|
|
||||||
def add_payment_entries(self, entries):
|
def add_payment_entries(self, entries):
|
||||||
self.set('payments', [])
|
self.set('payments', [])
|
||||||
for e in entries:
|
for e in entries:
|
||||||
@ -84,7 +115,10 @@ class PaymentReconciliation(Document):
|
|||||||
condition = self.check_condition()
|
condition = self.check_condition()
|
||||||
|
|
||||||
non_reconciled_invoices = get_outstanding_invoices(self.party_type, self.party,
|
non_reconciled_invoices = get_outstanding_invoices(self.party_type, self.party,
|
||||||
self.receivable_payable_account, condition=condition, limit=self.limit)
|
self.receivable_payable_account, condition=condition)
|
||||||
|
|
||||||
|
if self.limit:
|
||||||
|
non_reconciled_invoices = non_reconciled_invoices[:self.limit]
|
||||||
|
|
||||||
self.add_invoice_entries(non_reconciled_invoices)
|
self.add_invoice_entries(non_reconciled_invoices)
|
||||||
|
|
||||||
@ -112,36 +146,67 @@ class PaymentReconciliation(Document):
|
|||||||
if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit_in_account_currency")
|
if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit_in_account_currency")
|
||||||
|
|
||||||
lst = []
|
lst = []
|
||||||
|
dr_or_cr_notes = []
|
||||||
for e in self.get('payments'):
|
for e in self.get('payments'):
|
||||||
|
reconciled_entry = []
|
||||||
if e.invoice_number and e.allocated_amount:
|
if e.invoice_number and e.allocated_amount:
|
||||||
lst.append(frappe._dict({
|
if e.reference_type in ['Sales Invoice', 'Purchase Invoice']:
|
||||||
'voucher_type': e.reference_type,
|
reconciled_entry = dr_or_cr_notes
|
||||||
'voucher_no' : e.reference_name,
|
else:
|
||||||
'voucher_detail_no' : e.reference_row,
|
reconciled_entry = lst
|
||||||
'against_voucher_type' : e.invoice_type,
|
|
||||||
'against_voucher' : e.invoice_number,
|
reconciled_entry.append(self.get_payment_details(e, dr_or_cr))
|
||||||
'account' : self.receivable_payable_account,
|
|
||||||
'party_type': self.party_type,
|
|
||||||
'party': self.party,
|
|
||||||
'is_advance' : e.is_advance,
|
|
||||||
'dr_or_cr' : dr_or_cr,
|
|
||||||
'unadjusted_amount' : flt(e.amount),
|
|
||||||
'allocated_amount' : flt(e.allocated_amount)
|
|
||||||
}))
|
|
||||||
|
|
||||||
if lst:
|
if lst:
|
||||||
from erpnext.accounts.utils import reconcile_against_document
|
|
||||||
reconcile_against_document(lst)
|
reconcile_against_document(lst)
|
||||||
|
|
||||||
msgprint(_("Successfully Reconciled"))
|
if dr_or_cr_notes:
|
||||||
self.get_unreconciled_entries()
|
reconcile_dr_cr_note(dr_or_cr_notes)
|
||||||
|
|
||||||
|
msgprint(_("Successfully Reconciled"))
|
||||||
|
self.get_unreconciled_entries()
|
||||||
|
|
||||||
|
def get_payment_details(self, row, dr_or_cr):
|
||||||
|
return frappe._dict({
|
||||||
|
'voucher_type': row.reference_type,
|
||||||
|
'voucher_no' : row.reference_name,
|
||||||
|
'voucher_detail_no' : row.reference_row,
|
||||||
|
'against_voucher_type' : row.invoice_type,
|
||||||
|
'against_voucher' : row.invoice_number,
|
||||||
|
'account' : self.receivable_payable_account,
|
||||||
|
'party_type': self.party_type,
|
||||||
|
'party': self.party,
|
||||||
|
'is_advance' : row.is_advance,
|
||||||
|
'dr_or_cr' : dr_or_cr,
|
||||||
|
'unadjusted_amount' : flt(row.amount),
|
||||||
|
'allocated_amount' : flt(row.allocated_amount),
|
||||||
|
'difference_amount': row.difference_amount,
|
||||||
|
'difference_account': row.difference_account
|
||||||
|
})
|
||||||
|
|
||||||
|
def get_difference_amount(self, child_row):
|
||||||
|
if child_row.get("reference_type") != 'Payment Entry': return
|
||||||
|
|
||||||
|
child_row = frappe._dict(child_row)
|
||||||
|
|
||||||
|
if child_row.invoice_number and " | " in child_row.invoice_number:
|
||||||
|
child_row.invoice_type, child_row.invoice_number = child_row.invoice_number.split(" | ")
|
||||||
|
|
||||||
|
dr_or_cr = ("credit_in_account_currency"
|
||||||
|
if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit_in_account_currency")
|
||||||
|
|
||||||
|
row = self.get_payment_details(child_row, dr_or_cr)
|
||||||
|
|
||||||
|
doc = frappe.get_doc(row.voucher_type, row.voucher_no)
|
||||||
|
update_reference_in_payment_entry(row, doc, do_not_save=True)
|
||||||
|
|
||||||
|
return doc.difference_amount
|
||||||
|
|
||||||
def check_mandatory_to_fetch(self):
|
def check_mandatory_to_fetch(self):
|
||||||
for fieldname in ["company", "party_type", "party", "receivable_payable_account"]:
|
for fieldname in ["company", "party_type", "party", "receivable_payable_account"]:
|
||||||
if not self.get(fieldname):
|
if not self.get(fieldname):
|
||||||
frappe.throw(_("Please select {0} first").format(self.meta.get_label(fieldname)))
|
frappe.throw(_("Please select {0} first").format(self.meta.get_label(fieldname)))
|
||||||
|
|
||||||
|
|
||||||
def validate_invoice(self):
|
def validate_invoice(self):
|
||||||
if not self.get("invoices"):
|
if not self.get("invoices"):
|
||||||
frappe.throw(_("No records found in the Invoice table"))
|
frappe.throw(_("No records found in the Invoice table"))
|
||||||
@ -186,3 +251,41 @@ class PaymentReconciliation(Document):
|
|||||||
cond += " and `{0}` <= {1}".format(dr_or_cr, flt(self.maximum_amount))
|
cond += " and `{0}` <= {1}".format(dr_or_cr, flt(self.maximum_amount))
|
||||||
|
|
||||||
return cond
|
return cond
|
||||||
|
|
||||||
|
def reconcile_dr_cr_note(dr_cr_notes):
|
||||||
|
for d in dr_cr_notes:
|
||||||
|
voucher_type = ('Credit Note'
|
||||||
|
if d.voucher_type == 'Sales Invoice' else 'Debit Note')
|
||||||
|
|
||||||
|
dr_or_cr = ('credit_in_account_currency'
|
||||||
|
if d.reference_type == 'Sales Invoice' else 'debit_in_account_currency')
|
||||||
|
|
||||||
|
reconcile_dr_or_cr = ('debit_in_account_currency'
|
||||||
|
if dr_or_cr == 'credit_in_account_currency' else 'credit_in_account_currency')
|
||||||
|
|
||||||
|
jv = frappe.get_doc({
|
||||||
|
"doctype": "Journal Entry",
|
||||||
|
"voucher_type": voucher_type,
|
||||||
|
"posting_date": today(),
|
||||||
|
"accounts": [
|
||||||
|
{
|
||||||
|
'account': d.account,
|
||||||
|
'party': d.party,
|
||||||
|
'party_type': d.party_type,
|
||||||
|
reconcile_dr_or_cr: (abs(d.allocated_amount)
|
||||||
|
if abs(d.unadjusted_amount) > abs(d.allocated_amount) else abs(d.unadjusted_amount)),
|
||||||
|
'reference_type': d.against_voucher_type,
|
||||||
|
'reference_name': d.against_voucher
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'account': d.account,
|
||||||
|
'party': d.party,
|
||||||
|
'party_type': d.party_type,
|
||||||
|
dr_or_cr: abs(d.allocated_amount),
|
||||||
|
'reference_type': d.voucher_type,
|
||||||
|
'reference_name': d.voucher_no
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
jv.submit()
|
@ -1,389 +1,127 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"creation": "2014-07-09 16:13:35.452759",
|
||||||
"allow_events_in_timeline": 0,
|
"doctype": "DocType",
|
||||||
"allow_guest_to_view": 0,
|
"editable_grid": 1,
|
||||||
"allow_import": 0,
|
"field_order": [
|
||||||
"allow_rename": 0,
|
"reference_type",
|
||||||
"beta": 0,
|
"reference_name",
|
||||||
"creation": "2014-07-09 16:13:35.452759",
|
"posting_date",
|
||||||
"custom": 0,
|
"is_advance",
|
||||||
"docstatus": 0,
|
"reference_row",
|
||||||
"doctype": "DocType",
|
"col_break1",
|
||||||
"document_type": "",
|
"invoice_number",
|
||||||
"editable_grid": 1,
|
"amount",
|
||||||
|
"allocated_amount",
|
||||||
|
"section_break_10",
|
||||||
|
"difference_account",
|
||||||
|
"difference_amount",
|
||||||
|
"sec_break1",
|
||||||
|
"remark"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "reference_type",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"label": "Reference Type",
|
||||||
"bold": 0,
|
"options": "DocType",
|
||||||
"collapsible": 0,
|
"read_only": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "reference_type",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Reference Type",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "DocType",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "reference_name",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Dynamic Link",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Reference Name",
|
||||||
"columns": 3,
|
"options": "reference_type",
|
||||||
"fieldname": "reference_name",
|
"read_only": 1
|
||||||
"fieldtype": "Dynamic Link",
|
},
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Reference Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "reference_type",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "posting_date",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Date",
|
||||||
"allow_on_submit": 0,
|
"label": "Posting Date",
|
||||||
"bold": 0,
|
"read_only": 1
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "posting_date",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Posting Date",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "is_advance",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Data",
|
||||||
"allow_on_submit": 0,
|
"hidden": 1,
|
||||||
"bold": 0,
|
"label": "Is Advance",
|
||||||
"collapsible": 0,
|
"read_only": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "is_advance",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 1,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Is Advance",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "reference_row",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Data",
|
||||||
"allow_on_submit": 0,
|
"hidden": 1,
|
||||||
"bold": 0,
|
"label": "Reference Row",
|
||||||
"collapsible": 0,
|
"read_only": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "reference_row",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 1,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Reference Row",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "col_break1",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Column Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "col_break1",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "invoice_number",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Select",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Invoice Number",
|
||||||
"columns": 3,
|
"reqd": 1
|
||||||
"fieldname": "invoice_number",
|
},
|
||||||
"fieldtype": "Select",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Invoice Number",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "amount",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Currency",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Amount",
|
||||||
"columns": 2,
|
"read_only": 1
|
||||||
"fieldname": "amount",
|
},
|
||||||
"fieldtype": "Currency",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Amount",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "allocated_amount",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Currency",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Allocated amount",
|
||||||
"columns": 2,
|
"reqd": 1
|
||||||
"fieldname": "allocated_amount",
|
},
|
||||||
"fieldtype": "Currency",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Allocated amount",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "sec_break1",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Section Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "sec_break1",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "remark",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Small Text",
|
||||||
"allow_on_submit": 0,
|
"in_list_view": 1,
|
||||||
"bold": 0,
|
"label": "Remark",
|
||||||
"collapsible": 0,
|
"read_only": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "remark",
|
{
|
||||||
"fieldtype": "Small Text",
|
"columns": 2,
|
||||||
"hidden": 0,
|
"fieldname": "difference_account",
|
||||||
"ignore_user_permissions": 0,
|
"fieldtype": "Link",
|
||||||
"ignore_xss_filter": 0,
|
"in_list_view": 1,
|
||||||
"in_filter": 0,
|
"label": "Difference Account",
|
||||||
"in_global_search": 0,
|
"options": "Account"
|
||||||
"in_list_view": 1,
|
},
|
||||||
"in_standard_filter": 0,
|
{
|
||||||
"label": "Remark",
|
"fieldname": "difference_amount",
|
||||||
"length": 0,
|
"fieldtype": "Currency",
|
||||||
"no_copy": 0,
|
"label": "Difference Amount",
|
||||||
"permlevel": 0,
|
"print_hide": 1,
|
||||||
"print_hide": 0,
|
"read_only": 1
|
||||||
"print_hide_if_no_value": 0,
|
},
|
||||||
"read_only": 1,
|
{
|
||||||
"remember_last_selected_value": 0,
|
"fieldname": "section_break_10",
|
||||||
"report_hide": 0,
|
"fieldtype": "Section Break"
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"istable": 1,
|
||||||
"hide_heading": 0,
|
"modified": "2019-06-24 00:08:11.150796",
|
||||||
"hide_toolbar": 0,
|
"modified_by": "Administrator",
|
||||||
"idx": 0,
|
"module": "Accounts",
|
||||||
"image_view": 0,
|
"name": "Payment Reconciliation Payment",
|
||||||
"in_create": 0,
|
"owner": "Administrator",
|
||||||
"is_submittable": 0,
|
"permissions": [],
|
||||||
"issingle": 0,
|
"quick_entry": 1,
|
||||||
"istable": 1,
|
"sort_field": "modified",
|
||||||
"max_attachments": 0,
|
"sort_order": "DESC"
|
||||||
"menu_index": 0,
|
|
||||||
"modified": "2019-01-07 16:52:07.567027",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Accounts",
|
|
||||||
"name": "Payment Reconciliation Payment",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [],
|
|
||||||
"quick_entry": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 0,
|
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
@ -8,6 +8,10 @@ frappe.ui.form.on("POS Profile", "onload", function(frm) {
|
|||||||
return { filters: { selling: 1 } };
|
return { filters: { selling: 1 } };
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frm.set_query("tc_name", function() {
|
||||||
|
return { filters: { selling: 1 } };
|
||||||
|
});
|
||||||
|
|
||||||
erpnext.queries.setup_queries(frm, "Warehouse", function() {
|
erpnext.queries.setup_queries(frm, "Warehouse", function() {
|
||||||
return erpnext.queries.warehouse(frm.doc);
|
return erpnext.queries.warehouse(frm.doc);
|
||||||
});
|
});
|
||||||
|
@ -220,7 +220,12 @@ def get_pricing_rule_for_item(args, price_list_rate=0, doc=None):
|
|||||||
|
|
||||||
if args.transaction_type=="selling":
|
if args.transaction_type=="selling":
|
||||||
if args.customer and not (args.customer_group and args.territory):
|
if args.customer and not (args.customer_group and args.territory):
|
||||||
customer = frappe.get_cached_value("Customer", args.customer, ["customer_group", "territory"])
|
|
||||||
|
if args.quotation_to and args.quotation_to != 'Customer':
|
||||||
|
customer = frappe._dict()
|
||||||
|
else:
|
||||||
|
customer = frappe.get_cached_value("Customer", args.customer, ["customer_group", "territory"])
|
||||||
|
|
||||||
if customer:
|
if customer:
|
||||||
args.customer_group, args.territory = customer
|
args.customer_group, args.territory = customer
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
|||||||
can_change_release_date: function(date) {
|
can_change_release_date: function(date) {
|
||||||
const diff = frappe.datetime.get_diff(date, frappe.datetime.nowdate());
|
const diff = frappe.datetime.get_diff(date, frappe.datetime.nowdate());
|
||||||
if (diff < 0) {
|
if (diff < 0) {
|
||||||
frappe.throw('New release date should be in the future');
|
frappe.throw(__('New release date should be in the future'));
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
@ -523,8 +523,13 @@ frappe.ui.form.on("Purchase Invoice", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onload: function(frm) {
|
onload: function(frm) {
|
||||||
if(frm.doc.__onload && !frm.doc.__onload.supplier_tds) {
|
if(frm.doc.__onload) {
|
||||||
me.frm.set_df_property("apply_tds", "read_only", 1);
|
if(frm.doc.supplier) {
|
||||||
|
frm.doc.apply_tds = frm.doc.__onload.supplier_tds ? 1 : 0;
|
||||||
|
}
|
||||||
|
if(!frm.doc.__onload.supplier_tds) {
|
||||||
|
frm.set_df_property("apply_tds", "read_only", 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
erpnext.queries.setup_queries(frm, "Warehouse", function() {
|
erpnext.queries.setup_queries(frm, "Warehouse", function() {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -105,7 +105,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
def validate_release_date(self):
|
def validate_release_date(self):
|
||||||
if self.release_date and getdate(nowdate()) >= getdate(self.release_date):
|
if self.release_date and getdate(nowdate()) >= getdate(self.release_date):
|
||||||
frappe.msgprint('Release date must be in the future', raise_exception=True)
|
frappe.throw(_('Release date must be in the future'))
|
||||||
|
|
||||||
def validate_cash(self):
|
def validate_cash(self):
|
||||||
if not self.cash_bank_account and flt(self.paid_amount):
|
if not self.cash_bank_account and flt(self.paid_amount):
|
||||||
@ -337,7 +337,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
if not self.is_return:
|
if not self.is_return:
|
||||||
self.update_against_document_in_jv()
|
self.update_against_document_in_jv()
|
||||||
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
|
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
|
||||||
self.update_billing_status_in_pr()
|
|
||||||
|
self.update_billing_status_in_pr()
|
||||||
|
|
||||||
# Updating stock ledger should always be called after updating prevdoc status,
|
# Updating stock ledger should always be called after updating prevdoc status,
|
||||||
# because updating ordered qty in bin depends upon updated ordered qty in PO
|
# because updating ordered qty in bin depends upon updated ordered qty in PO
|
||||||
@ -416,6 +417,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
"account": self.credit_to,
|
"account": self.credit_to,
|
||||||
"party_type": "Supplier",
|
"party_type": "Supplier",
|
||||||
"party": self.supplier,
|
"party": self.supplier,
|
||||||
|
"due_date": self.due_date,
|
||||||
"against": self.against_expense_account,
|
"against": self.against_expense_account,
|
||||||
"credit": grand_total_in_company_currency,
|
"credit": grand_total_in_company_currency,
|
||||||
"credit_in_account_currency": grand_total_in_company_currency \
|
"credit_in_account_currency": grand_total_in_company_currency \
|
||||||
@ -484,9 +486,13 @@ class PurchaseInvoice(BuyingController):
|
|||||||
"credit": flt(item.rm_supp_cost)
|
"credit": flt(item.rm_supp_cost)
|
||||||
}, warehouse_account[self.supplier_warehouse]["account_currency"], item=item))
|
}, warehouse_account[self.supplier_warehouse]["account_currency"], item=item))
|
||||||
elif not item.is_fixed_asset or (item.is_fixed_asset and is_cwip_accounting_disabled()):
|
elif not item.is_fixed_asset or (item.is_fixed_asset and is_cwip_accounting_disabled()):
|
||||||
|
|
||||||
|
expense_account = (item.expense_account
|
||||||
|
if (not item.enable_deferred_expense or self.is_return) else item.deferred_expense_account)
|
||||||
|
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": item.expense_account if not item.enable_deferred_expense else item.deferred_expense_account,
|
"account": expense_account,
|
||||||
"against": self.supplier,
|
"against": self.supplier,
|
||||||
"debit": flt(item.base_net_amount, item.precision("base_net_amount")),
|
"debit": flt(item.base_net_amount, item.precision("base_net_amount")),
|
||||||
"debit_in_account_currency": (flt(item.base_net_amount,
|
"debit_in_account_currency": (flt(item.base_net_amount,
|
||||||
@ -769,7 +775,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
if not self.is_return:
|
if not self.is_return:
|
||||||
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
|
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
|
||||||
self.update_billing_status_in_pr()
|
|
||||||
|
self.update_billing_status_in_pr()
|
||||||
|
|
||||||
# Updating stock ledger should always be called after updating prevdoc status,
|
# Updating stock ledger should always be called after updating prevdoc status,
|
||||||
# because updating ordered qty in bin depends upon updated ordered qty in PO
|
# because updating ordered qty in bin depends upon updated ordered qty in PO
|
||||||
@ -787,9 +794,8 @@ class PurchaseInvoice(BuyingController):
|
|||||||
for d in self.items:
|
for d in self.items:
|
||||||
if d.project and d.project not in project_list:
|
if d.project and d.project not in project_list:
|
||||||
project = frappe.get_doc("Project", d.project)
|
project = frappe.get_doc("Project", d.project)
|
||||||
project.flags.dont_sync_tasks = True
|
|
||||||
project.update_purchase_costing()
|
project.update_purchase_costing()
|
||||||
project.save()
|
project.db_update()
|
||||||
project_list.append(d.project)
|
project_list.append(d.project)
|
||||||
|
|
||||||
def validate_supplier_invoice(self):
|
def validate_supplier_invoice(self):
|
||||||
|
@ -6,8 +6,8 @@ frappe.listview_settings['Purchase Invoice'] = {
|
|||||||
add_fields: ["supplier", "supplier_name", "base_grand_total", "outstanding_amount", "due_date", "company",
|
add_fields: ["supplier", "supplier_name", "base_grand_total", "outstanding_amount", "due_date", "company",
|
||||||
"currency", "is_return", "release_date", "on_hold"],
|
"currency", "is_return", "release_date", "on_hold"],
|
||||||
get_indicator: function(doc) {
|
get_indicator: function(doc) {
|
||||||
if(cint(doc.is_return)==1) {
|
if(flt(doc.outstanding_amount) < 0 && doc.docstatus == 1) {
|
||||||
return [__("Return"), "darkgrey", "is_return,=,Yes"];
|
return [__("Debit Note Issued"), "darkgrey", "outstanding_amount,<,0"]
|
||||||
} else if(flt(doc.outstanding_amount) > 0 && doc.docstatus==1) {
|
} else if(flt(doc.outstanding_amount) > 0 && doc.docstatus==1) {
|
||||||
if(cint(doc.on_hold) && !doc.release_date) {
|
if(cint(doc.on_hold) && !doc.release_date) {
|
||||||
return [__("On Hold"), "darkgrey"];
|
return [__("On Hold"), "darkgrey"];
|
||||||
@ -18,9 +18,9 @@ frappe.listview_settings['Purchase Invoice'] = {
|
|||||||
} else {
|
} else {
|
||||||
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due,>=,Today"];
|
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due,>=,Today"];
|
||||||
}
|
}
|
||||||
} else if(flt(doc.outstanding_amount) < 0 && doc.docstatus == 1) {
|
} else if(cint(doc.is_return)) {
|
||||||
return [__("Debit Note Issued"), "darkgrey", "outstanding_amount,<,0"]
|
return [__("Return"), "darkgrey", "is_return,=,Yes"];
|
||||||
}else if(flt(doc.outstanding_amount)==0 && doc.docstatus==1) {
|
} else if(flt(doc.outstanding_amount)==0 && doc.docstatus==1) {
|
||||||
return [__("Paid"), "green", "outstanding_amount,=,0"];
|
return [__("Paid"), "green", "outstanding_amount,=,0"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
38
erpnext/accounts/doctype/sales_invoice/regional/india.js
Normal file
38
erpnext/accounts/doctype/sales_invoice/regional/india.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
frappe.ui.form.on("Sales Invoice", {
|
||||||
|
setup: function(frm) {
|
||||||
|
frm.set_query('transporter', function() {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
'is_transporter': 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
frm.set_query('driver', function(doc) {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
'transporter': doc.transporter
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
refresh: function(frm) {
|
||||||
|
if(frm.doc.docstatus == 1 && !frm.is_dirty()
|
||||||
|
&& !frm.doc.is_return && !frm.doc.ewaybill) {
|
||||||
|
|
||||||
|
frm.add_custom_button('e-Way Bill JSON', () => {
|
||||||
|
var w = window.open(
|
||||||
|
frappe.urllib.get_full_url(
|
||||||
|
"/api/method/erpnext.regional.india.utils.generate_ewb_json?"
|
||||||
|
+ "dt=" + encodeURIComponent(frm.doc.doctype)
|
||||||
|
+ "&dn=" + encodeURIComponent(frm.doc.name)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (!w) {
|
||||||
|
frappe.msgprint(__("Please enable pop-ups")); return;
|
||||||
|
}
|
||||||
|
}, __("Make"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,33 @@
|
|||||||
|
var globalOnload = frappe.listview_settings['Sales Invoice'].onload;
|
||||||
|
frappe.listview_settings['Sales Invoice'].onload = function (doclist) {
|
||||||
|
|
||||||
|
// Provision in case onload event is added to sales_invoice.js in future
|
||||||
|
if (globalOnload) {
|
||||||
|
globalOnload(doclist);
|
||||||
|
}
|
||||||
|
|
||||||
|
const action = () => {
|
||||||
|
const selected_docs = doclist.get_checked_items();
|
||||||
|
const docnames = doclist.get_checked_items(true);
|
||||||
|
|
||||||
|
for (let doc of selected_docs) {
|
||||||
|
if (doc.docstatus !== 1) {
|
||||||
|
frappe.throw(__("e-Way Bill JSON can only be generated from a submitted document"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var w = window.open(
|
||||||
|
frappe.urllib.get_full_url(
|
||||||
|
"/api/method/erpnext.regional.india.utils.generate_ewb_json?"
|
||||||
|
+ "dt=" + encodeURIComponent(doclist.doctype)
|
||||||
|
+ "&dn=" + encodeURIComponent(docnames)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (!w) {
|
||||||
|
frappe.msgprint(__("Please enable pop-ups")); return;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
doclist.page.add_actions_menu_item(__('Generate e-Way Bill JSON'), action, false);
|
||||||
|
};
|
File diff suppressed because it is too large
Load Diff
@ -54,8 +54,8 @@ class SalesInvoice(SellingController):
|
|||||||
|
|
||||||
def set_indicator(self):
|
def set_indicator(self):
|
||||||
"""Set indicator for portal"""
|
"""Set indicator for portal"""
|
||||||
if cint(self.is_return) == 1:
|
if self.outstanding_amount < 0:
|
||||||
self.indicator_title = _("Return")
|
self.indicator_title = _("Credit Note Issued")
|
||||||
self.indicator_color = "darkgrey"
|
self.indicator_color = "darkgrey"
|
||||||
elif self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()):
|
elif self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()):
|
||||||
self.indicator_color = "orange"
|
self.indicator_color = "orange"
|
||||||
@ -63,8 +63,8 @@ class SalesInvoice(SellingController):
|
|||||||
elif self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()):
|
elif self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()):
|
||||||
self.indicator_color = "red"
|
self.indicator_color = "red"
|
||||||
self.indicator_title = _("Overdue")
|
self.indicator_title = _("Overdue")
|
||||||
elif self.outstanding_amount < 0:
|
elif cint(self.is_return) == 1:
|
||||||
self.indicator_title = _("Credit Note Issued")
|
self.indicator_title = _("Return")
|
||||||
self.indicator_color = "darkgrey"
|
self.indicator_color = "darkgrey"
|
||||||
else:
|
else:
|
||||||
self.indicator_color = "green"
|
self.indicator_color = "green"
|
||||||
@ -508,8 +508,8 @@ class SalesInvoice(SellingController):
|
|||||||
if frappe.db.get_single_value('Selling Settings', dic[i][0]) == 'Yes':
|
if frappe.db.get_single_value('Selling Settings', dic[i][0]) == 'Yes':
|
||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
is_stock_item = frappe.get_cached_value('Item', d.item_code, 'is_stock_item')
|
is_stock_item = frappe.get_cached_value('Item', d.item_code, 'is_stock_item')
|
||||||
if d.item_code and is_stock_item == 1\
|
if (d.item_code and is_stock_item == 1\
|
||||||
and not d.get(i.lower().replace(' ','_')) and not self.get(dic[i][1]):
|
and not d.get(i.lower().replace(' ','_')) and not self.get(dic[i][1])):
|
||||||
msgprint(_("{0} is mandatory for Item {1}").format(i,d.item_code), raise_exception=1)
|
msgprint(_("{0} is mandatory for Item {1}").format(i,d.item_code), raise_exception=1)
|
||||||
|
|
||||||
|
|
||||||
@ -734,6 +734,7 @@ class SalesInvoice(SellingController):
|
|||||||
"account": self.debit_to,
|
"account": self.debit_to,
|
||||||
"party_type": "Customer",
|
"party_type": "Customer",
|
||||||
"party": self.customer,
|
"party": self.customer,
|
||||||
|
"due_date": self.due_date,
|
||||||
"against": self.against_income_account,
|
"against": self.against_income_account,
|
||||||
"debit": grand_total_in_company_currency,
|
"debit": grand_total_in_company_currency,
|
||||||
"debit_in_account_currency": grand_total_in_company_currency \
|
"debit_in_account_currency": grand_total_in_company_currency \
|
||||||
@ -768,7 +769,14 @@ class SalesInvoice(SellingController):
|
|||||||
if item.is_fixed_asset:
|
if item.is_fixed_asset:
|
||||||
asset = frappe.get_doc("Asset", item.asset)
|
asset = frappe.get_doc("Asset", item.asset)
|
||||||
|
|
||||||
fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset, item.base_net_amount)
|
if (len(asset.finance_books) > 1 and not item.finance_book
|
||||||
|
and asset.finance_books[0].finance_book):
|
||||||
|
frappe.throw(_("Select finance book for the item {0} at row {1}")
|
||||||
|
.format(item.item_code, item.idx))
|
||||||
|
|
||||||
|
fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset,
|
||||||
|
item.base_net_amount, item.finance_book)
|
||||||
|
|
||||||
for gle in fixed_asset_gl_entries:
|
for gle in fixed_asset_gl_entries:
|
||||||
gle["against"] = self.customer
|
gle["against"] = self.customer
|
||||||
gl_entries.append(self.get_gl_dict(gle))
|
gl_entries.append(self.get_gl_dict(gle))
|
||||||
@ -776,10 +784,13 @@ class SalesInvoice(SellingController):
|
|||||||
asset.db_set("disposal_date", self.posting_date)
|
asset.db_set("disposal_date", self.posting_date)
|
||||||
asset.set_status("Sold" if self.docstatus==1 else None)
|
asset.set_status("Sold" if self.docstatus==1 else None)
|
||||||
else:
|
else:
|
||||||
account_currency = get_account_currency(item.income_account)
|
income_account = (item.income_account
|
||||||
|
if (not item.enable_deferred_revenue or self.is_return) else item.deferred_revenue_account)
|
||||||
|
|
||||||
|
account_currency = get_account_currency(income_account)
|
||||||
gl_entries.append(
|
gl_entries.append(
|
||||||
self.get_gl_dict({
|
self.get_gl_dict({
|
||||||
"account": item.income_account if not item.enable_deferred_revenue else item.deferred_revenue_account,
|
"account": income_account,
|
||||||
"against": self.customer,
|
"against": self.customer,
|
||||||
"credit": flt(item.base_net_amount, item.precision("base_net_amount")),
|
"credit": flt(item.base_net_amount, item.precision("base_net_amount")),
|
||||||
"credit_in_account_currency": (flt(item.base_net_amount, item.precision("base_net_amount"))
|
"credit_in_account_currency": (flt(item.base_net_amount, item.precision("base_net_amount"))
|
||||||
@ -1022,9 +1033,8 @@ class SalesInvoice(SellingController):
|
|||||||
def update_project(self):
|
def update_project(self):
|
||||||
if self.project:
|
if self.project:
|
||||||
project = frappe.get_doc("Project", self.project)
|
project = frappe.get_doc("Project", self.project)
|
||||||
project.flags.dont_sync_tasks = True
|
|
||||||
project.update_billed_amount()
|
project.update_billed_amount()
|
||||||
project.save()
|
project.db_update()
|
||||||
|
|
||||||
|
|
||||||
def verify_payment_amount_is_positive(self):
|
def verify_payment_amount_is_positive(self):
|
||||||
|
@ -6,16 +6,16 @@ frappe.listview_settings['Sales Invoice'] = {
|
|||||||
add_fields: ["customer", "customer_name", "base_grand_total", "outstanding_amount", "due_date", "company",
|
add_fields: ["customer", "customer_name", "base_grand_total", "outstanding_amount", "due_date", "company",
|
||||||
"currency", "is_return"],
|
"currency", "is_return"],
|
||||||
get_indicator: function(doc) {
|
get_indicator: function(doc) {
|
||||||
if(cint(doc.is_return)==1) {
|
if(flt(doc.outstanding_amount) < 0) {
|
||||||
return [__("Return"), "darkgrey", "is_return,=,Yes"];
|
|
||||||
} else if(flt(doc.outstanding_amount)==0) {
|
|
||||||
return [__("Paid"), "green", "outstanding_amount,=,0"]
|
|
||||||
} else if(flt(doc.outstanding_amount) < 0) {
|
|
||||||
return [__("Credit Note Issued"), "darkgrey", "outstanding_amount,<,0"]
|
return [__("Credit Note Issued"), "darkgrey", "outstanding_amount,<,0"]
|
||||||
}else if (flt(doc.outstanding_amount) > 0 && doc.due_date >= frappe.datetime.get_today()) {
|
} else if (flt(doc.outstanding_amount) > 0 && doc.due_date >= frappe.datetime.get_today()) {
|
||||||
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due_date,>,Today"]
|
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due_date,>,Today"]
|
||||||
} else if (flt(doc.outstanding_amount) > 0 && doc.due_date < frappe.datetime.get_today()) {
|
} else if (flt(doc.outstanding_amount) > 0 && doc.due_date < frappe.datetime.get_today()) {
|
||||||
return [__("Overdue"), "red", "outstanding_amount,>,0|due_date,<=,Today"]
|
return [__("Overdue"), "red", "outstanding_amount,>,0|due_date,<=,Today"]
|
||||||
|
} else if(cint(doc.is_return)) {
|
||||||
|
return [__("Return"), "darkgrey", "is_return,=,Yes"];
|
||||||
|
} else if(flt(doc.outstanding_amount)==0) {
|
||||||
|
return [__("Paid"), "green", "outstanding_amount,=,0"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
right_column: "grand_total"
|
right_column: "grand_total"
|
||||||
|
@ -19,6 +19,8 @@ from erpnext.controllers.taxes_and_totals import get_itemised_tax_breakup_data
|
|||||||
from erpnext.stock.doctype.item.test_item import create_item
|
from erpnext.stock.doctype.item.test_item import create_item
|
||||||
from six import iteritems
|
from six import iteritems
|
||||||
from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction
|
from erpnext.accounts.doctype.sales_invoice.sales_invoice import make_inter_company_transaction
|
||||||
|
from erpnext.regional.india.utils import get_ewb_data
|
||||||
|
|
||||||
class TestSalesInvoice(unittest.TestCase):
|
class TestSalesInvoice(unittest.TestCase):
|
||||||
def make(self):
|
def make(self):
|
||||||
w = frappe.copy_doc(test_records[0])
|
w = frappe.copy_doc(test_records[0])
|
||||||
@ -1421,7 +1423,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
"included_in_print_rate": 1
|
"included_in_print_rate": 1
|
||||||
})
|
})
|
||||||
si.save()
|
si.save()
|
||||||
|
si.submit()
|
||||||
self.assertEqual(si.net_total, 19453.13)
|
self.assertEqual(si.net_total, 19453.13)
|
||||||
self.assertEqual(si.grand_total, 24900)
|
self.assertEqual(si.grand_total, 24900)
|
||||||
self.assertEqual(si.total_taxes_and_charges, 5446.88)
|
self.assertEqual(si.total_taxes_and_charges, 5446.88)
|
||||||
@ -1443,6 +1445,50 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||||
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||||
|
|
||||||
|
def test_rounding_adjustment_2(self):
|
||||||
|
si = create_sales_invoice(rate=400, do_not_save=True)
|
||||||
|
for rate in [400, 600, 100]:
|
||||||
|
si.append("items", {
|
||||||
|
"item_code": "_Test Item",
|
||||||
|
"gst_hsn_code": "999800",
|
||||||
|
"warehouse": "_Test Warehouse - _TC",
|
||||||
|
"qty": 1,
|
||||||
|
"rate": rate,
|
||||||
|
"income_account": "Sales - _TC",
|
||||||
|
"cost_center": "_Test Cost Center - _TC"
|
||||||
|
})
|
||||||
|
for tax_account in ["_Test Account VAT - _TC", "_Test Account Service Tax - _TC"]:
|
||||||
|
si.append("taxes", {
|
||||||
|
"charge_type": "On Net Total",
|
||||||
|
"account_head": tax_account,
|
||||||
|
"description": tax_account,
|
||||||
|
"rate": 9,
|
||||||
|
"cost_center": "_Test Cost Center - _TC",
|
||||||
|
"included_in_print_rate": 1
|
||||||
|
})
|
||||||
|
si.save()
|
||||||
|
si.submit()
|
||||||
|
self.assertEqual(si.net_total, 1271.19)
|
||||||
|
self.assertEqual(si.grand_total, 1500)
|
||||||
|
self.assertEqual(si.total_taxes_and_charges, 228.82)
|
||||||
|
self.assertEqual(si.rounding_adjustment, -0.01)
|
||||||
|
|
||||||
|
expected_values = dict((d[0], d) for d in [
|
||||||
|
[si.debit_to, 1500, 0.0],
|
||||||
|
["_Test Account Service Tax - _TC", 0.0, 114.41],
|
||||||
|
["_Test Account VAT - _TC", 0.0, 114.41],
|
||||||
|
["Sales - _TC", 0.0, 1271.18]
|
||||||
|
])
|
||||||
|
|
||||||
|
gl_entries = frappe.db.sql("""select account, debit, credit
|
||||||
|
from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
|
||||||
|
order by account asc""", si.name, as_dict=1)
|
||||||
|
|
||||||
|
for gle in gl_entries:
|
||||||
|
self.assertEqual(expected_values[gle.account][0], gle.account)
|
||||||
|
self.assertEqual(expected_values[gle.account][1], gle.debit)
|
||||||
|
self.assertEqual(expected_values[gle.account][2], gle.credit)
|
||||||
|
|
||||||
def test_sales_invoice_with_shipping_rule(self):
|
def test_sales_invoice_with_shipping_rule(self):
|
||||||
from erpnext.accounts.doctype.shipping_rule.test_shipping_rule \
|
from erpnext.accounts.doctype.shipping_rule.test_shipping_rule \
|
||||||
import create_shipping_rule
|
import create_shipping_rule
|
||||||
@ -1681,6 +1727,111 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
self.assertEqual(target_doc.company, "_Test Company 1")
|
self.assertEqual(target_doc.company, "_Test Company 1")
|
||||||
self.assertEqual(target_doc.supplier, "_Test Internal Supplier")
|
self.assertEqual(target_doc.supplier, "_Test Internal Supplier")
|
||||||
|
|
||||||
|
def test_eway_bill_json(self):
|
||||||
|
if not frappe.db.exists('Address', '_Test Address for Eway bill-Billing'):
|
||||||
|
address = frappe.get_doc({
|
||||||
|
"address_line1": "_Test Address Line 1",
|
||||||
|
"address_title": "_Test Address for Eway bill",
|
||||||
|
"address_type": "Billing",
|
||||||
|
"city": "_Test City",
|
||||||
|
"state": "Test State",
|
||||||
|
"country": "India",
|
||||||
|
"doctype": "Address",
|
||||||
|
"is_primary_address": 1,
|
||||||
|
"phone": "+91 0000000000",
|
||||||
|
"gstin": "27AAECE4835E1ZR",
|
||||||
|
"gst_state": "Maharashtra",
|
||||||
|
"gst_state_number": "27",
|
||||||
|
"pincode": "401108"
|
||||||
|
}).insert()
|
||||||
|
|
||||||
|
address.append("links", {
|
||||||
|
"link_doctype": "Company",
|
||||||
|
"link_name": "_Test Company"
|
||||||
|
})
|
||||||
|
|
||||||
|
address.save()
|
||||||
|
|
||||||
|
if not frappe.db.exists('Address', '_Test Customer-Address for Eway bill-Shipping'):
|
||||||
|
address = frappe.get_doc({
|
||||||
|
"address_line1": "_Test Address Line 1",
|
||||||
|
"address_title": "_Test Customer-Address for Eway bill",
|
||||||
|
"address_type": "Shipping",
|
||||||
|
"city": "_Test City",
|
||||||
|
"state": "Test State",
|
||||||
|
"country": "India",
|
||||||
|
"doctype": "Address",
|
||||||
|
"is_primary_address": 1,
|
||||||
|
"phone": "+91 0000000000",
|
||||||
|
"gst_state": "Maharashtra",
|
||||||
|
"gst_state_number": "27",
|
||||||
|
"pincode": "410038"
|
||||||
|
}).insert()
|
||||||
|
|
||||||
|
address.append("links", {
|
||||||
|
"link_doctype": "Customer",
|
||||||
|
"link_name": "_Test Customer"
|
||||||
|
})
|
||||||
|
|
||||||
|
address.save()
|
||||||
|
|
||||||
|
gst_settings = frappe.get_doc("GST Settings")
|
||||||
|
|
||||||
|
gst_account = frappe.get_all(
|
||||||
|
"GST Account",
|
||||||
|
fields=["cgst_account", "sgst_account", "igst_account"],
|
||||||
|
filters = {"company": "_Test Company"})
|
||||||
|
|
||||||
|
if not gst_account:
|
||||||
|
gst_settings.append("gst_accounts", {
|
||||||
|
"company": "_Test Company",
|
||||||
|
"cgst_account": "CGST - _TC",
|
||||||
|
"sgst_account": "SGST - _TC",
|
||||||
|
"igst_account": "IGST - _TC",
|
||||||
|
})
|
||||||
|
|
||||||
|
gst_settings.save()
|
||||||
|
|
||||||
|
si = create_sales_invoice(do_not_save =1, rate = '60000')
|
||||||
|
|
||||||
|
si.distance = 2000
|
||||||
|
si.company_address = "_Test Address for Eway bill-Billing"
|
||||||
|
si.customer_address = "_Test Customer-Address for Eway bill-Shipping"
|
||||||
|
si.vehicle_no = "KA12KA1234"
|
||||||
|
si.gst_category = "Registered Regular"
|
||||||
|
|
||||||
|
si.append("taxes", {
|
||||||
|
"charge_type": "On Net Total",
|
||||||
|
"account_head": "CGST - _TC",
|
||||||
|
"cost_center": "Main - _TC",
|
||||||
|
"description": "CGST @ 9.0",
|
||||||
|
"rate": 9
|
||||||
|
})
|
||||||
|
|
||||||
|
si.append("taxes", {
|
||||||
|
"charge_type": "On Net Total",
|
||||||
|
"account_head": "SGST - _TC",
|
||||||
|
"cost_center": "Main - _TC",
|
||||||
|
"description": "SGST @ 9.0",
|
||||||
|
"rate": 9
|
||||||
|
})
|
||||||
|
|
||||||
|
si.submit()
|
||||||
|
|
||||||
|
data = get_ewb_data("Sales Invoice", si.name)
|
||||||
|
|
||||||
|
self.assertEqual(data['version'], '1.0.1118')
|
||||||
|
self.assertEqual(data['billLists'][0]['fromGstin'], '27AAECE4835E1ZR')
|
||||||
|
self.assertEqual(data['billLists'][0]['fromTrdName'], '_Test Company')
|
||||||
|
self.assertEqual(data['billLists'][0]['toTrdName'], '_Test Customer')
|
||||||
|
self.assertEqual(data['billLists'][0]['vehicleType'], 'R')
|
||||||
|
self.assertEqual(data['billLists'][0]['totalValue'], 60000)
|
||||||
|
self.assertEqual(data['billLists'][0]['cgstValue'], 5400)
|
||||||
|
self.assertEqual(data['billLists'][0]['sgstValue'], 5400)
|
||||||
|
self.assertEqual(data['billLists'][0]['vehicleNo'], 'KA12KA1234')
|
||||||
|
self.assertEqual(data['billLists'][0]['itemList'][0]['taxableAmount'], 60000)
|
||||||
|
|
||||||
|
|
||||||
def create_sales_invoice(**args):
|
def create_sales_invoice(**args):
|
||||||
si = frappe.new_doc("Sales Invoice")
|
si = frappe.new_doc("Sales Invoice")
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
"income_account",
|
"income_account",
|
||||||
"is_fixed_asset",
|
"is_fixed_asset",
|
||||||
"asset",
|
"asset",
|
||||||
|
"finance_book",
|
||||||
"col_break4",
|
"col_break4",
|
||||||
"expense_account",
|
"expense_account",
|
||||||
"deferred_revenue",
|
"deferred_revenue",
|
||||||
@ -770,11 +771,18 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "dimension_col_break",
|
"fieldname": "dimension_col_break",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "asset",
|
||||||
|
"fieldname": "finance_book",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Finance Book",
|
||||||
|
"options": "Finance Book"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2019-05-25 22:05:59.971263",
|
"modified": "2019-06-28 17:30:12.156086",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Invoice Item",
|
"name": "Sales Invoice Item",
|
||||||
|
@ -295,7 +295,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2019-03-06 15:58:37.839241",
|
"modified": "2019-03-19 14:54:56.524556",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Invoice Payment",
|
"name": "Sales Invoice Payment",
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe import _
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.utilities.product import get_price
|
from erpnext.utilities.product import get_price
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ class SubscriptionPlan(Document):
|
|||||||
|
|
||||||
def validate_interval_count(self):
|
def validate_interval_count(self):
|
||||||
if self.billing_interval_count < 1:
|
if self.billing_interval_count < 1:
|
||||||
frappe.throw('Billing Interval Count cannot be less than 1')
|
frappe.throw(_('Billing Interval Count cannot be less than 1'))
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_plan_rate(plan, quantity=1, customer=None):
|
def get_plan_rate(plan, quantity=1, customer=None):
|
||||||
@ -26,7 +27,7 @@ def get_plan_rate(plan, quantity=1, customer=None):
|
|||||||
customer_group = frappe.db.get_value("Customer", customer, "customer_group")
|
customer_group = frappe.db.get_value("Customer", customer, "customer_group")
|
||||||
else:
|
else:
|
||||||
customer_group = None
|
customer_group = None
|
||||||
|
|
||||||
price = get_price(item_code=plan.item, price_list=plan.price_list, customer_group=customer_group, company=None, qty=quantity)
|
price = get_price(item_code=plan.item, price_list=plan.price_list, customer_group=customer_group, company=None, qty=quantity)
|
||||||
if not price:
|
if not price:
|
||||||
return 0
|
return 0
|
||||||
|
@ -145,9 +145,9 @@ def round_off_debit_credit(gl_map):
|
|||||||
.format(gl_map[0].voucher_type, gl_map[0].voucher_no, debit_credit_diff))
|
.format(gl_map[0].voucher_type, gl_map[0].voucher_no, debit_credit_diff))
|
||||||
|
|
||||||
elif abs(debit_credit_diff) >= (1.0 / (10**precision)):
|
elif abs(debit_credit_diff) >= (1.0 / (10**precision)):
|
||||||
make_round_off_gle(gl_map, debit_credit_diff)
|
make_round_off_gle(gl_map, debit_credit_diff, precision)
|
||||||
|
|
||||||
def make_round_off_gle(gl_map, debit_credit_diff):
|
def make_round_off_gle(gl_map, debit_credit_diff, precision):
|
||||||
round_off_account, round_off_cost_center = get_round_off_account_and_cost_center(gl_map[0].company)
|
round_off_account, round_off_cost_center = get_round_off_account_and_cost_center(gl_map[0].company)
|
||||||
round_off_account_exists = False
|
round_off_account_exists = False
|
||||||
round_off_gle = frappe._dict()
|
round_off_gle = frappe._dict()
|
||||||
@ -160,6 +160,10 @@ def make_round_off_gle(gl_map, debit_credit_diff):
|
|||||||
debit_credit_diff += flt(d.credit_in_account_currency)
|
debit_credit_diff += flt(d.credit_in_account_currency)
|
||||||
round_off_account_exists = True
|
round_off_account_exists = True
|
||||||
|
|
||||||
|
if round_off_account_exists and abs(debit_credit_diff) <= (1.0 / (10**precision)):
|
||||||
|
gl_map.remove(round_off_gle)
|
||||||
|
return
|
||||||
|
|
||||||
if not round_off_gle:
|
if not round_off_gle:
|
||||||
for k in ["voucher_type", "voucher_no", "company",
|
for k in ["voucher_type", "voucher_no", "company",
|
||||||
"posting_date", "remarks", "is_opening"]:
|
"posting_date", "remarks", "is_opening"]:
|
||||||
|
578
erpnext/accounts/page/bank_reconciliation/bank_reconciliation.js
Normal file
578
erpnext/accounts/page/bank_reconciliation/bank_reconciliation.js
Normal file
@ -0,0 +1,578 @@
|
|||||||
|
frappe.provide("erpnext.accounts");
|
||||||
|
|
||||||
|
frappe.pages['bank-reconciliation'].on_page_load = function(wrapper) {
|
||||||
|
new erpnext.accounts.bankReconciliation(wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
erpnext.accounts.bankReconciliation = class BankReconciliation {
|
||||||
|
constructor(wrapper) {
|
||||||
|
this.page = frappe.ui.make_app_page({
|
||||||
|
parent: wrapper,
|
||||||
|
title: __("Bank Reconciliation"),
|
||||||
|
single_column: true
|
||||||
|
});
|
||||||
|
this.parent = wrapper;
|
||||||
|
this.page = this.parent.page;
|
||||||
|
|
||||||
|
this.check_plaid_status();
|
||||||
|
this.make();
|
||||||
|
}
|
||||||
|
|
||||||
|
make() {
|
||||||
|
const me = this;
|
||||||
|
|
||||||
|
me.$main_section = $(`<div class="reconciliation page-main-content"></div>`).appendTo(me.page.main);
|
||||||
|
const empty_state = __("Upload a bank statement, link or reconcile a bank account")
|
||||||
|
me.$main_section.append(`<div class="flex justify-center align-center text-muted"
|
||||||
|
style="height: 50vh; display: flex;"><h5 class="text-muted">${empty_state}</h5></div>`)
|
||||||
|
|
||||||
|
me.page.add_field({
|
||||||
|
fieldtype: 'Link',
|
||||||
|
label: __('Company'),
|
||||||
|
fieldname: 'company',
|
||||||
|
options: "Company",
|
||||||
|
onchange: function() {
|
||||||
|
if (this.value) {
|
||||||
|
me.company = this.value;
|
||||||
|
} else {
|
||||||
|
me.company = null;
|
||||||
|
me.bank_account = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
me.page.add_field({
|
||||||
|
fieldtype: 'Link',
|
||||||
|
label: __('Bank Account'),
|
||||||
|
fieldname: 'bank_account',
|
||||||
|
options: "Bank Account",
|
||||||
|
get_query: function() {
|
||||||
|
if(!me.company) {
|
||||||
|
frappe.throw(__("Please select company first"));
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
"company": me.company
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onchange: function() {
|
||||||
|
if (this.value) {
|
||||||
|
me.bank_account = this.value;
|
||||||
|
me.add_actions();
|
||||||
|
} else {
|
||||||
|
me.bank_account = null;
|
||||||
|
me.page.hide_actions_menu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
check_plaid_status() {
|
||||||
|
const me = this;
|
||||||
|
frappe.db.get_value("Plaid Settings", "Plaid Settings", "enabled", (r) => {
|
||||||
|
if (r && r.enabled == "1") {
|
||||||
|
me.plaid_status = "active"
|
||||||
|
} else {
|
||||||
|
me.plaid_status = "inactive"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
add_actions() {
|
||||||
|
const me = this;
|
||||||
|
|
||||||
|
me.page.show_menu()
|
||||||
|
|
||||||
|
me.page.add_menu_item(__("Upload a statement"), function() {
|
||||||
|
me.clear_page_content();
|
||||||
|
new erpnext.accounts.bankTransactionUpload(me);
|
||||||
|
}, true)
|
||||||
|
|
||||||
|
if (me.plaid_status==="active") {
|
||||||
|
me.page.add_menu_item(__("Synchronize this account"), function() {
|
||||||
|
me.clear_page_content();
|
||||||
|
new erpnext.accounts.bankTransactionSync(me);
|
||||||
|
}, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
me.page.add_menu_item(__("Reconcile this account"), function() {
|
||||||
|
me.clear_page_content();
|
||||||
|
me.make_reconciliation_tool();
|
||||||
|
}, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_page_content() {
|
||||||
|
const me = this;
|
||||||
|
$(me.page.body).find('.frappe-list').remove();
|
||||||
|
me.$main_section.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
make_reconciliation_tool() {
|
||||||
|
const me = this;
|
||||||
|
frappe.model.with_doctype("Bank Transaction", () => {
|
||||||
|
erpnext.accounts.ReconciliationList = new erpnext.accounts.ReconciliationTool({
|
||||||
|
parent: me.parent,
|
||||||
|
doctype: "Bank Transaction"
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
erpnext.accounts.bankTransactionUpload = class bankTransactionUpload {
|
||||||
|
constructor(parent) {
|
||||||
|
this.parent = parent;
|
||||||
|
this.data = [];
|
||||||
|
|
||||||
|
const assets = [
|
||||||
|
"/assets/frappe/css/frappe-datatable.css",
|
||||||
|
"/assets/frappe/js/lib/clusterize.min.js",
|
||||||
|
"/assets/frappe/js/lib/Sortable.min.js",
|
||||||
|
"/assets/frappe/js/lib/frappe-datatable.js"
|
||||||
|
];
|
||||||
|
|
||||||
|
frappe.require(assets, () => {
|
||||||
|
this.make();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
make() {
|
||||||
|
const me = this;
|
||||||
|
frappe.upload.make({
|
||||||
|
args: {
|
||||||
|
method: 'erpnext.accounts.doctype.bank_transaction.bank_transaction_upload.upload_bank_statement',
|
||||||
|
allow_multiple: 0
|
||||||
|
},
|
||||||
|
no_socketio: true,
|
||||||
|
sample_url: "e.g. http://example.com/somefile.csv",
|
||||||
|
callback: function(attachment, r) {
|
||||||
|
if (!r.exc && r.message) {
|
||||||
|
me.data = r.message;
|
||||||
|
me.setup_transactions_dom();
|
||||||
|
me.create_datatable();
|
||||||
|
me.add_primary_action();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_transactions_dom() {
|
||||||
|
const me = this;
|
||||||
|
me.parent.$main_section.append(`<div class="transactions-table"></div>`)
|
||||||
|
}
|
||||||
|
|
||||||
|
create_datatable() {
|
||||||
|
try {
|
||||||
|
this.datatable = new DataTable('.transactions-table', {
|
||||||
|
columns: this.data.columns,
|
||||||
|
data: this.data.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
let msg = __(`Your file could not be processed by ERPNext.
|
||||||
|
<br>It should be a standard CSV or XLSX file.
|
||||||
|
<br>The headers should be in the first row.`)
|
||||||
|
frappe.throw(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
add_primary_action() {
|
||||||
|
const me = this;
|
||||||
|
me.parent.page.set_primary_action(__("Submit"), function() {
|
||||||
|
me.add_bank_entries()
|
||||||
|
}, null, __("Creating bank entries..."))
|
||||||
|
}
|
||||||
|
|
||||||
|
add_bank_entries() {
|
||||||
|
const me = this;
|
||||||
|
frappe.xcall('erpnext.accounts.doctype.bank_transaction.bank_transaction_upload.create_bank_entries',
|
||||||
|
{columns: this.datatable.datamanager.columns, data: this.datatable.datamanager.data, bank_account: me.parent.bank_account}
|
||||||
|
).then((result) => {
|
||||||
|
let result_title = result.errors == 0 ? __("{0} bank transaction(s) created", [result.success]) : __("{0} bank transaction(s) created and {1} errors", [result.success, result.errors])
|
||||||
|
let result_msg = `
|
||||||
|
<div class="flex justify-center align-center text-muted" style="height: 50vh; display: flex;">
|
||||||
|
<h5 class="text-muted">${result_title}</h5>
|
||||||
|
</div>`
|
||||||
|
me.parent.page.clear_primary_action();
|
||||||
|
me.parent.$main_section.empty();
|
||||||
|
me.parent.$main_section.append(result_msg);
|
||||||
|
if (result.errors == 0) {
|
||||||
|
frappe.show_alert({message:__("All bank transactions have been created"), indicator:'green'});
|
||||||
|
} else {
|
||||||
|
frappe.show_alert({message:__("Please check the error log for details about the import errors"), indicator:'red'});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
erpnext.accounts.bankTransactionSync = class bankTransactionSync {
|
||||||
|
constructor(parent) {
|
||||||
|
this.parent = parent;
|
||||||
|
this.data = [];
|
||||||
|
|
||||||
|
this.init_config()
|
||||||
|
}
|
||||||
|
|
||||||
|
init_config() {
|
||||||
|
const me = this;
|
||||||
|
frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.plaid_configuration')
|
||||||
|
.then(result => {
|
||||||
|
me.plaid_env = result.plaid_env;
|
||||||
|
me.plaid_public_key = result.plaid_public_key;
|
||||||
|
me.client_name = result.client_name;
|
||||||
|
me.sync_transactions()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
sync_transactions() {
|
||||||
|
const me = this;
|
||||||
|
frappe.db.get_value("Bank Account", me.parent.bank_account, "bank", (v) => {
|
||||||
|
frappe.xcall('erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.sync_transactions', {
|
||||||
|
bank: v['bank'],
|
||||||
|
bank_account: me.parent.bank_account,
|
||||||
|
freeze: true
|
||||||
|
})
|
||||||
|
.then((result) => {
|
||||||
|
let result_title = (result.length > 0) ? __("{0} bank transaction(s) created", [result.length]) : __("This bank account is already synchronized")
|
||||||
|
let result_msg = `
|
||||||
|
<div class="flex justify-center align-center text-muted" style="height: 50vh; display: flex;">
|
||||||
|
<h5 class="text-muted">${result_title}</h5>
|
||||||
|
</div>`
|
||||||
|
this.parent.$main_section.append(result_msg)
|
||||||
|
frappe.show_alert({message:__("Bank account '{0}' has been synchronized", [me.parent.bank_account]), indicator:'green'});
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
erpnext.accounts.ReconciliationTool = class ReconciliationTool extends frappe.views.BaseList {
|
||||||
|
constructor(opts) {
|
||||||
|
super(opts);
|
||||||
|
this.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_defaults() {
|
||||||
|
super.setup_defaults();
|
||||||
|
|
||||||
|
this.page_title = __("Bank Reconciliation");
|
||||||
|
this.doctype = 'Bank Transaction';
|
||||||
|
this.fields = ['date', 'description', 'debit', 'credit', 'currency']
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_view() {
|
||||||
|
this.render_header();
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_side_bar() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
make_standard_filters() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
freeze() {
|
||||||
|
this.$result.find('.list-count').html(`<span>${__('Refreshing')}...</span>`);
|
||||||
|
}
|
||||||
|
|
||||||
|
get_args() {
|
||||||
|
const args = super.get_args();
|
||||||
|
|
||||||
|
return Object.assign({}, args, {
|
||||||
|
...args.filters.push(["Bank Transaction", "docstatus", "=", 1],
|
||||||
|
["Bank Transaction", "unallocated_amount", ">", 0])
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
update_data(r) {
|
||||||
|
let data = r.message || [];
|
||||||
|
|
||||||
|
if (this.start === 0) {
|
||||||
|
this.data = data;
|
||||||
|
} else {
|
||||||
|
this.data = this.data.concat(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const me = this;
|
||||||
|
this.$result.find('.list-row-container').remove();
|
||||||
|
$('[data-fieldname="name"]').remove();
|
||||||
|
me.data.map((value) => {
|
||||||
|
const row = $('<div class="list-row-container">').data("data", value).appendTo(me.$result).get(0);
|
||||||
|
new erpnext.accounts.ReconciliationRow(row, value);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render_header() {
|
||||||
|
const me = this;
|
||||||
|
if ($(this.wrapper).find('.transaction-header').length === 0) {
|
||||||
|
me.$result.append(frappe.render_template("bank_transaction_header"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
erpnext.accounts.ReconciliationRow = class ReconciliationRow {
|
||||||
|
constructor(row, data) {
|
||||||
|
this.data = data;
|
||||||
|
this.row = row;
|
||||||
|
this.make();
|
||||||
|
this.bind_events();
|
||||||
|
}
|
||||||
|
|
||||||
|
make() {
|
||||||
|
$(this.row).append(frappe.render_template("bank_transaction_row", this.data))
|
||||||
|
}
|
||||||
|
|
||||||
|
bind_events() {
|
||||||
|
const me = this;
|
||||||
|
$(me.row).on('click', '.clickable-section', function() {
|
||||||
|
me.bank_entry = $(this).attr("data-name");
|
||||||
|
me.show_dialog($(this).attr("data-name"));
|
||||||
|
})
|
||||||
|
|
||||||
|
$(me.row).on('click', '.new-reconciliation', function() {
|
||||||
|
me.bank_entry = $(this).attr("data-name");
|
||||||
|
me.show_dialog($(this).attr("data-name"));
|
||||||
|
})
|
||||||
|
|
||||||
|
$(me.row).on('click', '.new-payment', function() {
|
||||||
|
me.bank_entry = $(this).attr("data-name");
|
||||||
|
me.new_payment();
|
||||||
|
})
|
||||||
|
|
||||||
|
$(me.row).on('click', '.new-invoice', function() {
|
||||||
|
me.bank_entry = $(this).attr("data-name");
|
||||||
|
me.new_invoice();
|
||||||
|
})
|
||||||
|
|
||||||
|
$(me.row).on('click', '.new-expense', function() {
|
||||||
|
me.bank_entry = $(this).attr("data-name");
|
||||||
|
me.new_expense();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
new_payment() {
|
||||||
|
const me = this;
|
||||||
|
const paid_amount = me.data.credit > 0 ? me.data.credit : me.data.debit;
|
||||||
|
const payment_type = me.data.credit > 0 ? "Receive": "Pay";
|
||||||
|
const party_type = me.data.credit > 0 ? "Customer": "Supplier";
|
||||||
|
|
||||||
|
frappe.new_doc("Payment Entry", {"payment_type": payment_type, "paid_amount": paid_amount,
|
||||||
|
"party_type": party_type, "paid_from": me.data.bank_account})
|
||||||
|
}
|
||||||
|
|
||||||
|
new_invoice() {
|
||||||
|
const me = this;
|
||||||
|
const invoice_type = me.data.credit > 0 ? "Sales Invoice" : "Purchase Invoice";
|
||||||
|
|
||||||
|
frappe.new_doc(invoice_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
new_expense() {
|
||||||
|
frappe.new_doc("Expense Claim")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
show_dialog(data) {
|
||||||
|
const me = this;
|
||||||
|
|
||||||
|
frappe.db.get_value("Bank Account", me.data.bank_account, "account", (r) => {
|
||||||
|
me.gl_account = r.account;
|
||||||
|
})
|
||||||
|
|
||||||
|
frappe.xcall('erpnext.accounts.page.bank_reconciliation.bank_reconciliation.get_linked_payments',
|
||||||
|
{bank_transaction: data, freeze:true, freeze_message:__("Finding linked payments")}
|
||||||
|
).then((result) => {
|
||||||
|
me.make_dialog(result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
make_dialog(data) {
|
||||||
|
const me = this;
|
||||||
|
me.selected_payment = null;
|
||||||
|
|
||||||
|
const fields = [
|
||||||
|
{
|
||||||
|
fieldtype: 'Section Break',
|
||||||
|
fieldname: 'section_break_1',
|
||||||
|
label: __('Automatic Reconciliation')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldtype: 'HTML',
|
||||||
|
fieldname: 'payment_proposals'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldtype: 'Section Break',
|
||||||
|
fieldname: 'section_break_2',
|
||||||
|
label: __('Search for a payment')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldtype: 'Link',
|
||||||
|
fieldname: 'payment_doctype',
|
||||||
|
options: 'DocType',
|
||||||
|
label: 'Payment DocType',
|
||||||
|
get_query: () => {
|
||||||
|
return {
|
||||||
|
filters : {
|
||||||
|
"name": ["in", ["Payment Entry", "Journal Entry", "Sales Invoice", "Purchase Invoice", "Expense Claim"]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldtype: 'Column Break',
|
||||||
|
fieldname: 'column_break_1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldtype: 'Dynamic Link',
|
||||||
|
fieldname: 'payment_entry',
|
||||||
|
options: 'payment_doctype',
|
||||||
|
label: 'Payment Document',
|
||||||
|
get_query: () => {
|
||||||
|
let dt = this.dialog.fields_dict.payment_doctype.value;
|
||||||
|
if (dt === "Payment Entry") {
|
||||||
|
return {
|
||||||
|
query: "erpnext.accounts.page.bank_reconciliation.bank_reconciliation.payment_entry_query",
|
||||||
|
filters : {
|
||||||
|
"bank_account": this.data.bank_account,
|
||||||
|
"company": this.data.company
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (dt === "Journal Entry") {
|
||||||
|
return {
|
||||||
|
query: "erpnext.accounts.page.bank_reconciliation.bank_reconciliation.journal_entry_query",
|
||||||
|
filters : {
|
||||||
|
"bank_account": this.data.bank_account,
|
||||||
|
"company": this.data.company
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (dt === "Sales Invoice") {
|
||||||
|
return {
|
||||||
|
query: "erpnext.accounts.page.bank_reconciliation.bank_reconciliation.sales_invoices_query"
|
||||||
|
}
|
||||||
|
} else if (dt === "Purchase Invoice") {
|
||||||
|
return {
|
||||||
|
filters : [
|
||||||
|
["Purchase Invoice", "ifnull(clearance_date, '')", "=", ""],
|
||||||
|
["Purchase Invoice", "docstatus", "=", 1],
|
||||||
|
["Purchase Invoice", "company", "=", this.data.company]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
} else if (dt === "Expense Claim") {
|
||||||
|
return {
|
||||||
|
filters : [
|
||||||
|
["Expense Claim", "ifnull(clearance_date, '')", "=", ""],
|
||||||
|
["Expense Claim", "docstatus", "=", 1],
|
||||||
|
["Expense Claim", "company", "=", this.data.company]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onchange: function() {
|
||||||
|
if (me.selected_payment !== this.value) {
|
||||||
|
me.selected_payment = this.value;
|
||||||
|
me.display_payment_details(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldtype: 'Section Break',
|
||||||
|
fieldname: 'section_break_3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fieldtype: 'HTML',
|
||||||
|
fieldname: 'payment_details'
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
me.dialog = new frappe.ui.Dialog({
|
||||||
|
title: __("Choose a corresponding payment"),
|
||||||
|
fields: fields,
|
||||||
|
size: "large"
|
||||||
|
});
|
||||||
|
|
||||||
|
const proposals_wrapper = me.dialog.fields_dict.payment_proposals.$wrapper;
|
||||||
|
if (data && data.length > 0) {
|
||||||
|
proposals_wrapper.append(frappe.render_template("linked_payment_header"));
|
||||||
|
data.map(value => {
|
||||||
|
proposals_wrapper.append(frappe.render_template("linked_payment_row", value))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const empty_data_msg = __("ERPNext could not find any matching payment entry")
|
||||||
|
proposals_wrapper.append(`<div class="text-center"><h5 class="text-muted">${empty_data_msg}</h5></div>`)
|
||||||
|
}
|
||||||
|
|
||||||
|
$(me.dialog.body).on('click', '.reconciliation-btn', (e) => {
|
||||||
|
const payment_entry = $(e.target).attr('data-name');
|
||||||
|
const payment_doctype = $(e.target).attr('data-doctype');
|
||||||
|
frappe.xcall('erpnext.accounts.page.bank_reconciliation.bank_reconciliation.reconcile',
|
||||||
|
{bank_transaction: me.bank_entry, payment_doctype: payment_doctype, payment_name: payment_entry})
|
||||||
|
.then((result) => {
|
||||||
|
setTimeout(function(){
|
||||||
|
erpnext.accounts.ReconciliationList.refresh();
|
||||||
|
}, 2000);
|
||||||
|
me.dialog.hide();
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
me.dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
display_payment_details(event) {
|
||||||
|
const me = this;
|
||||||
|
if (event.value) {
|
||||||
|
let dt = me.dialog.fields_dict.payment_doctype.value;
|
||||||
|
me.dialog.fields_dict['payment_details'].$wrapper.empty();
|
||||||
|
frappe.db.get_doc(dt, event.value)
|
||||||
|
.then(doc => {
|
||||||
|
let displayed_docs = []
|
||||||
|
if (dt === "Payment Entry") {
|
||||||
|
payment.currency = doc.payment_type == "Receive" ? doc.paid_to_account_currency : doc.paid_from_account_currency;
|
||||||
|
payment.doctype = dt
|
||||||
|
displayed_docs.push(payment);
|
||||||
|
} else if (dt === "Journal Entry") {
|
||||||
|
doc.accounts.forEach(payment => {
|
||||||
|
if (payment.account === me.gl_account) {
|
||||||
|
payment.doctype = dt;
|
||||||
|
payment.posting_date = doc.posting_date;
|
||||||
|
payment.party = doc.pay_to_recd_from;
|
||||||
|
payment.reference_no = doc.cheque_no;
|
||||||
|
payment.reference_date = doc.cheque_date;
|
||||||
|
payment.currency = payment.account_currency;
|
||||||
|
payment.paid_amount = payment.credit > 0 ? payment.credit : payment.debit;
|
||||||
|
payment.name = doc.name;
|
||||||
|
displayed_docs.push(payment);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (dt === "Sales Invoice") {
|
||||||
|
doc.payments.forEach(payment => {
|
||||||
|
if (payment.clearance_date === null || payment.clearance_date === "") {
|
||||||
|
payment.doctype = dt;
|
||||||
|
payment.posting_date = doc.posting_date;
|
||||||
|
payment.party = doc.customer;
|
||||||
|
payment.reference_no = doc.remarks;
|
||||||
|
payment.currency = doc.currency;
|
||||||
|
payment.paid_amount = payment.amount;
|
||||||
|
payment.name = doc.name;
|
||||||
|
displayed_docs.push(payment);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const details_wrapper = me.dialog.fields_dict.payment_details.$wrapper;
|
||||||
|
details_wrapper.append(frappe.render_template("linked_payment_header"));
|
||||||
|
displayed_docs.forEach(values => {
|
||||||
|
details_wrapper.append(frappe.render_template("linked_payment_row", values));
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"content": null,
|
||||||
|
"creation": "2018-11-24 12:03:14.646669",
|
||||||
|
"docstatus": 0,
|
||||||
|
"doctype": "Page",
|
||||||
|
"idx": 0,
|
||||||
|
"modified": "2018-11-24 12:03:14.646669",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "Accounts",
|
||||||
|
"name": "bank-reconciliation",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"page_name": "bank-reconciliation",
|
||||||
|
"roles": [
|
||||||
|
{
|
||||||
|
"role": "System Manager"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Accounts Manager"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Accounts User"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"script": null,
|
||||||
|
"standard": "Yes",
|
||||||
|
"style": null,
|
||||||
|
"system_page": 0,
|
||||||
|
"title": "Bank Reconciliation"
|
||||||
|
}
|
378
erpnext/accounts/page/bank_reconciliation/bank_reconciliation.py
Normal file
378
erpnext/accounts/page/bank_reconciliation/bank_reconciliation.py
Normal file
@ -0,0 +1,378 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
import difflib
|
||||||
|
from frappe.utils import flt
|
||||||
|
from six import iteritems
|
||||||
|
from erpnext import get_company_currency
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def reconcile(bank_transaction, payment_doctype, payment_name):
|
||||||
|
transaction = frappe.get_doc("Bank Transaction", bank_transaction)
|
||||||
|
payment_entry = frappe.get_doc(payment_doctype, payment_name)
|
||||||
|
|
||||||
|
account = frappe.db.get_value("Bank Account", transaction.bank_account, "account")
|
||||||
|
gl_entry = frappe.get_doc("GL Entry", dict(account=account, voucher_type=payment_doctype, voucher_no=payment_name))
|
||||||
|
|
||||||
|
if transaction.unallocated_amount == 0:
|
||||||
|
frappe.throw(_("This bank transaction is already fully reconciled"))
|
||||||
|
|
||||||
|
if transaction.credit > 0 and gl_entry.credit > 0:
|
||||||
|
frappe.throw(_("The selected payment entry should be linked with a debtor bank transaction"))
|
||||||
|
|
||||||
|
if transaction.debit > 0 and gl_entry.debit > 0:
|
||||||
|
frappe.throw(_("The selected payment entry should be linked with a creditor bank transaction"))
|
||||||
|
|
||||||
|
add_payment_to_transaction(transaction, payment_entry, gl_entry)
|
||||||
|
|
||||||
|
return 'reconciled'
|
||||||
|
|
||||||
|
def add_payment_to_transaction(transaction, payment_entry, gl_entry):
|
||||||
|
gl_amount, transaction_amount = (gl_entry.credit, transaction.debit) if gl_entry.credit > 0 else (gl_entry.debit, transaction.credit)
|
||||||
|
allocated_amount = gl_amount if gl_amount <= transaction_amount else transaction_amount
|
||||||
|
transaction.append("payment_entries", {
|
||||||
|
"payment_document": payment_entry.doctype,
|
||||||
|
"payment_entry": payment_entry.name,
|
||||||
|
"allocated_amount": allocated_amount
|
||||||
|
})
|
||||||
|
|
||||||
|
transaction.save()
|
||||||
|
transaction.update_allocations()
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def get_linked_payments(bank_transaction):
|
||||||
|
transaction = frappe.get_doc("Bank Transaction", bank_transaction)
|
||||||
|
bank_account = frappe.db.get_values("Bank Account", transaction.bank_account, ["account", "company"], as_dict=True)
|
||||||
|
|
||||||
|
# Get all payment entries with a matching amount
|
||||||
|
amount_matching = check_matching_amount(bank_account[0].account, bank_account[0].company, transaction)
|
||||||
|
|
||||||
|
# Get some data from payment entries linked to a corresponding bank transaction
|
||||||
|
description_matching = get_matching_descriptions_data(bank_account[0].company, transaction)
|
||||||
|
|
||||||
|
if amount_matching:
|
||||||
|
return check_amount_vs_description(amount_matching, description_matching)
|
||||||
|
|
||||||
|
elif description_matching:
|
||||||
|
description_matching = filter(lambda x: not x.get('clearance_date'), description_matching)
|
||||||
|
if not description_matching:
|
||||||
|
return []
|
||||||
|
|
||||||
|
return sorted(list(description_matching), key = lambda x: x["posting_date"], reverse=True)
|
||||||
|
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
|
def check_matching_amount(bank_account, company, transaction):
|
||||||
|
payments = []
|
||||||
|
amount = transaction.credit if transaction.credit > 0 else transaction.debit
|
||||||
|
|
||||||
|
payment_type = "Receive" if transaction.credit > 0 else "Pay"
|
||||||
|
account_from_to = "paid_to" if transaction.credit > 0 else "paid_from"
|
||||||
|
currency_field = "paid_to_account_currency as currency" if transaction.credit > 0 else "paid_from_account_currency as currency"
|
||||||
|
|
||||||
|
payment_entries = frappe.get_all("Payment Entry", fields=["'Payment Entry' as doctype", "name", "paid_amount", "payment_type", "reference_no", "reference_date",
|
||||||
|
"party", "party_type", "posting_date", "{0}".format(currency_field)], filters=[["paid_amount", "like", "{0}%".format(amount)],
|
||||||
|
["docstatus", "=", "1"], ["payment_type", "=", [payment_type, "Internal Transfer"]], ["ifnull(clearance_date, '')", "=", ""], ["{0}".format(account_from_to), "=", "{0}".format(bank_account)]])
|
||||||
|
|
||||||
|
if transaction.credit > 0:
|
||||||
|
journal_entries = frappe.db.sql("""
|
||||||
|
SELECT
|
||||||
|
'Journal Entry' as doctype, je.name, je.posting_date, je.cheque_no as reference_no,
|
||||||
|
je.pay_to_recd_from as party, je.cheque_date as reference_date, jea.debit_in_account_currency as paid_amount
|
||||||
|
FROM
|
||||||
|
`tabJournal Entry Account` as jea
|
||||||
|
JOIN
|
||||||
|
`tabJournal Entry` as je
|
||||||
|
ON
|
||||||
|
jea.parent = je.name
|
||||||
|
WHERE
|
||||||
|
(je.clearance_date is null or je.clearance_date='0000-00-00')
|
||||||
|
AND
|
||||||
|
jea.account = %s
|
||||||
|
AND
|
||||||
|
jea.debit_in_account_currency like %s
|
||||||
|
AND
|
||||||
|
je.docstatus = 1
|
||||||
|
""", (bank_account, amount), as_dict=True)
|
||||||
|
else:
|
||||||
|
journal_entries = frappe.db.sql("""
|
||||||
|
SELECT
|
||||||
|
'Journal Entry' as doctype, je.name, je.posting_date, je.cheque_no as reference_no,
|
||||||
|
jea.account_currency as currency, je.pay_to_recd_from as party, je.cheque_date as reference_date,
|
||||||
|
jea.credit_in_account_currency as paid_amount
|
||||||
|
FROM
|
||||||
|
`tabJournal Entry Account` as jea
|
||||||
|
JOIN
|
||||||
|
`tabJournal Entry` as je
|
||||||
|
ON
|
||||||
|
jea.parent = je.name
|
||||||
|
WHERE
|
||||||
|
(je.clearance_date is null or je.clearance_date='0000-00-00')
|
||||||
|
AND
|
||||||
|
jea.account = %(bank_account)s
|
||||||
|
AND
|
||||||
|
jea.credit_in_account_currency like %(txt)s
|
||||||
|
AND
|
||||||
|
je.docstatus = 1
|
||||||
|
""", {
|
||||||
|
'bank_account': bank_account,
|
||||||
|
'txt': '%%%s%%' % amount
|
||||||
|
}, as_dict=True)
|
||||||
|
|
||||||
|
frappe.errprint(journal_entries)
|
||||||
|
|
||||||
|
if transaction.credit > 0:
|
||||||
|
sales_invoices = frappe.db.sql("""
|
||||||
|
SELECT
|
||||||
|
'Sales Invoice' as doctype, si.name, si.customer as party,
|
||||||
|
si.posting_date, sip.amount as paid_amount
|
||||||
|
FROM
|
||||||
|
`tabSales Invoice Payment` as sip
|
||||||
|
JOIN
|
||||||
|
`tabSales Invoice` as si
|
||||||
|
ON
|
||||||
|
sip.parent = si.name
|
||||||
|
WHERE
|
||||||
|
(sip.clearance_date is null or sip.clearance_date='0000-00-00')
|
||||||
|
AND
|
||||||
|
sip.account = %s
|
||||||
|
AND
|
||||||
|
sip.amount like %s
|
||||||
|
AND
|
||||||
|
si.docstatus = 1
|
||||||
|
""", (bank_account, amount), as_dict=True)
|
||||||
|
else:
|
||||||
|
sales_invoices = []
|
||||||
|
|
||||||
|
if transaction.debit > 0:
|
||||||
|
purchase_invoices = frappe.get_all("Purchase Invoice",
|
||||||
|
fields = ["'Purchase Invoice' as doctype", "name", "paid_amount", "supplier as party", "posting_date", "currency"],
|
||||||
|
filters=[
|
||||||
|
["paid_amount", "like", "{0}%".format(amount)],
|
||||||
|
["docstatus", "=", "1"],
|
||||||
|
["is_paid", "=", "1"],
|
||||||
|
["ifnull(clearance_date, '')", "=", ""],
|
||||||
|
["cash_bank_account", "=", "{0}".format(bank_account)]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
mode_of_payments = [x["parent"] for x in frappe.db.get_list("Mode of Payment Account",
|
||||||
|
filters={"default_account": bank_account}, fields=["parent"])]
|
||||||
|
|
||||||
|
company_currency = get_company_currency(company)
|
||||||
|
|
||||||
|
expense_claims = frappe.get_all("Expense Claim",
|
||||||
|
fields=["'Expense Claim' as doctype", "name", "total_sanctioned_amount as paid_amount",
|
||||||
|
"employee as party", "posting_date", "'{0}' as currency".format(company_currency)],
|
||||||
|
filters=[
|
||||||
|
["total_sanctioned_amount", "like", "{0}%".format(amount)],
|
||||||
|
["docstatus", "=", "1"],
|
||||||
|
["is_paid", "=", "1"],
|
||||||
|
["ifnull(clearance_date, '')", "=", ""],
|
||||||
|
["mode_of_payment", "in", "{0}".format(tuple(mode_of_payments))]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
purchase_invoices = expense_claims = []
|
||||||
|
|
||||||
|
for data in [payment_entries, journal_entries, sales_invoices, purchase_invoices, expense_claims]:
|
||||||
|
if data:
|
||||||
|
payments.extend(data)
|
||||||
|
|
||||||
|
return payments
|
||||||
|
|
||||||
|
def get_matching_descriptions_data(company, transaction):
|
||||||
|
if not transaction.description :
|
||||||
|
return []
|
||||||
|
|
||||||
|
bank_transactions = frappe.db.sql("""
|
||||||
|
SELECT
|
||||||
|
bt.name, bt.description, bt.date, btp.payment_document, btp.payment_entry
|
||||||
|
FROM
|
||||||
|
`tabBank Transaction` as bt
|
||||||
|
LEFT JOIN
|
||||||
|
`tabBank Transaction Payments` as btp
|
||||||
|
ON
|
||||||
|
bt.name = btp.parent
|
||||||
|
WHERE
|
||||||
|
bt.allocated_amount > 0
|
||||||
|
AND
|
||||||
|
bt.docstatus = 1
|
||||||
|
""", as_dict=True)
|
||||||
|
|
||||||
|
selection = []
|
||||||
|
for bank_transaction in bank_transactions:
|
||||||
|
if bank_transaction.description:
|
||||||
|
seq=difflib.SequenceMatcher(lambda x: x == " ", transaction.description, bank_transaction.description)
|
||||||
|
|
||||||
|
if seq.ratio() > 0.6:
|
||||||
|
bank_transaction["ratio"] = seq.ratio()
|
||||||
|
selection.append(bank_transaction)
|
||||||
|
|
||||||
|
document_types = set([x["payment_document"] for x in selection])
|
||||||
|
|
||||||
|
links = {}
|
||||||
|
for document_type in document_types:
|
||||||
|
links[document_type] = [x["payment_entry"] for x in selection if x["payment_document"]==document_type]
|
||||||
|
|
||||||
|
|
||||||
|
data = []
|
||||||
|
company_currency = get_company_currency(company)
|
||||||
|
for key, value in iteritems(links):
|
||||||
|
if key == "Payment Entry":
|
||||||
|
data.extend(frappe.get_all("Payment Entry", filters=[["name", "in", value]],
|
||||||
|
fields=["'Payment Entry' as doctype", "posting_date", "party", "reference_no",
|
||||||
|
"reference_date", "paid_amount", "paid_to_account_currency as currency", "clearance_date"]))
|
||||||
|
if key == "Journal Entry":
|
||||||
|
journal_entries = frappe.get_all("Journal Entry", filters=[["name", "in", value]],
|
||||||
|
fields=["name", "'Journal Entry' as doctype", "posting_date",
|
||||||
|
"pay_to_recd_from as party", "cheque_no as reference_no", "cheque_date as reference_date",
|
||||||
|
"total_credit as paid_amount", "clearance_date"])
|
||||||
|
for journal_entry in journal_entries:
|
||||||
|
journal_entry_accounts = frappe.get_all("Journal Entry Account", filters={"parenttype": journal_entry["doctype"], "parent": journal_entry["name"]}, fields=["account_currency"])
|
||||||
|
journal_entry["currency"] = journal_entry_accounts[0]["account_currency"] if journal_entry_accounts else company_currency
|
||||||
|
data.extend(journal_entries)
|
||||||
|
if key == "Sales Invoice":
|
||||||
|
data.extend(frappe.get_all("Sales Invoice", filters=[["name", "in", value]], fields=["'Sales Invoice' as doctype", "posting_date", "customer_name as party", "paid_amount", "currency"]))
|
||||||
|
if key == "Purchase Invoice":
|
||||||
|
data.extend(frappe.get_all("Purchase Invoice", filters=[["name", "in", value]], fields=["'Purchase Invoice' as doctype", "posting_date", "supplier_name as party", "paid_amount", "currency"]))
|
||||||
|
if key == "Expense Claim":
|
||||||
|
expense_claims = frappe.get_all("Expense Claim", filters=[["name", "in", value]], fields=["'Expense Claim' as doctype", "posting_date", "employee_name as party", "total_amount_reimbursed as paid_amount"])
|
||||||
|
data.extend([dict(x,**{"currency": company_currency}) for x in expense_claims])
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
def check_amount_vs_description(amount_matching, description_matching):
|
||||||
|
result = []
|
||||||
|
|
||||||
|
if description_matching:
|
||||||
|
for am_match in amount_matching:
|
||||||
|
for des_match in description_matching:
|
||||||
|
if des_match.get("clearance_date"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if am_match["party"] == des_match["party"]:
|
||||||
|
if am_match not in result:
|
||||||
|
result.append(am_match)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if "reference_no" in am_match and "reference_no" in des_match:
|
||||||
|
if difflib.SequenceMatcher(lambda x: x == " ", am_match["reference_no"], des_match["reference_no"]).ratio() > 70:
|
||||||
|
if am_match not in result:
|
||||||
|
result.append(am_match)
|
||||||
|
if result:
|
||||||
|
return sorted(result, key = lambda x: x["posting_date"], reverse=True)
|
||||||
|
else:
|
||||||
|
return sorted(amount_matching, key = lambda x: x["posting_date"], reverse=True)
|
||||||
|
|
||||||
|
else:
|
||||||
|
return sorted(amount_matching, key = lambda x: x["posting_date"], reverse=True)
|
||||||
|
|
||||||
|
def get_matching_transactions_payments(description_matching):
|
||||||
|
payments = [x["payment_entry"] for x in description_matching]
|
||||||
|
|
||||||
|
payment_by_ratio = {x["payment_entry"]: x["ratio"] for x in description_matching}
|
||||||
|
|
||||||
|
if payments:
|
||||||
|
reference_payment_list = frappe.get_all("Payment Entry", fields=["name", "paid_amount", "payment_type", "reference_no", "reference_date",
|
||||||
|
"party", "party_type", "posting_date", "paid_to_account_currency"], filters=[["name", "in", payments]])
|
||||||
|
|
||||||
|
return sorted(reference_payment_list, key=lambda x: payment_by_ratio[x["name"]])
|
||||||
|
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
|
def payment_entry_query(doctype, txt, searchfield, start, page_len, filters):
|
||||||
|
account = frappe.db.get_value("Bank Account", filters.get("bank_account"), "account")
|
||||||
|
if not account:
|
||||||
|
return
|
||||||
|
|
||||||
|
return frappe.db.sql("""
|
||||||
|
SELECT
|
||||||
|
name, party, paid_amount, received_amount, reference_no
|
||||||
|
FROM
|
||||||
|
`tabPayment Entry`
|
||||||
|
WHERE
|
||||||
|
(clearance_date is null or clearance_date='0000-00-00')
|
||||||
|
AND (paid_from = %(account)s or paid_to = %(account)s)
|
||||||
|
AND (name like %(txt)s or party like %(txt)s)
|
||||||
|
AND docstatus = 1
|
||||||
|
ORDER BY
|
||||||
|
if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999), name
|
||||||
|
LIMIT
|
||||||
|
%(start)s, %(page_len)s""",
|
||||||
|
{
|
||||||
|
'txt': "%%%s%%" % txt,
|
||||||
|
'_txt': txt.replace("%", ""),
|
||||||
|
'start': start,
|
||||||
|
'page_len': page_len,
|
||||||
|
'account': account
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def journal_entry_query(doctype, txt, searchfield, start, page_len, filters):
|
||||||
|
account = frappe.db.get_value("Bank Account", filters.get("bank_account"), "account")
|
||||||
|
|
||||||
|
return frappe.db.sql("""
|
||||||
|
SELECT
|
||||||
|
jea.parent, je.pay_to_recd_from,
|
||||||
|
if(jea.debit_in_account_currency > 0, jea.debit_in_account_currency, jea.credit_in_account_currency)
|
||||||
|
FROM
|
||||||
|
`tabJournal Entry Account` as jea
|
||||||
|
LEFT JOIN
|
||||||
|
`tabJournal Entry` as je
|
||||||
|
ON
|
||||||
|
jea.parent = je.name
|
||||||
|
WHERE
|
||||||
|
(je.clearance_date is null or je.clearance_date='0000-00-00')
|
||||||
|
AND
|
||||||
|
jea.account = %(account)s
|
||||||
|
AND
|
||||||
|
(jea.parent like %(txt)s or je.pay_to_recd_from like %(txt)s)
|
||||||
|
AND
|
||||||
|
je.docstatus = 1
|
||||||
|
ORDER BY
|
||||||
|
if(locate(%(_txt)s, jea.parent), locate(%(_txt)s, jea.parent), 99999),
|
||||||
|
jea.parent
|
||||||
|
LIMIT
|
||||||
|
%(start)s, %(page_len)s""",
|
||||||
|
{
|
||||||
|
'txt': "%%%s%%" % txt,
|
||||||
|
'_txt': txt.replace("%", ""),
|
||||||
|
'start': start,
|
||||||
|
'page_len': page_len,
|
||||||
|
'account': account
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def sales_invoices_query(doctype, txt, searchfield, start, page_len, filters):
|
||||||
|
return frappe.db.sql("""
|
||||||
|
SELECT
|
||||||
|
sip.parent, si.customer, sip.amount, sip.mode_of_payment
|
||||||
|
FROM
|
||||||
|
`tabSales Invoice Payment` as sip
|
||||||
|
LEFT JOIN
|
||||||
|
`tabSales Invoice` as si
|
||||||
|
ON
|
||||||
|
sip.parent = si.name
|
||||||
|
WHERE
|
||||||
|
(sip.clearance_date is null or sip.clearance_date='0000-00-00')
|
||||||
|
AND
|
||||||
|
(sip.parent like %(txt)s or si.customer like %(txt)s)
|
||||||
|
ORDER BY
|
||||||
|
if(locate(%(_txt)s, sip.parent), locate(%(_txt)s, sip.parent), 99999),
|
||||||
|
sip.parent
|
||||||
|
LIMIT
|
||||||
|
%(start)s, %(page_len)s""",
|
||||||
|
{
|
||||||
|
'txt': "%%%s%%" % txt,
|
||||||
|
'_txt': txt.replace("%", ""),
|
||||||
|
'start': start,
|
||||||
|
'page_len': page_len
|
||||||
|
}
|
||||||
|
)
|
@ -0,0 +1,21 @@
|
|||||||
|
<div class="transaction-header">
|
||||||
|
<div class="level list-row list-row-head text-muted small">
|
||||||
|
<div class="col-sm-2 ellipsis hidden-xs">
|
||||||
|
{{ __("Date") }}
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-11 col-sm-4 ellipsis list-subject">
|
||||||
|
{{ __("Description") }}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2 ellipsis hidden-xs">
|
||||||
|
{{ __("Debit") }}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2 ellipsis hidden-xs">
|
||||||
|
{{ __("Credit") }}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-1 ellipsis hidden-xs">
|
||||||
|
{{ __("Currency") }}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-1 ellipsis">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,36 @@
|
|||||||
|
<div class="list-row transaction-item">
|
||||||
|
<div>
|
||||||
|
<div class="clickable-section" data-name={{ name }}>
|
||||||
|
<div class="col-sm-2 ellipsis hidden-xs">
|
||||||
|
{%= frappe.datetime.str_to_user(date) %}
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-8 col-sm-4 ellipsis list-subject">
|
||||||
|
{{ description }}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2 ellipsis hidden-xs">
|
||||||
|
{%= format_currency(debit, currency) %}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2 ellipsis hidden-xs">
|
||||||
|
{%= format_currency(credit, currency) %}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-1 ellipsis hidden-xs">
|
||||||
|
{{ currency }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-3 col-sm-1">
|
||||||
|
<div class="btn-group">
|
||||||
|
<a class="dropdown-toggle btn btn-default btn-xs" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<span>Actions </span>
|
||||||
|
<span class="caret"></span>
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu reports-dropdown" style="max-height: 300px; overflow-y: auto; right: 0px; left: auto;">
|
||||||
|
<li><a class="new-reconciliation" data-name={{ name }}>{{ __("Reconcile") }}</a></li>
|
||||||
|
<li class="divider"></li>
|
||||||
|
<li><a class="new-payment" data-name={{ name }}>{{ __("New Payment") }}</a></li>
|
||||||
|
<li><a class="new-invoice" data-name={{ name }}>{{ __("New Invoice") }}</a></li>
|
||||||
|
<li><a class="new-expense" data-name={{ name }}>{{ __("New Expense") }}</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,21 @@
|
|||||||
|
<div class="transaction-header">
|
||||||
|
<div class="level list-row list-row-head text-muted small">
|
||||||
|
<div class="col-xs-3 col-sm-2 ellipsis">
|
||||||
|
{{ __("Payment Name") }}
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-3 col-sm-2 ellipsis">
|
||||||
|
{{ __("Reference Date") }}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2 ellipsis hidden-xs">
|
||||||
|
{{ __("Amount") }}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2 ellipsis hidden-xs">
|
||||||
|
{{ __("Party") }}
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-3 col-sm-2 ellipsis">
|
||||||
|
{{ __("Reference Number") }}
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-2 col-sm-2">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,36 @@
|
|||||||
|
<div class="list-row">
|
||||||
|
<div>
|
||||||
|
<div class="col-xs-3 col-sm-2 ellipsis">
|
||||||
|
{{ name }}
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-3 col-sm-2 ellipsis">
|
||||||
|
{% if (typeof reference_date !== "undefined") %}
|
||||||
|
{%= frappe.datetime.str_to_user(reference_date) %}
|
||||||
|
{% else %}
|
||||||
|
{% if (typeof posting_date !== "undefined") %}
|
||||||
|
{%= frappe.datetime.str_to_user(posting_date) %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2 ellipsis hidden-xs">
|
||||||
|
{{ format_currency(paid_amount, currency) }}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2 ellipsis hidden-xs">
|
||||||
|
{% if (typeof party !== "undefined") %}
|
||||||
|
{{ party }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-3 col-sm-2 ellipsis">
|
||||||
|
{% if (typeof reference_no !== "undefined") %}
|
||||||
|
{{ reference_no }}
|
||||||
|
{% else %}
|
||||||
|
{{ "" }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-2 col-sm-2">
|
||||||
|
<div class="text-right margin-bottom">
|
||||||
|
<button class="btn btn-primary btn-xs reconciliation-btn" data-doctype="{{ doctype }}" data-name="{{ name }}">{{ __("Reconcile") }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -1957,6 +1957,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
|||||||
}],
|
}],
|
||||||
function(values){
|
function(values){
|
||||||
me.item_batch_no[me.items[0].item_code] = values.batch;
|
me.item_batch_no[me.items[0].item_code] = values.batch;
|
||||||
|
const item = me.frm.doc.items.find(
|
||||||
|
({ item_code }) => item_code === me.items[0].item_code
|
||||||
|
);
|
||||||
|
if (item) {
|
||||||
|
item.batch_no = values.batch;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
__('Select Batch No'))
|
__('Select Batch No'))
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ def _get_party_details(party=None, account=None, party_type="Customer", company=
|
|||||||
frappe.throw(_("Not permitted for {0}").format(party), frappe.PermissionError)
|
frappe.throw(_("Not permitted for {0}").format(party), frappe.PermissionError)
|
||||||
|
|
||||||
party = frappe.get_doc(party_type, party)
|
party = frappe.get_doc(party_type, party)
|
||||||
currency = party.default_currency if party.default_currency else get_company_currency(company)
|
currency = party.default_currency if party.get("default_currency") else get_company_currency(company)
|
||||||
|
|
||||||
party_address, shipping_address = set_address_details(out, party, party_type, doctype, company, party_address, shipping_address)
|
party_address, shipping_address = set_address_details(out, party, party_type, doctype, company, party_address, shipping_address)
|
||||||
set_contact_details(out, party, party_type)
|
set_contact_details(out, party, party_type)
|
||||||
@ -144,7 +144,7 @@ def set_other_values(out, party, party_type):
|
|||||||
|
|
||||||
def get_default_price_list(party):
|
def get_default_price_list(party):
|
||||||
"""Return default price list for party (Document object)"""
|
"""Return default price list for party (Document object)"""
|
||||||
if party.default_price_list:
|
if party.get("default_price_list"):
|
||||||
return party.default_price_list
|
return party.default_price_list
|
||||||
|
|
||||||
if party.doctype == "Customer":
|
if party.doctype == "Customer":
|
||||||
|
@ -1,19 +1,23 @@
|
|||||||
{
|
{
|
||||||
"creation": "2014-08-28 11:11:39.796473",
|
"align_labels_right": 0,
|
||||||
"custom_format": 0,
|
"creation": "2014-08-28 11:11:39.796473",
|
||||||
"disabled": 0,
|
"custom_format": 0,
|
||||||
"doc_type": "Journal Entry",
|
"disabled": 0,
|
||||||
"docstatus": 0,
|
"doc_type": "Journal Entry",
|
||||||
"doctype": "Print Format",
|
"docstatus": 0,
|
||||||
"html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n\n<div class=\"page-break\">\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Credit Note\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n {%- for label, value in (\n (_(\"Credit To\"), doc.pay_to_recd_from),\n (_(\"Date\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Amount\"), \"<strong>\" + doc.get_formatted(\"total_amount\") + \"</strong><br>\" + (doc.total_amount_in_words or \"\") + \"<br>\"),\n (_(\"Remarks\"), doc.remark)\n ) -%}\n\n <div class=\"row\">\n <div class=\"col-xs-3\"><label class=\"text-right\">{{ label }}</label></div>\n <div class=\"col-xs-9\">{{ value }}</div>\n </div>\n\n {%- endfor -%}\n\n <hr>\n <br>\n <p class=\"strong\">\n {{ _(\"For\") }} {{ doc.company }},<br>\n <br>\n <br>\n <br>\n {{ _(\"Authorized Signatory\") }}\n </p>\n</div>\n\n\n",
|
"doctype": "Print Format",
|
||||||
"idx": 2,
|
"format_data": "[{\"fieldname\": \"print_heading_template\", \"fieldtype\": \"Custom HTML\", \"options\": \"<div class=\\\"print-heading\\\">\\t\\t\\t\\t<h2>Journal Entry<br><small>{{ doc.name }}</small>\\t\\t\\t\\t</h2></div>\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"voucher_type\", \"print_hide\": 0, \"label\": \"Entry Type\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"posting_date\", \"print_hide\": 0, \"label\": \"Posting Date\"}, {\"fieldname\": \"finance_book\", \"print_hide\": 0, \"label\": \"Finance Book\"}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"accounts\", \"print_hide\": 0, \"label\": \"Accounting Entries\", \"visible_columns\": [{\"fieldname\": \"account\", \"print_width\": \"250px\", \"print_hide\": 0}, {\"fieldname\": \"bank_account_no\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"party_type\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"party\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"debit_in_account_currency\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"credit_in_account_currency\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"reference_type\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"reference_name\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"reference_due_date\", \"print_width\": \"\", \"print_hide\": 0}, {\"fieldname\": \"project\", \"print_width\": \"\", \"print_hide\": 0}]}, {\"fieldtype\": \"Section Break\", \"label\": \"\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"cheque_no\", \"print_hide\": 0, \"label\": \"Reference Number\"}, {\"fieldname\": \"cheque_date\", \"print_hide\": 0, \"label\": \"Reference Date\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"get_balance\", \"print_hide\": 0, \"label\": \"Make Difference Entry\"}, {\"fieldname\": \"total_amount\", \"print_hide\": 0, \"label\": \"Total Amount\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Reference\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"clearance_date\", \"print_hide\": 0, \"label\": \"Clearance Date\"}, {\"fieldname\": \"remark\", \"print_hide\": 0, \"label\": \"Remark\"}, {\"fieldname\": \"inter_company_journal_entry_reference\", \"print_hide\": 0, \"label\": \"Inter Company Journal Entry Reference\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"due_date\", \"print_hide\": 0, \"label\": \"Due Date\"}, {\"fieldtype\": \"Section Break\", \"label\": \"Printing Settings\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"pay_to_recd_from\", \"print_hide\": 0, \"label\": \"Pay To / Recd From\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"letter_head\", \"print_hide\": 0, \"label\": \"Letter Head\"}, {\"fieldtype\": \"Section Break\", \"label\": \"More Information\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"mode_of_payment\", \"print_hide\": 0, \"label\": \"Mode of Payment\"}, {\"fieldtype\": \"Column Break\"}, {\"fieldname\": \"stock_entry\", \"print_hide\": 0, \"label\": \"Stock Entry\"}]",
|
||||||
"modified": "2015-07-22 17:42:01.560817",
|
"html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n\n<div class=\"page-break\">\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Credit Note\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n {%- for label, value in (\n (_(\"Credit To\"), doc.pay_to_recd_from),\n (_(\"Date\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Amount\"), \"<strong>\" + doc.get_formatted(\"total_amount\") + \"</strong><br>\" + (doc.total_amount_in_words or \"\") + \"<br>\"),\n (_(\"Remarks\"), doc.remark)\n ) -%}\n\n <div class=\"row\">\n <div class=\"col-xs-3\"><label class=\"text-right\">{{ label }}</label></div>\n <div class=\"col-xs-9\">{{ value }}</div>\n </div>\n\n {%- endfor -%}\n\n <hr>\n <br>\n <p class=\"strong\">\n {{ _(\"For\") }} {{ doc.company }},<br>\n <br>\n <br>\n <br>\n {{ _(\"Authorized Signatory\") }}\n </p>\n</div>\n\n\n",
|
||||||
"modified_by": "Administrator",
|
"idx": 2,
|
||||||
"name": "Credit Note",
|
"line_breaks": 0,
|
||||||
"owner": "Administrator",
|
"modified": "2019-04-18 12:10:14.732269",
|
||||||
"parent": "Journal Entry",
|
"modified_by": "Administrator",
|
||||||
"parentfield": "__print_formats",
|
"module": "Accounts",
|
||||||
"parenttype": "DocType",
|
"name": "Credit Note",
|
||||||
"print_format_type": "Server",
|
"owner": "Administrator",
|
||||||
|
"parentfield": "__print_formats",
|
||||||
|
"print_format_builder": 0,
|
||||||
|
"print_format_type": "Server",
|
||||||
|
"show_section_headings": 0,
|
||||||
"standard": "Yes"
|
"standard": "Yes"
|
||||||
}
|
}
|
@ -8,6 +8,7 @@ frappe.query_reports["Accounts Payable"] = {
|
|||||||
"label": __("Company"),
|
"label": __("Company"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Company",
|
"options": "Company",
|
||||||
|
"reqd": 1,
|
||||||
"default": frappe.defaults.get_user_default("Company")
|
"default": frappe.defaults.get_user_default("Company")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -107,3 +108,14 @@ frappe.query_reports["Accounts Payable"] = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
erpnext.dimension_filters.then((dimensions) => {
|
||||||
|
dimensions.forEach((dimension) => {
|
||||||
|
frappe.query_reports["Accounts Payable"].filters.splice(9, 0 ,{
|
||||||
|
"fieldname": dimension["fieldname"],
|
||||||
|
"label": __(dimension["label"]),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": dimension["document_type"]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -92,3 +92,14 @@ frappe.query_reports["Accounts Payable Summary"] = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
erpnext.dimension_filters.then((dimensions) => {
|
||||||
|
dimensions.forEach((dimension) => {
|
||||||
|
frappe.query_reports["Accounts Payable Summary"].filters.splice(9, 0 ,{
|
||||||
|
"fieldname": dimension["fieldname"],
|
||||||
|
"label": __(dimension["label"]),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": dimension["document_type"]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -8,6 +8,7 @@ frappe.query_reports["Accounts Receivable"] = {
|
|||||||
"label": __("Company"),
|
"label": __("Company"),
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"options": "Company",
|
"options": "Company",
|
||||||
|
"reqd": 1,
|
||||||
"default": frappe.defaults.get_user_default("Company")
|
"default": frappe.defaults.get_user_default("Company")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -171,3 +172,14 @@ frappe.query_reports["Accounts Receivable"] = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
erpnext.dimension_filters.then((dimensions) => {
|
||||||
|
dimensions.forEach((dimension) => {
|
||||||
|
frappe.query_reports["Accounts Receivable"].filters.splice(9, 0 ,{
|
||||||
|
"fieldname": dimension["fieldname"],
|
||||||
|
"label": __(dimension["label"]),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": dimension["document_type"]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe, erpnext
|
import frappe, erpnext
|
||||||
from frappe import _, scrub
|
from frappe import _, scrub
|
||||||
from frappe.utils import getdate, nowdate, flt, cint, formatdate, cstr
|
from frappe.utils import getdate, nowdate, flt, cint, formatdate, cstr
|
||||||
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
||||||
|
|
||||||
class ReceivablePayableReport(object):
|
class ReceivablePayableReport(object):
|
||||||
def __init__(self, filters=None):
|
def __init__(self, filters=None):
|
||||||
@ -197,10 +198,9 @@ class ReceivablePayableReport(object):
|
|||||||
self.payment_term_map = self.get_payment_term_detail(voucher_nos)
|
self.payment_term_map = self.get_payment_term_detail(voucher_nos)
|
||||||
|
|
||||||
for gle in gl_entries_data:
|
for gle in gl_entries_data:
|
||||||
if self.is_receivable_or_payable(gle, self.dr_or_cr, future_vouchers):
|
if self.is_receivable_or_payable(gle, self.dr_or_cr, future_vouchers, return_entries):
|
||||||
outstanding_amount, credit_note_amount, payment_amount = self.get_outstanding_amount(
|
outstanding_amount, credit_note_amount, payment_amount = self.get_outstanding_amount(
|
||||||
gle,self.filters.report_date, self.dr_or_cr, return_entries)
|
gle,self.filters.report_date, self.dr_or_cr, return_entries)
|
||||||
|
|
||||||
temp_outstanding_amt = outstanding_amount
|
temp_outstanding_amt = outstanding_amount
|
||||||
temp_credit_note_amt = credit_note_amount
|
temp_credit_note_amt = credit_note_amount
|
||||||
|
|
||||||
@ -379,7 +379,7 @@ class ReceivablePayableReport(object):
|
|||||||
# returns a generator
|
# returns a generator
|
||||||
return self.get_gl_entries(party_type, report_date)
|
return self.get_gl_entries(party_type, report_date)
|
||||||
|
|
||||||
def is_receivable_or_payable(self, gle, dr_or_cr, future_vouchers):
|
def is_receivable_or_payable(self, gle, dr_or_cr, future_vouchers, return_entries):
|
||||||
return (
|
return (
|
||||||
# advance
|
# advance
|
||||||
(not gle.against_voucher) or
|
(not gle.against_voucher) or
|
||||||
@ -390,30 +390,37 @@ class ReceivablePayableReport(object):
|
|||||||
# sales invoice/purchase invoice
|
# sales invoice/purchase invoice
|
||||||
(gle.against_voucher==gle.voucher_no and gle.get(dr_or_cr) > 0) or
|
(gle.against_voucher==gle.voucher_no and gle.get(dr_or_cr) > 0) or
|
||||||
|
|
||||||
|
# standalone credit notes
|
||||||
|
(gle.against_voucher==gle.voucher_no and gle.voucher_no in return_entries and not return_entries.get(gle.voucher_no)) or
|
||||||
|
|
||||||
# entries adjusted with future vouchers
|
# entries adjusted with future vouchers
|
||||||
((gle.against_voucher_type, gle.against_voucher) in future_vouchers)
|
((gle.against_voucher_type, gle.against_voucher) in future_vouchers)
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_return_entries(self, party_type):
|
def get_return_entries(self, party_type):
|
||||||
doctype = "Sales Invoice" if party_type=="Customer" else "Purchase Invoice"
|
doctype = "Sales Invoice" if party_type=="Customer" else "Purchase Invoice"
|
||||||
return [d.name for d in frappe.get_all(doctype, filters={"is_return": 1, "docstatus": 1})]
|
return_entries = frappe._dict(frappe.get_all(doctype,
|
||||||
|
filters={"is_return": 1, "docstatus": 1}, fields=["name", "return_against"], as_list=1))
|
||||||
|
return return_entries
|
||||||
|
|
||||||
def get_outstanding_amount(self, gle, report_date, dr_or_cr, return_entries):
|
def get_outstanding_amount(self, gle, report_date, dr_or_cr, return_entries):
|
||||||
payment_amount, credit_note_amount = 0.0, 0.0
|
payment_amount, credit_note_amount = 0.0, 0.0
|
||||||
reverse_dr_or_cr = "credit" if dr_or_cr=="debit" else "debit"
|
reverse_dr_or_cr = "credit" if dr_or_cr=="debit" else "debit"
|
||||||
|
|
||||||
for e in self.get_gl_entries_for(gle.party, gle.party_type, gle.voucher_type, gle.voucher_no):
|
for e in self.get_gl_entries_for(gle.party, gle.party_type, gle.voucher_type, gle.voucher_no):
|
||||||
if getdate(e.posting_date) <= report_date and e.name!=gle.name:
|
if getdate(e.posting_date) <= report_date \
|
||||||
|
and (e.name!=gle.name or (e.voucher_no in return_entries and not return_entries.get(e.voucher_no))):
|
||||||
|
|
||||||
amount = flt(e.get(reverse_dr_or_cr), self.currency_precision) - flt(e.get(dr_or_cr), self.currency_precision)
|
amount = flt(e.get(reverse_dr_or_cr), self.currency_precision) - flt(e.get(dr_or_cr), self.currency_precision)
|
||||||
if e.voucher_no not in return_entries:
|
if e.voucher_no not in return_entries:
|
||||||
payment_amount += amount
|
payment_amount += amount
|
||||||
else:
|
else:
|
||||||
credit_note_amount += amount
|
credit_note_amount += amount
|
||||||
|
|
||||||
outstanding_amount = (flt((flt(gle.get(dr_or_cr), self.currency_precision)
|
voucher_amount = flt(gle.get(dr_or_cr), self.currency_precision) - flt(gle.get(reverse_dr_or_cr), self.currency_precision)
|
||||||
- flt(gle.get(reverse_dr_or_cr), self.currency_precision)
|
if gle.voucher_no in return_entries and not return_entries.get(gle.voucher_no):
|
||||||
- payment_amount - credit_note_amount), self.currency_precision))
|
voucher_amount = 0
|
||||||
|
|
||||||
|
outstanding_amount = flt((voucher_amount - payment_amount - credit_note_amount), self.currency_precision)
|
||||||
credit_note_amount = flt(credit_note_amount, self.currency_precision)
|
credit_note_amount = flt(credit_note_amount, self.currency_precision)
|
||||||
|
|
||||||
return outstanding_amount, credit_note_amount, payment_amount
|
return outstanding_amount, credit_note_amount, payment_amount
|
||||||
@ -541,10 +548,19 @@ class ReceivablePayableReport(object):
|
|||||||
conditions.append("""cost_center in (select name from `tabCost Center` where
|
conditions.append("""cost_center in (select name from `tabCost Center` where
|
||||||
lft >= {0} and rgt <= {1})""".format(lft, rgt))
|
lft >= {0} and rgt <= {1})""".format(lft, rgt))
|
||||||
|
|
||||||
accounts = [d.name for d in frappe.get_all("Account",
|
if self.filters.company:
|
||||||
filters={"account_type": account_type, "company": self.filters.company})]
|
accounts = [d.name for d in frappe.get_all("Account",
|
||||||
conditions.append("account in (%s)" % ','.join(['%s'] *len(accounts)))
|
filters={"account_type": account_type, "company": self.filters.company})]
|
||||||
values += accounts
|
conditions.append("account in (%s)" % ','.join(['%s'] *len(accounts)))
|
||||||
|
values += accounts
|
||||||
|
|
||||||
|
accounting_dimensions = get_accounting_dimensions()
|
||||||
|
|
||||||
|
if accounting_dimensions:
|
||||||
|
for dimension in accounting_dimensions:
|
||||||
|
if self.filters.get(dimension):
|
||||||
|
conditions.append("{0} = %s".format(dimension))
|
||||||
|
values.append(self.filters.get(dimension))
|
||||||
|
|
||||||
return " and ".join(conditions), values
|
return " and ".join(conditions), values
|
||||||
|
|
||||||
@ -592,9 +608,12 @@ class ReceivablePayableReport(object):
|
|||||||
|
|
||||||
rows = []
|
rows = []
|
||||||
for d in data:
|
for d in data:
|
||||||
|
values = d[self.ageing_col_idx_start : self.ageing_col_idx_start+5]
|
||||||
|
precision = cint(frappe.db.get_default("float_precision")) or 2
|
||||||
|
formatted_values = [frappe.utils.rounded(val, precision) for val in values]
|
||||||
rows.append(
|
rows.append(
|
||||||
{
|
{
|
||||||
'values': d[self.ageing_col_idx_start : self.ageing_col_idx_start+5]
|
'values': formatted_values
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -116,3 +116,14 @@ frappe.query_reports["Accounts Receivable Summary"] = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
erpnext.dimension_filters.then((dimensions) => {
|
||||||
|
dimensions.forEach((dimension) => {
|
||||||
|
frappe.query_reports["Accounts Receivable Summary"].filters.splice(9, 0 ,{
|
||||||
|
"fieldname": dimension["fieldname"],
|
||||||
|
"label": __(dimension["label"]),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": dimension["document_type"]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -63,9 +63,7 @@ frappe.query_reports["Budget Variance Report"] = {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
let dimension_filters = erpnext.get_dimension_filters();
|
erpnext.dimension_filters.then((dimensions) => {
|
||||||
|
|
||||||
dimension_filters.then((dimensions) => {
|
|
||||||
dimensions.forEach((dimension) => {
|
dimensions.forEach((dimension) => {
|
||||||
frappe.query_reports["Budget Variance Report"].filters[4].options.push(dimension["document_type"]);
|
frappe.query_reports["Budget Variance Report"].filters[4].options.push(dimension["document_type"]);
|
||||||
});
|
});
|
||||||
|
@ -322,7 +322,10 @@ def sort_accounts(accounts, is_root=False, key="name"):
|
|||||||
"""Sort root types as Asset, Liability, Equity, Income, Expense"""
|
"""Sort root types as Asset, Liability, Equity, Income, Expense"""
|
||||||
|
|
||||||
def compare_accounts(a, b):
|
def compare_accounts(a, b):
|
||||||
if is_root:
|
if re.split('\W+', a[key])[0].isdigit():
|
||||||
|
# if chart of accounts is numbered, then sort by number
|
||||||
|
return cmp(a[key], b[key])
|
||||||
|
elif is_root:
|
||||||
if a.report_type != b.report_type and a.report_type == "Balance Sheet":
|
if a.report_type != b.report_type and a.report_type == "Balance Sheet":
|
||||||
return -1
|
return -1
|
||||||
if a.root_type != b.root_type and a.root_type == "Asset":
|
if a.root_type != b.root_type and a.root_type == "Asset":
|
||||||
@ -353,6 +356,7 @@ def set_gl_entries_by_account(
|
|||||||
"company": company,
|
"company": company,
|
||||||
"from_date": from_date,
|
"from_date": from_date,
|
||||||
"to_date": to_date,
|
"to_date": to_date,
|
||||||
|
"finance_book": filters.get("finance_book")
|
||||||
}
|
}
|
||||||
|
|
||||||
if filters.get("include_default_book_entries"):
|
if filters.get("include_default_book_entries"):
|
||||||
|
@ -159,9 +159,7 @@ frappe.query_reports["General Ledger"] = {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
let dimension_filters = erpnext.get_dimension_filters();
|
erpnext.dimension_filters.then((dimensions) => {
|
||||||
|
|
||||||
dimension_filters.then((dimensions) => {
|
|
||||||
dimensions.forEach((dimension) => {
|
dimensions.forEach((dimension) => {
|
||||||
frappe.query_reports["General Ledger"].filters.splice(15, 0 ,{
|
frappe.query_reports["General Ledger"].filters.splice(15, 0 ,{
|
||||||
"fieldname": dimension["fieldname"],
|
"fieldname": dimension["fieldname"],
|
||||||
@ -171,4 +169,3 @@ dimension_filters.then((dimensions) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ def get_columns(group_wise_columns, filters):
|
|||||||
"warehouse": _("Warehouse") + ":Link/Warehouse",
|
"warehouse": _("Warehouse") + ":Link/Warehouse",
|
||||||
"qty": _("Qty") + ":Float",
|
"qty": _("Qty") + ":Float",
|
||||||
"base_rate": _("Avg. Selling Rate") + ":Currency/currency",
|
"base_rate": _("Avg. Selling Rate") + ":Currency/currency",
|
||||||
"buying_rate": _("Avg. Buying Rate") + ":Currency/currency",
|
"buying_rate": _("Valuation Rate") + ":Currency/currency",
|
||||||
"base_amount": _("Selling Amount") + ":Currency/currency",
|
"base_amount": _("Selling Amount") + ":Currency/currency",
|
||||||
"buying_amount": _("Buying Amount") + ":Currency/currency",
|
"buying_amount": _("Buying Amount") + ":Currency/currency",
|
||||||
"gross_profit": _("Gross Profit") + ":Currency/currency",
|
"gross_profit": _("Gross Profit") + ":Currency/currency",
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
{
|
{
|
||||||
"add_total_row": 0,
|
"add_total_row": 0,
|
||||||
"creation": "2019-05-01 13:46:23.044979",
|
"creation": "2019-05-01 12:59:52.018850",
|
||||||
"disable_prepared_report": 0,
|
"disable_prepared_report": 0,
|
||||||
"disabled": 0,
|
"disabled": 0,
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Report",
|
"doctype": "Report",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": "Yes",
|
"is_standard": "Yes",
|
||||||
"letter_head": "Test Letter Head 1",
|
"modified": "2019-05-01 13:00:26.545278",
|
||||||
"modified": "2019-05-01 13:46:23.044979",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Inactive Sales Items",
|
"name": "Inactive Sales Items",
|
||||||
@ -17,5 +16,15 @@
|
|||||||
"ref_doctype": "Sales Invoice",
|
"ref_doctype": "Sales Invoice",
|
||||||
"report_name": "Inactive Sales Items",
|
"report_name": "Inactive Sales Items",
|
||||||
"report_type": "Script Report",
|
"report_type": "Script Report",
|
||||||
"roles": []
|
"roles": [
|
||||||
|
{
|
||||||
|
"role": "Accounts User"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Accounts Manager"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Auditor"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
@ -102,9 +102,7 @@ def get_conditions(filters):
|
|||||||
("customer", " and `tabSales Invoice`.customer = %(customer)s"),
|
("customer", " and `tabSales Invoice`.customer = %(customer)s"),
|
||||||
("item_code", " and `tabSales Invoice Item`.item_code = %(item_code)s"),
|
("item_code", " and `tabSales Invoice Item`.item_code = %(item_code)s"),
|
||||||
("from_date", " and `tabSales Invoice`.posting_date>=%(from_date)s"),
|
("from_date", " and `tabSales Invoice`.posting_date>=%(from_date)s"),
|
||||||
("to_date", " and `tabSales Invoice`.posting_date<=%(to_date)s"),
|
("to_date", " and `tabSales Invoice`.posting_date<=%(to_date)s")):
|
||||||
("company_gstin", " and `tabSales Invoice`.company_gstin = %(company_gstin)s"),
|
|
||||||
("invoice_type", " and `tabSales Invoice`.invoice_type = %(invoice_type)s")):
|
|
||||||
if filters.get(opts[0]):
|
if filters.get(opts[0]):
|
||||||
conditions += opts[1]
|
conditions += opts[1]
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
"fieldname": "based_on",
|
"fieldname": "based_on",
|
||||||
"label": __("Based On"),
|
"label": __("Based On"),
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"options": "Cost Center\nProject",
|
"options": ["Cost Center", "Project"],
|
||||||
"default": "Cost Center",
|
"default": "Cost Center",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
@ -104,5 +104,10 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
"parent_field": "parent_account",
|
"parent_field": "parent_account",
|
||||||
"initial_depth": 3
|
"initial_depth": 3
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
|
erpnext.dimension_filters.then((dimensions) => {
|
||||||
|
dimensions.forEach((dimension) => {
|
||||||
|
frappe.query_reports["Profitability Analysis"].filters[1].options.push(dimension["document_type"]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -24,8 +24,17 @@ def get_accounts_data(based_on, company):
|
|||||||
if based_on == 'cost_center':
|
if based_on == 'cost_center':
|
||||||
return frappe.db.sql("""select name, parent_cost_center as parent_account, cost_center_name as account_name, lft, rgt
|
return frappe.db.sql("""select name, parent_cost_center as parent_account, cost_center_name as account_name, lft, rgt
|
||||||
from `tabCost Center` where company=%s order by name""", company, as_dict=True)
|
from `tabCost Center` where company=%s order by name""", company, as_dict=True)
|
||||||
else:
|
elif based_on == 'project':
|
||||||
return frappe.get_all('Project', fields = ["name"], filters = {'company': company}, order_by = 'name')
|
return frappe.get_all('Project', fields = ["name"], filters = {'company': company}, order_by = 'name')
|
||||||
|
else:
|
||||||
|
filters = {}
|
||||||
|
doctype = frappe.unscrub(based_on)
|
||||||
|
has_company = frappe.db.has_column(doctype, 'company')
|
||||||
|
|
||||||
|
if has_company:
|
||||||
|
filters.update({'company': company})
|
||||||
|
|
||||||
|
return frappe.get_all(doctype, fields = ["name"], filters = filters, order_by = 'name')
|
||||||
|
|
||||||
def get_data(accounts, filters, based_on):
|
def get_data(accounts, filters, based_on):
|
||||||
if not accounts:
|
if not accounts:
|
||||||
@ -42,7 +51,7 @@ def get_data(accounts, filters, based_on):
|
|||||||
accumulate_values_into_parents(accounts, accounts_by_name)
|
accumulate_values_into_parents(accounts, accounts_by_name)
|
||||||
|
|
||||||
data = prepare_data(accounts, filters, total_row, parent_children_map, based_on)
|
data = prepare_data(accounts, filters, total_row, parent_children_map, based_on)
|
||||||
data = filter_out_zero_value_rows(data, parent_children_map,
|
data = filter_out_zero_value_rows(data, parent_children_map,
|
||||||
show_zero_values=filters.get("show_zero_values"))
|
show_zero_values=filters.get("show_zero_values"))
|
||||||
|
|
||||||
return data
|
return data
|
||||||
@ -112,14 +121,14 @@ def prepare_data(accounts, filters, total_row, parent_children_map, based_on):
|
|||||||
|
|
||||||
for key in value_fields:
|
for key in value_fields:
|
||||||
row[key] = flt(d.get(key, 0.0), 3)
|
row[key] = flt(d.get(key, 0.0), 3)
|
||||||
|
|
||||||
if abs(row[key]) >= 0.005:
|
if abs(row[key]) >= 0.005:
|
||||||
# ignore zero values
|
# ignore zero values
|
||||||
has_value = True
|
has_value = True
|
||||||
|
|
||||||
row["has_value"] = has_value
|
row["has_value"] = has_value
|
||||||
data.append(row)
|
data.append(row)
|
||||||
|
|
||||||
data.extend([{},total_row])
|
data.extend([{},total_row])
|
||||||
|
|
||||||
return data
|
return data
|
||||||
@ -174,7 +183,7 @@ def set_gl_entries_by_account(company, from_date, to_date, based_on, gl_entries_
|
|||||||
if from_date:
|
if from_date:
|
||||||
additional_conditions.append("and posting_date >= %(from_date)s")
|
additional_conditions.append("and posting_date >= %(from_date)s")
|
||||||
|
|
||||||
gl_entries = frappe.db.sql("""select posting_date, {based_on} as based_on, debit, credit,
|
gl_entries = frappe.db.sql("""select posting_date, {based_on} as based_on, debit, credit,
|
||||||
is_opening, (select root_type from `tabAccount` where name = account) as type
|
is_opening, (select root_type from `tabAccount` where name = account) as type
|
||||||
from `tabGL Entry` where company=%(company)s
|
from `tabGL Entry` where company=%(company)s
|
||||||
{additional_conditions}
|
{additional_conditions}
|
||||||
|
@ -67,3 +67,14 @@ frappe.query_reports["Sales Register"] = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
erpnext.dimension_filters.then((dimensions) => {
|
||||||
|
dimensions.forEach((dimension) => {
|
||||||
|
frappe.query_reports["Sales Register"].filters.splice(7, 0 ,{
|
||||||
|
"fieldname": dimension["fieldname"],
|
||||||
|
"label": __(dimension["label"]),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": dimension["document_type"]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
from frappe import msgprint, _
|
from frappe import msgprint, _
|
||||||
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
return _execute(filters)
|
return _execute(filters)
|
||||||
@ -157,12 +158,22 @@ def get_conditions(filters):
|
|||||||
conditions += """ and exists(select name from `tabSales Invoice Item`
|
conditions += """ and exists(select name from `tabSales Invoice Item`
|
||||||
where parent=`tabSales Invoice`.name
|
where parent=`tabSales Invoice`.name
|
||||||
and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s)"""
|
and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s)"""
|
||||||
|
|
||||||
if filters.get("item_group"):
|
if filters.get("item_group"):
|
||||||
conditions += """ and exists(select name from `tabSales Invoice Item`
|
conditions += """ and exists(select name from `tabSales Invoice Item`
|
||||||
where parent=`tabSales Invoice`.name
|
where parent=`tabSales Invoice`.name
|
||||||
and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s)"""
|
and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s)"""
|
||||||
|
|
||||||
|
accounting_dimensions = get_accounting_dimensions()
|
||||||
|
|
||||||
|
if accounting_dimensions:
|
||||||
|
for dimension in accounting_dimensions:
|
||||||
|
if filters.get(dimension):
|
||||||
|
conditions += """ and exists(select name from `tabSales Invoice Item`
|
||||||
|
where parent=`tabSales Invoice`.name
|
||||||
|
and ifnull(`tabSales Invoice Item`.{0}, '') = %({0})s)""".format(dimension)
|
||||||
|
|
||||||
|
|
||||||
return conditions
|
return conditions
|
||||||
|
|
||||||
def get_invoices(filters, additional_query_columns):
|
def get_invoices(filters, additional_query_columns):
|
||||||
@ -171,7 +182,7 @@ def get_invoices(filters, additional_query_columns):
|
|||||||
|
|
||||||
conditions = get_conditions(filters)
|
conditions = get_conditions(filters)
|
||||||
return frappe.db.sql("""
|
return frappe.db.sql("""
|
||||||
select name, posting_date, debit_to, project, customer,
|
select name, posting_date, debit_to, project, customer,
|
||||||
customer_name, owner, remarks, territory, tax_id, customer_group,
|
customer_name, owner, remarks, territory, tax_id, customer_group,
|
||||||
base_net_total, base_grand_total, base_rounded_total, outstanding_amount {0}
|
base_net_total, base_grand_total, base_rounded_total, outstanding_amount {0}
|
||||||
from `tabSales Invoice`
|
from `tabSales Invoice`
|
||||||
|
@ -96,3 +96,14 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
erpnext.dimension_filters.then((dimensions) => {
|
||||||
|
dimensions.forEach((dimension) => {
|
||||||
|
frappe.query_reports["Trial Balance"].filters.splice(5, 0 ,{
|
||||||
|
"fieldname": dimension["fieldname"],
|
||||||
|
"label": __(dimension["label"]),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": dimension["document_type"]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ from frappe import _
|
|||||||
from frappe.utils import flt, getdate, formatdate, cstr
|
from frappe.utils import flt, getdate, formatdate, cstr
|
||||||
from erpnext.accounts.report.financial_statements \
|
from erpnext.accounts.report.financial_statements \
|
||||||
import filter_accounts, set_gl_entries_by_account, filter_out_zero_value_rows
|
import filter_accounts, set_gl_entries_by_account, filter_out_zero_value_rows
|
||||||
|
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
|
||||||
|
|
||||||
value_fields = ("opening_debit", "opening_credit", "debit", "credit", "closing_debit", "closing_credit")
|
value_fields = ("opening_debit", "opening_credit", "debit", "credit", "closing_debit", "closing_credit")
|
||||||
|
|
||||||
@ -109,6 +110,25 @@ def get_rootwise_opening_balances(filters, report_type):
|
|||||||
|
|
||||||
additional_conditions += fb_conditions
|
additional_conditions += fb_conditions
|
||||||
|
|
||||||
|
accounting_dimensions = get_accounting_dimensions()
|
||||||
|
|
||||||
|
query_filters = {
|
||||||
|
"company": filters.company,
|
||||||
|
"from_date": filters.from_date,
|
||||||
|
"report_type": report_type,
|
||||||
|
"year_start_date": filters.year_start_date,
|
||||||
|
"finance_book": filters.finance_book,
|
||||||
|
"company_fb": frappe.db.get_value("Company", filters.company, 'default_finance_book')
|
||||||
|
}
|
||||||
|
|
||||||
|
if accounting_dimensions:
|
||||||
|
for dimension in accounting_dimensions:
|
||||||
|
additional_conditions += """ and {0} in (%({0})s) """.format(dimension)
|
||||||
|
|
||||||
|
query_filters.update({
|
||||||
|
dimension: filters.get(dimension)
|
||||||
|
})
|
||||||
|
|
||||||
gle = frappe.db.sql("""
|
gle = frappe.db.sql("""
|
||||||
select
|
select
|
||||||
account, sum(debit) as opening_debit, sum(credit) as opening_credit
|
account, sum(debit) as opening_debit, sum(credit) as opening_credit
|
||||||
@ -118,16 +138,7 @@ def get_rootwise_opening_balances(filters, report_type):
|
|||||||
{additional_conditions}
|
{additional_conditions}
|
||||||
and (posting_date < %(from_date)s or ifnull(is_opening, 'No') = 'Yes')
|
and (posting_date < %(from_date)s or ifnull(is_opening, 'No') = 'Yes')
|
||||||
and account in (select name from `tabAccount` where report_type=%(report_type)s)
|
and account in (select name from `tabAccount` where report_type=%(report_type)s)
|
||||||
group by account""".format(additional_conditions=additional_conditions),
|
group by account""".format(additional_conditions=additional_conditions), query_filters , as_dict=True)
|
||||||
{
|
|
||||||
"company": filters.company,
|
|
||||||
"from_date": filters.from_date,
|
|
||||||
"report_type": report_type,
|
|
||||||
"year_start_date": filters.year_start_date,
|
|
||||||
"finance_book": filters.finance_book,
|
|
||||||
"company_fb": frappe.db.get_value("Company", filters.company, 'default_finance_book')
|
|
||||||
},
|
|
||||||
as_dict=True)
|
|
||||||
|
|
||||||
opening = frappe._dict()
|
opening = frappe._dict()
|
||||||
for d in gle:
|
for d in gle:
|
||||||
|
@ -435,7 +435,7 @@ def update_reference_in_journal_entry(d, jv_obj):
|
|||||||
jv_obj.flags.ignore_validate_update_after_submit = True
|
jv_obj.flags.ignore_validate_update_after_submit = True
|
||||||
jv_obj.save(ignore_permissions=True)
|
jv_obj.save(ignore_permissions=True)
|
||||||
|
|
||||||
def update_reference_in_payment_entry(d, payment_entry):
|
def update_reference_in_payment_entry(d, payment_entry, do_not_save=False):
|
||||||
reference_details = {
|
reference_details = {
|
||||||
"reference_doctype": d.against_voucher_type,
|
"reference_doctype": d.against_voucher_type,
|
||||||
"reference_name": d.against_voucher,
|
"reference_name": d.against_voucher,
|
||||||
@ -466,7 +466,17 @@ def update_reference_in_payment_entry(d, payment_entry):
|
|||||||
payment_entry.setup_party_account_field()
|
payment_entry.setup_party_account_field()
|
||||||
payment_entry.set_missing_values()
|
payment_entry.set_missing_values()
|
||||||
payment_entry.set_amounts()
|
payment_entry.set_amounts()
|
||||||
payment_entry.save(ignore_permissions=True)
|
|
||||||
|
if d.difference_amount and d.difference_account:
|
||||||
|
payment_entry.set_gain_or_loss(account_details={
|
||||||
|
'account': d.difference_account,
|
||||||
|
'cost_center': payment_entry.cost_center or frappe.get_cached_value('Company',
|
||||||
|
payment_entry.company, "cost_center"),
|
||||||
|
'amount': d.difference_amount
|
||||||
|
})
|
||||||
|
|
||||||
|
if not do_not_save:
|
||||||
|
payment_entry.save(ignore_permissions=True)
|
||||||
|
|
||||||
def unlink_ref_doc_from_payment_entries(ref_doc):
|
def unlink_ref_doc_from_payment_entries(ref_doc):
|
||||||
remove_ref_doc_link_from_jv(ref_doc.doctype, ref_doc.name)
|
remove_ref_doc_link_from_jv(ref_doc.doctype, ref_doc.name)
|
||||||
@ -618,7 +628,7 @@ def get_held_invoices(party_type, party):
|
|||||||
return held_invoices
|
return held_invoices
|
||||||
|
|
||||||
|
|
||||||
def get_outstanding_invoices(party_type, party, account, condition=None, limit=None):
|
def get_outstanding_invoices(party_type, party, account, condition=None, filters=None):
|
||||||
outstanding_invoices = []
|
outstanding_invoices = []
|
||||||
precision = frappe.get_precision("Sales Invoice", "outstanding_amount") or 2
|
precision = frappe.get_precision("Sales Invoice", "outstanding_amount") or 2
|
||||||
|
|
||||||
@ -631,11 +641,11 @@ def get_outstanding_invoices(party_type, party, account, condition=None, limit=N
|
|||||||
|
|
||||||
invoice = 'Sales Invoice' if erpnext.get_party_account_type(party_type) == 'Receivable' else 'Purchase Invoice'
|
invoice = 'Sales Invoice' if erpnext.get_party_account_type(party_type) == 'Receivable' else 'Purchase Invoice'
|
||||||
held_invoices = get_held_invoices(party_type, party)
|
held_invoices = get_held_invoices(party_type, party)
|
||||||
limit_cond = "limit %s" % limit if limit else ""
|
|
||||||
|
|
||||||
invoice_list = frappe.db.sql("""
|
invoice_list = frappe.db.sql("""
|
||||||
select
|
select
|
||||||
voucher_no, voucher_type, posting_date, ifnull(sum({dr_or_cr}), 0) as invoice_amount
|
voucher_no, voucher_type, posting_date, due_date,
|
||||||
|
ifnull(sum({dr_or_cr}), 0) as invoice_amount
|
||||||
from
|
from
|
||||||
`tabGL Entry`
|
`tabGL Entry`
|
||||||
where
|
where
|
||||||
@ -646,11 +656,10 @@ def get_outstanding_invoices(party_type, party, account, condition=None, limit=N
|
|||||||
and (against_voucher = '' or against_voucher is null))
|
and (against_voucher = '' or against_voucher is null))
|
||||||
or (voucher_type not in ('Journal Entry', 'Payment Entry')))
|
or (voucher_type not in ('Journal Entry', 'Payment Entry')))
|
||||||
group by voucher_type, voucher_no
|
group by voucher_type, voucher_no
|
||||||
order by posting_date, name {limit_cond}""".format(
|
order by posting_date, name""".format(
|
||||||
dr_or_cr=dr_or_cr,
|
dr_or_cr=dr_or_cr,
|
||||||
invoice = invoice,
|
invoice = invoice,
|
||||||
condition=condition or "",
|
condition=condition or ""
|
||||||
limit_cond = limit_cond
|
|
||||||
), {
|
), {
|
||||||
"party_type": party_type,
|
"party_type": party_type,
|
||||||
"party": party,
|
"party": party,
|
||||||
@ -669,7 +678,7 @@ def get_outstanding_invoices(party_type, party, account, condition=None, limit=N
|
|||||||
""".format(payment_dr_or_cr=payment_dr_or_cr), {
|
""".format(payment_dr_or_cr=payment_dr_or_cr), {
|
||||||
"party_type": party_type,
|
"party_type": party_type,
|
||||||
"party": party,
|
"party": party,
|
||||||
"account": account,
|
"account": account
|
||||||
}, as_dict=True)
|
}, as_dict=True)
|
||||||
|
|
||||||
pe_map = frappe._dict()
|
pe_map = frappe._dict()
|
||||||
@ -680,10 +689,12 @@ def get_outstanding_invoices(party_type, party, account, condition=None, limit=N
|
|||||||
payment_amount = pe_map.get((d.voucher_type, d.voucher_no), 0)
|
payment_amount = pe_map.get((d.voucher_type, d.voucher_no), 0)
|
||||||
outstanding_amount = flt(d.invoice_amount - payment_amount, precision)
|
outstanding_amount = flt(d.invoice_amount - payment_amount, precision)
|
||||||
if outstanding_amount > 0.5 / (10**precision):
|
if outstanding_amount > 0.5 / (10**precision):
|
||||||
if not d.voucher_type == "Purchase Invoice" or d.voucher_no not in held_invoices:
|
if (filters.get("outstanding_amt_greater_than") and
|
||||||
due_date = frappe.db.get_value(
|
not (outstanding_amount >= filters.get("outstanding_amt_greater_than") and
|
||||||
d.voucher_type, d.voucher_no, "posting_date" if party_type == "Employee" else "due_date")
|
outstanding_amount <= filters.get("outstanding_amt_less_than"))):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not d.voucher_type == "Purchase Invoice" or d.voucher_no not in held_invoices:
|
||||||
outstanding_invoices.append(
|
outstanding_invoices.append(
|
||||||
frappe._dict({
|
frappe._dict({
|
||||||
'voucher_no': d.voucher_no,
|
'voucher_no': d.voucher_no,
|
||||||
@ -692,7 +703,7 @@ def get_outstanding_invoices(party_type, party, account, condition=None, limit=N
|
|||||||
'invoice_amount': flt(d.invoice_amount),
|
'invoice_amount': flt(d.invoice_amount),
|
||||||
'payment_amount': payment_amount,
|
'payment_amount': payment_amount,
|
||||||
'outstanding_amount': outstanding_amount,
|
'outstanding_amount': outstanding_amount,
|
||||||
'due_date': due_date
|
'due_date': d.due_date
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,497 +1,497 @@
|
|||||||
{
|
{
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
"creation": "2016-03-01 17:01:27.920130",
|
"creation": "2016-03-01 17:01:27.920130",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Document",
|
"document_type": "Document",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"naming_series",
|
"naming_series",
|
||||||
"asset_name",
|
"asset_name",
|
||||||
"item_code",
|
"item_code",
|
||||||
"item_name",
|
"item_name",
|
||||||
"asset_category",
|
"asset_category",
|
||||||
"asset_owner",
|
"asset_owner",
|
||||||
"asset_owner_company",
|
"asset_owner_company",
|
||||||
"supplier",
|
"supplier",
|
||||||
"customer",
|
"customer",
|
||||||
"image",
|
"image",
|
||||||
"column_break_3",
|
"column_break_3",
|
||||||
"company",
|
"company",
|
||||||
"location",
|
"location",
|
||||||
"custodian",
|
"custodian",
|
||||||
"department",
|
"department",
|
||||||
"purchase_date",
|
"purchase_date",
|
||||||
"disposal_date",
|
"disposal_date",
|
||||||
"journal_entry_for_scrap",
|
"journal_entry_for_scrap",
|
||||||
"accounting_dimensions_section",
|
"accounting_dimensions_section",
|
||||||
"cost_center",
|
"cost_center",
|
||||||
"dimension_col_break",
|
"dimension_col_break",
|
||||||
"section_break_5",
|
"section_break_5",
|
||||||
"gross_purchase_amount",
|
"gross_purchase_amount",
|
||||||
"available_for_use_date",
|
"available_for_use_date",
|
||||||
"column_break_18",
|
"column_break_18",
|
||||||
"calculate_depreciation",
|
"calculate_depreciation",
|
||||||
"is_existing_asset",
|
"is_existing_asset",
|
||||||
"opening_accumulated_depreciation",
|
"opening_accumulated_depreciation",
|
||||||
"number_of_depreciations_booked",
|
"number_of_depreciations_booked",
|
||||||
"section_break_23",
|
"section_break_23",
|
||||||
"finance_books",
|
"finance_books",
|
||||||
"section_break_33",
|
"section_break_33",
|
||||||
"depreciation_method",
|
"depreciation_method",
|
||||||
"value_after_depreciation",
|
"value_after_depreciation",
|
||||||
"total_number_of_depreciations",
|
"total_number_of_depreciations",
|
||||||
"column_break_24",
|
"column_break_24",
|
||||||
"frequency_of_depreciation",
|
"frequency_of_depreciation",
|
||||||
"next_depreciation_date",
|
"next_depreciation_date",
|
||||||
"section_break_14",
|
"section_break_14",
|
||||||
"schedules",
|
"schedules",
|
||||||
"insurance_details",
|
"insurance_details",
|
||||||
"policy_number",
|
"policy_number",
|
||||||
"insurer",
|
"insurer",
|
||||||
"insured_value",
|
"insured_value",
|
||||||
"column_break_48",
|
"column_break_48",
|
||||||
"insurance_start_date",
|
"insurance_start_date",
|
||||||
"insurance_end_date",
|
"insurance_end_date",
|
||||||
"comprehensive_insurance",
|
"comprehensive_insurance",
|
||||||
"section_break_31",
|
"section_break_31",
|
||||||
"maintenance_required",
|
"maintenance_required",
|
||||||
"other_details",
|
"other_details",
|
||||||
"status",
|
"status",
|
||||||
"booked_fixed_asset",
|
"booked_fixed_asset",
|
||||||
"column_break_51",
|
"column_break_51",
|
||||||
"purchase_receipt",
|
"purchase_receipt",
|
||||||
"purchase_receipt_amount",
|
"purchase_receipt_amount",
|
||||||
"purchase_invoice",
|
"purchase_invoice",
|
||||||
"default_finance_book",
|
"default_finance_book",
|
||||||
"amended_from"
|
"amended_from"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"fieldname": "naming_series",
|
"fieldname": "naming_series",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Naming Series",
|
"label": "Naming Series",
|
||||||
"options": "ACC-ASS-.YYYY.-"
|
"options": "ACC-ASS-.YYYY.-"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "asset_name",
|
"fieldname": "asset_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Asset Name",
|
"label": "Asset Name",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "item_code",
|
"fieldname": "item_code",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Item Code",
|
"label": "Item Code",
|
||||||
"options": "Item",
|
"options": "Item",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "item_code.item_name",
|
"fetch_from": "item_code.item_name",
|
||||||
"fieldname": "item_name",
|
"fieldname": "item_name",
|
||||||
"fieldtype": "Read Only",
|
"fieldtype": "Read Only",
|
||||||
"label": "Item Name"
|
"label": "Item Name"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "item_code.asset_category",
|
"fetch_from": "item_code.asset_category",
|
||||||
"fieldname": "asset_category",
|
"fieldname": "asset_category",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_global_search": 1,
|
"in_global_search": 1,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Asset Category",
|
"label": "Asset Category",
|
||||||
"options": "Asset Category",
|
"options": "Asset Category",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "asset_owner",
|
"fieldname": "asset_owner",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Asset Owner",
|
"label": "Asset Owner",
|
||||||
"options": "\nCompany\nSupplier\nCustomer"
|
"options": "\nCompany\nSupplier\nCustomer"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.asset_owner == \"Company\"",
|
"depends_on": "eval:doc.asset_owner == \"Company\"",
|
||||||
"fieldname": "asset_owner_company",
|
"fieldname": "asset_owner_company",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Asset Owner Company",
|
"label": "Asset Owner Company",
|
||||||
"options": "Company"
|
"options": "Company"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.asset_owner == \"Supplier\"",
|
"depends_on": "eval:doc.asset_owner == \"Supplier\"",
|
||||||
"fieldname": "supplier",
|
"fieldname": "supplier",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Supplier",
|
"label": "Supplier",
|
||||||
"options": "Supplier"
|
"options": "Supplier"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:doc.asset_owner == \"Customer\"",
|
"depends_on": "eval:doc.asset_owner == \"Customer\"",
|
||||||
"fieldname": "customer",
|
"fieldname": "customer",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Customer",
|
"label": "Customer",
|
||||||
"options": "Customer"
|
"options": "Customer"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"fieldname": "image",
|
"fieldname": "image",
|
||||||
"fieldtype": "Attach Image",
|
"fieldtype": "Attach Image",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Image",
|
"label": "Image",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_3",
|
"fieldname": "column_break_3",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "company",
|
"fieldname": "company",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Company",
|
"label": "Company",
|
||||||
"options": "Company",
|
"options": "Company",
|
||||||
"remember_last_selected_value": 1,
|
"remember_last_selected_value": 1,
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "location",
|
"fieldname": "location",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Location",
|
"label": "Location",
|
||||||
"options": "Location",
|
"options": "Location",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "custodian",
|
"fieldname": "custodian",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"ignore_user_permissions": 1,
|
"ignore_user_permissions": 1,
|
||||||
"label": "Custodian",
|
"label": "Custodian",
|
||||||
"options": "Employee"
|
"options": "Employee"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "cost_center",
|
"fieldname": "cost_center",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Cost Center",
|
"label": "Cost Center",
|
||||||
"options": "Cost Center"
|
"options": "Cost Center"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "department",
|
"fieldname": "department",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Department",
|
"label": "Department",
|
||||||
"options": "Department"
|
"options": "Department"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "purchase_date",
|
"fieldname": "purchase_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Purchase Date",
|
"label": "Purchase Date",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "disposal_date",
|
"fieldname": "disposal_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Disposal Date",
|
"label": "Disposal Date",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "journal_entry_for_scrap",
|
"fieldname": "journal_entry_for_scrap",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Journal Entry for Scrap",
|
"label": "Journal Entry for Scrap",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Journal Entry",
|
"options": "Journal Entry",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "section_break_5",
|
"fieldname": "section_break_5",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "gross_purchase_amount",
|
"fieldname": "gross_purchase_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Gross Purchase Amount",
|
"label": "Gross Purchase Amount",
|
||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "available_for_use_date",
|
"fieldname": "available_for_use_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Available-for-use Date"
|
"label": "Available-for-use Date"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_18",
|
"fieldname": "column_break_18",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "calculate_depreciation",
|
"fieldname": "calculate_depreciation",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Calculate Depreciation"
|
"label": "Calculate Depreciation"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "is_existing_asset",
|
"fieldname": "is_existing_asset",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Is Existing Asset"
|
"label": "Is Existing Asset"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "is_existing_asset",
|
"depends_on": "is_existing_asset",
|
||||||
"fieldname": "opening_accumulated_depreciation",
|
"fieldname": "opening_accumulated_depreciation",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Opening Accumulated Depreciation",
|
"label": "Opening Accumulated Depreciation",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Company:company:default_currency"
|
"options": "Company:company:default_currency"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:(doc.is_existing_asset && doc.opening_accumulated_depreciation)",
|
"depends_on": "eval:(doc.is_existing_asset && doc.opening_accumulated_depreciation)",
|
||||||
"fieldname": "number_of_depreciations_booked",
|
"fieldname": "number_of_depreciations_booked",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"label": "Number of Depreciations Booked",
|
"label": "Number of Depreciations Booked",
|
||||||
"no_copy": 1
|
"no_copy": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "calculate_depreciation",
|
"depends_on": "calculate_depreciation",
|
||||||
"fieldname": "section_break_23",
|
"fieldname": "section_break_23",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Depreciation"
|
"label": "Depreciation"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "finance_books",
|
"fieldname": "finance_books",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Finance Books",
|
"label": "Finance Books",
|
||||||
"options": "Asset Finance Book"
|
"options": "Asset Finance Book"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "section_break_33",
|
"fieldname": "section_break_33",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 1
|
"hidden": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "depreciation_method",
|
"fieldname": "depreciation_method",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Depreciation Method",
|
"label": "Depreciation Method",
|
||||||
"options": "\nStraight Line\nDouble Declining Balance\nManual"
|
"options": "\nStraight Line\nDouble Declining Balance\nManual"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "value_after_depreciation",
|
"fieldname": "value_after_depreciation",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Value After Depreciation",
|
"label": "Value After Depreciation",
|
||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "total_number_of_depreciations",
|
"fieldname": "total_number_of_depreciations",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"label": "Total Number of Depreciations"
|
"label": "Total Number of Depreciations"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_24",
|
"fieldname": "column_break_24",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "frequency_of_depreciation",
|
"fieldname": "frequency_of_depreciation",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"label": "Frequency of Depreciation (Months)"
|
"label": "Frequency of Depreciation (Months)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "next_depreciation_date",
|
"fieldname": "next_depreciation_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Next Depreciation Date",
|
"label": "Next Depreciation Date",
|
||||||
"no_copy": 1
|
"no_copy": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "calculate_depreciation",
|
"depends_on": "calculate_depreciation",
|
||||||
"fieldname": "section_break_14",
|
"fieldname": "section_break_14",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Depreciation Schedule"
|
"label": "Depreciation Schedule"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "schedules",
|
"fieldname": "schedules",
|
||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Depreciation Schedules",
|
"label": "Depreciation Schedules",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Depreciation Schedule"
|
"options": "Depreciation Schedule"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"fieldname": "insurance_details",
|
"fieldname": "insurance_details",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Insurance details"
|
"label": "Insurance details"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "policy_number",
|
"fieldname": "policy_number",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Policy number"
|
"label": "Policy number"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "insurer",
|
"fieldname": "insurer",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Insurer"
|
"label": "Insurer"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "insured_value",
|
"fieldname": "insured_value",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Insured value"
|
"label": "Insured value"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_48",
|
"fieldname": "column_break_48",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "insurance_start_date",
|
"fieldname": "insurance_start_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Insurance Start Date"
|
"label": "Insurance Start Date"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "insurance_end_date",
|
"fieldname": "insurance_end_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Insurance End Date"
|
"label": "Insurance End Date"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "comprehensive_insurance",
|
"fieldname": "comprehensive_insurance",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Comprehensive Insurance"
|
"label": "Comprehensive Insurance"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "section_break_31",
|
"fieldname": "section_break_31",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Maintenance"
|
"label": "Maintenance"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"description": "Check if Asset requires Preventive Maintenance or Calibration",
|
"description": "Check if Asset requires Preventive Maintenance or Calibration",
|
||||||
"fieldname": "maintenance_required",
|
"fieldname": "maintenance_required",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Maintenance Required"
|
"label": "Maintenance Required"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"fieldname": "other_details",
|
"fieldname": "other_details",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Other Details"
|
"label": "Other Details"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"default": "Draft",
|
"default": "Draft",
|
||||||
"fieldname": "status",
|
"fieldname": "status",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 1,
|
"in_standard_filter": 1,
|
||||||
"label": "Status",
|
"label": "Status",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Draft\nSubmitted\nPartially Depreciated\nFully Depreciated\nSold\nScrapped\nIn Maintenance\nOut of Order\nIssue\nReceipt",
|
"options": "Draft\nSubmitted\nPartially Depreciated\nFully Depreciated\nSold\nScrapped\nIn Maintenance\nOut of Order\nIssue\nReceipt",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "booked_fixed_asset",
|
"fieldname": "booked_fixed_asset",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Booked Fixed Asset",
|
"label": "Booked Fixed Asset",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_51",
|
"fieldname": "column_break_51",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "purchase_receipt",
|
"fieldname": "purchase_receipt",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Purchase Receipt",
|
"label": "Purchase Receipt",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Purchase Receipt",
|
"options": "Purchase Receipt",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "purchase_receipt_amount",
|
"fieldname": "purchase_receipt_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Purchase Receipt Amount",
|
"label": "Purchase Receipt Amount",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "purchase_invoice",
|
"fieldname": "purchase_invoice",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Purchase Invoice",
|
"label": "Purchase Invoice",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Purchase Invoice",
|
"options": "Purchase Invoice",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "company.default_finance_book",
|
"fetch_from": "company.default_finance_book",
|
||||||
"fieldname": "default_finance_book",
|
"fieldname": "default_finance_book",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 1,
|
"hidden": 1,
|
||||||
"label": "Default Finance Book",
|
"label": "Default Finance Book",
|
||||||
"options": "Finance Book",
|
"options": "Finance Book",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "amended_from",
|
"fieldname": "amended_from",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Amended From",
|
"label": "Amended From",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"options": "Asset",
|
"options": "Asset",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"collapsible": 1,
|
"collapsible": 1,
|
||||||
"fieldname": "accounting_dimensions_section",
|
"fieldname": "accounting_dimensions_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Accounting Dimensions"
|
"label": "Accounting Dimensions"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "dimension_col_break",
|
"fieldname": "dimension_col_break",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"idx": 72,
|
"idx": 72,
|
||||||
"image_field": "image",
|
"image_field": "image",
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"modified": "2019-05-25 22:26:19.786201",
|
"modified": "2019-05-25 22:26:19.786201",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Assets",
|
"module": "Assets",
|
||||||
"name": "Asset",
|
"name": "Asset",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 1,
|
"amend": 1,
|
||||||
"cancel": 1,
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"import": 1,
|
"import": 1,
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Accounts User",
|
"role": "Accounts User",
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 1,
|
"submit": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cancel": 1,
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Quality Manager",
|
"role": "Quality Manager",
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 1,
|
"submit": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"show_name_in_global_search": 1,
|
"show_name_in_global_search": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"title_field": "asset_name"
|
"title_field": "asset_name"
|
||||||
}
|
}
|
@ -1,3 +1,37 @@
|
|||||||
frappe.listview_settings['Asset'] = {
|
frappe.listview_settings['Asset'] = {
|
||||||
add_fields: ['image']
|
add_fields: ['status'],
|
||||||
|
get_indicator: function (doc) {
|
||||||
|
if (doc.status === "Fully Depreciated") {
|
||||||
|
return [__("Fully Depreciated"), "green", "status,=,Fully Depreciated"];
|
||||||
|
|
||||||
|
} else if (doc.status === "Partially Depreciated") {
|
||||||
|
return [__("Partially Depreciated"), "grey", "status,=,Partially Depreciated"];
|
||||||
|
|
||||||
|
} else if (doc.status === "Sold") {
|
||||||
|
return [__("Sold"), "green", "status,=,Sold"];
|
||||||
|
|
||||||
|
} else if (doc.status === "Scrapped") {
|
||||||
|
return [__("Scrapped"), "grey", "status,=,Scrapped"];
|
||||||
|
|
||||||
|
} else if (doc.status === "In Maintenance") {
|
||||||
|
return [__("In Maintenance"), "orange", "status,=,In Maintenance"];
|
||||||
|
|
||||||
|
} else if (doc.status === "Out of Order") {
|
||||||
|
return [__("Out of Order"), "grey", "status,=,Out of Order"];
|
||||||
|
|
||||||
|
} else if (doc.status === "Issue") {
|
||||||
|
return [__("Issue"), "orange", "status,=,Issue"];
|
||||||
|
|
||||||
|
} else if (doc.status === "Receipt") {
|
||||||
|
return [__("Receipt"), "green", "status,=,Receipt"];
|
||||||
|
|
||||||
|
} else if (doc.status === "Submitted") {
|
||||||
|
return [__("Submitted"), "blue", "status,=,Submitted"];
|
||||||
|
|
||||||
|
} else if (doc.status === "Draft") {
|
||||||
|
return [__("Draft"), "red", "status,=,Draft"];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user