Compare commits
181 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea75295bb3 | ||
|
|
d2c643eb0b | ||
|
|
94fcb0e9f9 | ||
|
|
3362d6b948 | ||
|
|
75c1682e61 | ||
|
|
2dc8972794 | ||
|
|
f786eccdf9 | ||
|
|
a1036ad50b | ||
|
|
5b34d00bc0 | ||
|
|
ee3b788024 | ||
|
|
b509b06edf | ||
|
|
5fcccda883 | ||
|
|
4fb9230d16 | ||
|
|
37d3686372 | ||
|
|
5eafa5a487 | ||
|
|
97dbb4d125 | ||
|
|
17ac38ff29 | ||
|
|
65652071ff | ||
|
|
79dc8ac9cc | ||
|
|
15e7646edd | ||
|
|
d1b87ba41c | ||
|
|
a5576f5b21 | ||
|
|
8976ad5ca1 | ||
|
|
c7f8b82fff | ||
|
|
6b62b86bbf | ||
|
|
8fbf856618 | ||
|
|
7d6d678e8d | ||
|
|
c22ba2ec26 | ||
|
|
0cf0ebf08b | ||
|
|
0ff35a852a | ||
|
|
e04431ea5c | ||
|
|
fafc277666 | ||
|
|
fe1e4a41e6 | ||
|
|
7a8c5b0c2c | ||
|
|
056ecdca6a | ||
|
|
3b281a0a1b | ||
|
|
a60ab1af75 | ||
|
|
550fc695f1 | ||
|
|
013493de7a | ||
|
|
b3737c812a | ||
|
|
6d5a29af6a | ||
|
|
20d8c52d2a | ||
|
|
e11f299b21 | ||
|
|
68000c66fc | ||
|
|
3cc77b52e7 | ||
|
|
bd4348db10 | ||
|
|
4fd1cebf95 | ||
|
|
b892cc8b02 | ||
|
|
8652bce9e3 | ||
|
|
4e372a30fa | ||
|
|
df327f2974 | ||
|
|
3ccbb8f8b7 | ||
|
|
0d931e1d7d | ||
|
|
431b4fba72 | ||
|
|
fba985d49d | ||
|
|
4bd562d669 | ||
|
|
bb88e964a4 | ||
|
|
5f79479bd0 | ||
|
|
12b4096e68 | ||
|
|
1ef72c0b66 | ||
|
|
648191b9e8 | ||
|
|
624927bf0b | ||
|
|
3df2639a32 | ||
|
|
d982e8fcda | ||
|
|
af497ef669 | ||
|
|
79f3ea4094 | ||
|
|
e0a47aeb2f | ||
|
|
1516b8d54a | ||
|
|
e33047250e | ||
|
|
c4e38ffd4d | ||
|
|
be7703387d | ||
|
|
b800382abf | ||
|
|
e689a903d8 | ||
|
|
ecc6af9d2a | ||
|
|
5c5688b374 | ||
|
|
80f30094fb | ||
|
|
6fb2117767 | ||
|
|
0631aed3d9 | ||
|
|
88b0a1305f | ||
|
|
9e98fdfc6e | ||
|
|
cd6b955b99 | ||
|
|
bfd26b7084 | ||
|
|
18960c7757 | ||
|
|
9a7838265d | ||
|
|
57d3c93e6b | ||
|
|
a0b846fb88 | ||
|
|
8356d4b892 | ||
|
|
ba62013cbb | ||
|
|
59de1dae6a | ||
|
|
91cecf8eac | ||
|
|
6ec558bd59 | ||
|
|
11dd3ffdb5 | ||
|
|
f0ef673498 | ||
|
|
57d07d6b8e | ||
|
|
fc682c86c6 | ||
|
|
15f52e7b71 | ||
|
|
26bfede116 | ||
|
|
86217ca96c | ||
|
|
ae4ff5a403 | ||
|
|
0452b405f4 | ||
|
|
dc7004e083 | ||
|
|
ebdefade9b | ||
|
|
e9afbfde76 | ||
|
|
086da451ca | ||
|
|
91d2ace9bb | ||
|
|
91a9ee5179 | ||
|
|
11137850cb | ||
|
|
584153a1b1 | ||
|
|
eed0a4e2df | ||
|
|
f5cc1bd44c | ||
|
|
cc56ff5c37 | ||
|
|
20d3bef3c3 | ||
|
|
1f4c263a63 | ||
|
|
d0a2b1619b | ||
|
|
0fe6ced99d | ||
|
|
e50e0e4b30 | ||
|
|
cd717e422f | ||
|
|
6b862fcae5 | ||
|
|
a22e0d0c99 | ||
|
|
8ca5940f76 | ||
|
|
6c46b4edc4 | ||
|
|
8395a7ad6f | ||
|
|
6863b03790 | ||
|
|
a76067eea1 | ||
|
|
216f9373c9 | ||
|
|
5fe88ea93e | ||
|
|
fbeab5bf73 | ||
|
|
a3e070bc6b | ||
|
|
3ffe89659a | ||
|
|
5c3b69476d | ||
|
|
da17ceea73 | ||
|
|
2d84945839 | ||
|
|
8dc4c945dc | ||
|
|
cc9c7d5e2a | ||
|
|
07d0e9a2b2 | ||
|
|
f38d6d9c44 | ||
|
|
07bb1811af | ||
|
|
f07462860b | ||
|
|
720b06495c | ||
|
|
83ad646af4 | ||
|
|
8179bcbabd | ||
|
|
6be8bea934 | ||
|
|
0b9129e519 | ||
|
|
778e06d0ee | ||
|
|
3f5e80ebe3 | ||
|
|
ea943c6fe4 | ||
|
|
82a9fde921 | ||
|
|
b35721029b | ||
|
|
f403031449 | ||
|
|
25f36489b3 | ||
|
|
5005e467a0 | ||
|
|
68a148e293 | ||
|
|
205eae322b | ||
|
|
935f4a474b | ||
|
|
aa62a62bb0 | ||
|
|
104f62090d | ||
|
|
3ff7f79cc7 | ||
|
|
89e7f8b387 | ||
|
|
2fbc8509f5 | ||
|
|
67d87e29e3 | ||
|
|
55cf6c5f7e | ||
|
|
f3cf15fa0d | ||
|
|
d53d2ed791 | ||
|
|
34aeefc0a1 | ||
|
|
d8031d1a53 | ||
|
|
1098755d26 | ||
|
|
774f676a25 | ||
|
|
1629393618 | ||
|
|
4cf46edabc | ||
|
|
e6498996fa | ||
|
|
98b7bb5679 | ||
|
|
99017b173d | ||
|
|
42f2d1a7a8 | ||
|
|
a125a6199c | ||
|
|
ba1cdc6c57 | ||
|
|
875c941f3d | ||
|
|
8eeb5694ba | ||
|
|
0bef91c241 | ||
|
|
ae02209b6a | ||
|
|
e0adb6bbd6 | ||
|
|
efa191c72e |
@@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '10.1.38'
|
||||
__version__ = '10.1.59'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
||||
@@ -49,10 +49,16 @@ frappe.ui.form.on('Account', {
|
||||
}
|
||||
|
||||
if(!frm.doc.__islocal) {
|
||||
frm.add_custom_button(__('Update Account Number'), function () {
|
||||
frm.add_custom_button(__('Update Account Name / Number'), function () {
|
||||
frm.trigger("update_account_number");
|
||||
});
|
||||
}
|
||||
|
||||
if(!frm.doc.__islocal) {
|
||||
frm.add_custom_button(__('Merge Account'), function () {
|
||||
frm.trigger("merge_account");
|
||||
});
|
||||
}
|
||||
},
|
||||
account_type: function (frm) {
|
||||
if (frm.doc.is_group == 0) {
|
||||
@@ -98,20 +104,65 @@ frappe.ui.form.on('Account', {
|
||||
}
|
||||
},
|
||||
|
||||
update_account_number: function(frm) {
|
||||
merge_account: function(frm) {
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __('Update Account Number'),
|
||||
title: __('Merge with Existing Account'),
|
||||
fields: [
|
||||
{
|
||||
"label": "Account Number",
|
||||
"fieldname": "account_number",
|
||||
"label" : "Name",
|
||||
"fieldname": "name",
|
||||
"fieldtype": "Data",
|
||||
"reqd": 1
|
||||
"reqd": 1,
|
||||
"default": frm.doc.name
|
||||
}
|
||||
],
|
||||
primary_action: function() {
|
||||
var data = d.get_values();
|
||||
if(data.account_number === frm.doc.account_number) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.account.account.merge_account",
|
||||
args: {
|
||||
old: frm.doc.name,
|
||||
new: data.name,
|
||||
is_group: frm.doc.is_group,
|
||||
root_type: frm.doc.root_type,
|
||||
company: frm.doc.company
|
||||
},
|
||||
callback: function(r) {
|
||||
if(!r.exc) {
|
||||
if(r.message) {
|
||||
frappe.set_route("Form", "Account", r.message);
|
||||
}
|
||||
d.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
primary_action_label: __('Merge')
|
||||
});
|
||||
d.show();
|
||||
},
|
||||
|
||||
update_account_number: function(frm) {
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __('Update Account Number / Name'),
|
||||
fields: [
|
||||
{
|
||||
"label": "Account Name",
|
||||
"fieldname": "account_name",
|
||||
"fieldtype": "Data",
|
||||
"reqd": 1,
|
||||
"default": frm.doc.account_name
|
||||
},
|
||||
{
|
||||
"label": "Account Number",
|
||||
"fieldname": "account_number",
|
||||
"fieldtype": "Data",
|
||||
"default": frm.doc.account_number
|
||||
}
|
||||
],
|
||||
primary_action: function() {
|
||||
var data = d.get_values();
|
||||
if(data.account_number === frm.doc.account_number && data.account_name === frm.doc.account_name) {
|
||||
d.hide();
|
||||
return;
|
||||
}
|
||||
@@ -120,6 +171,7 @@ frappe.ui.form.on('Account', {
|
||||
method: "erpnext.accounts.doctype.account.account.update_account_number",
|
||||
args: {
|
||||
account_number: data.account_number,
|
||||
account_name: data.account_name,
|
||||
name: frm.doc.name
|
||||
},
|
||||
callback: function(r) {
|
||||
@@ -128,6 +180,7 @@ frappe.ui.form.on('Account', {
|
||||
frappe.set_route("Form", "Account", r.message);
|
||||
} else {
|
||||
frm.set_value("account_number", data.account_number);
|
||||
frm.set_value("account_name", data.account_name);
|
||||
}
|
||||
d.hide();
|
||||
}
|
||||
@@ -138,4 +191,4 @@ frappe.ui.form.on('Account', {
|
||||
});
|
||||
d.show();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"allow_copy": 1,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2013-01-30 12:49:46",
|
||||
"custom": 0,
|
||||
@@ -40,6 +40,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -68,6 +69,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
@@ -100,6 +102,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -130,6 +133,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -161,6 +165,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -193,6 +198,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -223,6 +229,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -253,6 +260,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -285,6 +293,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -313,6 +322,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
@@ -346,6 +356,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -379,6 +390,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -411,6 +423,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -444,6 +457,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -474,6 +488,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -503,6 +518,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -532,6 +548,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -561,6 +578,7 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@@ -575,7 +593,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-08-22 17:39:10.711343",
|
||||
"modified": "2018-07-08 09:47:04.287841",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Account",
|
||||
|
||||
@@ -165,53 +165,6 @@ class Account(NestedSet):
|
||||
|
||||
super(Account, self).on_trash(True)
|
||||
|
||||
def before_rename(self, old, new, merge=False):
|
||||
# Add company abbr if not provided
|
||||
from erpnext.setup.doctype.company.company import get_name_with_abbr
|
||||
new_account = get_name_with_abbr(new, self.company)
|
||||
if not merge:
|
||||
new_account = get_name_with_number(new_account, self.account_number)
|
||||
else:
|
||||
# Validate properties before merging
|
||||
if not frappe.db.exists("Account", new):
|
||||
throw(_("Account {0} does not exist").format(new))
|
||||
|
||||
val = list(frappe.db.get_value("Account", new_account,
|
||||
["is_group", "root_type", "company"]))
|
||||
|
||||
if val != [self.is_group, self.root_type, self.company]:
|
||||
throw(_("""Merging is only possible if following properties are same in both records. Is Group, Root Type, Company"""))
|
||||
|
||||
if self.is_group and frappe.db.get_value("Account", new, "parent_account") == old:
|
||||
frappe.db.set_value("Account", new, "parent_account",
|
||||
frappe.db.get_value("Account", old, "parent_account"))
|
||||
|
||||
return new_account
|
||||
|
||||
def after_rename(self, old, new, merge=False):
|
||||
super(Account, self).after_rename(old, new, merge)
|
||||
|
||||
if not merge:
|
||||
new_acc = frappe.db.get_value("Account", new, ["account_name", "account_number"], as_dict=1)
|
||||
|
||||
# exclude company abbr
|
||||
new_parts = new.split(" - ")[:-1]
|
||||
# update account number and remove from parts
|
||||
if new_parts[0][0].isdigit():
|
||||
# if account number is separate by space, split using space
|
||||
if len(new_parts) == 1:
|
||||
new_parts = new.split(" ")
|
||||
if new_acc.account_number != new_parts[0]:
|
||||
self.account_number = new_parts[0]
|
||||
self.db_set("account_number", new_parts[0])
|
||||
new_parts = new_parts[1:]
|
||||
|
||||
# update account name
|
||||
account_name = " - ".join(new_parts)
|
||||
if new_acc.account_name != account_name:
|
||||
self.account_name = account_name
|
||||
self.db_set("account_name", account_name)
|
||||
|
||||
def get_parent_account(doctype, txt, searchfield, start, page_len, filters):
|
||||
return frappe.db.sql("""select name from tabAccount
|
||||
where is_group = 1 and docstatus != 2 and company = %s
|
||||
@@ -252,25 +205,38 @@ def validate_account_number(name, account_number, company):
|
||||
.format(account_number, account_with_same_number))
|
||||
|
||||
@frappe.whitelist()
|
||||
def update_account_number(name, account_number):
|
||||
account = frappe.db.get_value("Account", name, ["account_name", "company"], as_dict=True)
|
||||
def update_account_number(name, account_name, account_number=None):
|
||||
|
||||
account = frappe.db.get_value("Account", name, "company", as_dict=True)
|
||||
if not account: return
|
||||
validate_account_number(name, account_number, account.company)
|
||||
|
||||
frappe.db.set_value("Account", name, "account_number", account_number)
|
||||
|
||||
account_name = account.account_name
|
||||
if account_name[0].isdigit():
|
||||
separator = " - " if " - " in account_name else " "
|
||||
account_name = account_name.split(separator, 1)[1]
|
||||
frappe.db.set_value("Account", name, "account_name", account_name)
|
||||
if account_number:
|
||||
frappe.db.set_value("Account", name, "account_number", account_number.strip())
|
||||
else:
|
||||
frappe.db.set_value("Account", name, "account_number", "")
|
||||
frappe.db.set_value("Account", name, "account_name", account_name.strip())
|
||||
|
||||
new_name = get_account_autoname(account_number, account_name, account.company)
|
||||
if name != new_name:
|
||||
frappe.rename_doc("Account", name, new_name)
|
||||
frappe.rename_doc("Account", name, new_name, ignore_permissions=1)
|
||||
return new_name
|
||||
|
||||
def get_name_with_number(new_account, account_number):
|
||||
if account_number and not new_account[0].isdigit():
|
||||
new_account = account_number + " - " + new_account
|
||||
return new_account
|
||||
@frappe.whitelist()
|
||||
def merge_account(old, new, is_group, root_type, company):
|
||||
# Validate properties before merging
|
||||
if not frappe.db.exists("Account", new):
|
||||
throw(_("Account {0} does not exist").format(new))
|
||||
|
||||
val = list(frappe.db.get_value("Account", new,
|
||||
["is_group", "root_type", "company"]))
|
||||
|
||||
if val != [cint(is_group), root_type, company]:
|
||||
throw(_("""Merging is only possible if following properties are same in both records. Is Group, Root Type, Company"""))
|
||||
|
||||
if is_group and frappe.db.get_value("Account", new, "parent_account") == old:
|
||||
frappe.db.set_value("Account", new, "parent_account",
|
||||
frappe.db.get_value("Account", old, "parent_account"))
|
||||
|
||||
frappe.rename_doc("Account", old, new, merge=1, ignore_permissions=1)
|
||||
|
||||
return new
|
||||
|
||||
@@ -5,6 +5,8 @@ from __future__ import unicode_literals
|
||||
import unittest
|
||||
import frappe
|
||||
from erpnext.stock import get_warehouse_account, get_company_default_inventory_account
|
||||
from erpnext.accounts.doctype.account.account import update_account_number
|
||||
from erpnext.accounts.doctype.account.account import merge_account
|
||||
|
||||
class TestAccount(unittest.TestCase):
|
||||
def test_rename_account(self):
|
||||
@@ -21,21 +23,79 @@ class TestAccount(unittest.TestCase):
|
||||
self.assertEqual(account_number, "1210")
|
||||
self.assertEqual(account_name, "Debtors")
|
||||
|
||||
frappe.rename_doc("Account", "1210 - Debtors - _TC", "1211 - Debtors 1 - _TC")
|
||||
new_account_number = "1211-11-4 - 6 - "
|
||||
new_account_name = "Debtors 1 - Test - "
|
||||
|
||||
new_acc = frappe.db.get_value("Account", "1211 - Debtors 1 - _TC",
|
||||
update_account_number("1210 - Debtors - _TC", new_account_name, new_account_number)
|
||||
|
||||
new_acc = frappe.db.get_value("Account", "1211-11-4 - 6 - - Debtors 1 - Test - - _TC",
|
||||
["account_name", "account_number"], as_dict=1)
|
||||
self.assertEqual(new_acc.account_name, "Debtors 1")
|
||||
self.assertEqual(new_acc.account_number, "1211")
|
||||
|
||||
frappe.rename_doc("Account", "1211 - Debtors 1 - _TC", "Debtors 2")
|
||||
self.assertEqual(new_acc.account_name, "Debtors 1 - Test -")
|
||||
self.assertEqual(new_acc.account_number, "1211-11-4 - 6 -")
|
||||
|
||||
new_acc = frappe.db.get_value("Account", "1211 - Debtors 2 - _TC",
|
||||
["account_name", "account_number"], as_dict=1)
|
||||
self.assertEqual(new_acc.account_name, "Debtors 2")
|
||||
self.assertEqual(new_acc.account_number, "1211")
|
||||
frappe.delete_doc("Account", "1211-11-4 - 6 - Debtors 1 - Test - - _TC")
|
||||
|
||||
frappe.delete_doc("Account", "1211 - Debtors 2 - _TC")
|
||||
def test_merge_account(self):
|
||||
if not frappe.db.exists("Account", "Current Assets - _TC"):
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "Current Assets"
|
||||
acc.is_group = 1
|
||||
acc.parent_account = "Application of Funds (Assets) - _TC"
|
||||
acc.company = "_Test Company"
|
||||
acc.insert()
|
||||
if not frappe.db.exists("Account", "Securities and Deposits - _TC"):
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "Securities and Deposits"
|
||||
acc.parent_account = "Current Assets - _TC"
|
||||
acc.is_group = 1
|
||||
acc.company = "_Test Company"
|
||||
acc.insert()
|
||||
if not frappe.db.exists("Account", "Earnest Money - _TC"):
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "Earnest Money"
|
||||
acc.parent_account = "Securities and Deposits - _TC"
|
||||
acc.company = "_Test Company"
|
||||
acc.insert()
|
||||
if not frappe.db.exists("Account", "Cash In Hand - _TC"):
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "Cash In Hand"
|
||||
acc.is_group = 1
|
||||
acc.parent_account = "Current Assets - _TC"
|
||||
acc.company = "_Test Company"
|
||||
acc.insert()
|
||||
if not frappe.db.exists("Account", "Accumulated Depreciation - _TC"):
|
||||
acc = frappe.new_doc("Account")
|
||||
acc.account_name = "Accumulated Depreciation"
|
||||
acc.parent_account = "Fixed Assets - _TC"
|
||||
acc.company = "_Test Company"
|
||||
acc.insert()
|
||||
|
||||
doc = frappe.get_doc("Account", "Securities and Deposits - _TC")
|
||||
parent = frappe.db.get_value("Account", "Earnest Money - _TC", "parent_account")
|
||||
|
||||
self.assertEqual(parent, "Securities and Deposits - _TC")
|
||||
|
||||
merge_account("Securities and Deposits - _TC", "Cash In Hand - _TC", doc.is_group, doc.root_type, doc.company)
|
||||
parent = frappe.db.get_value("Account", "Earnest Money - _TC", "parent_account")
|
||||
|
||||
# Parent account of the child account changes after merging
|
||||
self.assertEqual(parent, "Cash In Hand - _TC")
|
||||
|
||||
# Old account doesn't exist after merging
|
||||
self.assertFalse(frappe.db.exists("Account", "Securities and Deposits - _TC"))
|
||||
|
||||
doc = frappe.get_doc("Account", "Current Assets - _TC")
|
||||
|
||||
# Raise error as is_group property doesn't match
|
||||
self.assertRaises(frappe.ValidationError, merge_account, "Current Assets - _TC",\
|
||||
"Accumulated Depreciation - _TC", doc.is_group, doc.root_type, doc.company)
|
||||
|
||||
doc = frappe.get_doc("Account", "Capital Stock - _TC")
|
||||
|
||||
# Raise error as root_type property doesn't match
|
||||
self.assertRaises(frappe.ValidationError, merge_account, "Capital Stock - _TC",\
|
||||
"Softwares - _TC", doc.is_group, doc.root_type, doc.company)
|
||||
|
||||
def _make_test_records(verbose):
|
||||
from frappe.test_runner import make_test_objects
|
||||
|
||||
@@ -27,13 +27,21 @@ class Budget(Document):
|
||||
def validate_duplicate(self):
|
||||
budget_against_field = frappe.scrub(self.budget_against)
|
||||
budget_against = self.get(budget_against_field)
|
||||
existing_budget = frappe.db.get_value("Budget", {budget_against_field: budget_against,
|
||||
"fiscal_year": self.fiscal_year, "company": self.company,
|
||||
"name": ["!=", self.name], "docstatus": ["!=", 2]})
|
||||
if existing_budget:
|
||||
frappe.throw(_("Another Budget record '{0}' already exists against {1} '{2}' for fiscal year {3}")
|
||||
.format(existing_budget, self.budget_against, budget_against, self.fiscal_year), DuplicateBudgetError)
|
||||
|
||||
|
||||
accounts = [d.account for d in self.accounts] or []
|
||||
existing_budget = frappe.db.sql("""
|
||||
select
|
||||
b.name, ba.account from `tabBudget` b, `tabBudget Account` ba
|
||||
where
|
||||
ba.parent = b.name and b.docstatus < 2 and b.company = %s and %s=%s and
|
||||
b.fiscal_year=%s and b.name != %sand ba.account in (%s) """
|
||||
% ('%s', budget_against_field, '%s', '%s', '%s', ','.join(['%s'] * len(accounts))),
|
||||
(self.company, budget_against, self.fiscal_year, self.name) + tuple(accounts), as_dict=1)
|
||||
|
||||
for d in existing_budget:
|
||||
frappe.throw(_("Another Budget record '{0}' already exists against {1} '{2}' and account '{3}' for fiscal year {4}")
|
||||
.format(d.name, self.budget_against, budget_against, d.account, self.fiscal_year), DuplicateBudgetError)
|
||||
|
||||
def validate_accounts(self):
|
||||
account_list = []
|
||||
for d in self.get('accounts'):
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
@@ -702,7 +702,7 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
@@ -718,7 +718,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-20 12:40:09.611951",
|
||||
"modified": "2018-08-10 16:16:53.019380",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "GL Entry",
|
||||
@@ -794,4 +794,4 @@
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
||||
}
|
||||
@@ -381,7 +381,7 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
@@ -1443,7 +1443,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-08-31 11:21:09.442695",
|
||||
"modified": "2018-08-10 16:35:31.361030",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Journal Entry",
|
||||
|
||||
@@ -199,7 +199,7 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
@@ -661,7 +661,7 @@
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -795,7 +795,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-07 19:54:19.851534",
|
||||
"modified": "2018-08-10 16:35:42.833549",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Journal Entry Account",
|
||||
|
||||
@@ -588,6 +588,10 @@ frappe.ui.form.on('Payment Entry', {
|
||||
allocate_party_amount_against_ref_docs: function(frm, paid_amount) {
|
||||
var total_positive_outstanding_including_order = 0;
|
||||
var total_negative_outstanding = 0;
|
||||
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
|
||||
function(d) { return flt(d.amount) }));
|
||||
|
||||
paid_amount -= total_deductions;
|
||||
|
||||
$.each(frm.doc.references || [], function(i, row) {
|
||||
if(flt(row.outstanding_amount) > 0)
|
||||
@@ -815,23 +819,30 @@ frappe.ui.form.on('Payment Entry Reference', {
|
||||
|
||||
reference_name: function(frm, cdt, cdn) {
|
||||
var row = locals[cdt][cdn];
|
||||
return frappe.call({
|
||||
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_reference_details",
|
||||
args: {
|
||||
reference_doctype: row.reference_doctype,
|
||||
reference_name: row.reference_name,
|
||||
party_account_currency: frm.doc.payment_type=="Receive" ?
|
||||
frm.doc.paid_from_account_currency : frm.doc.paid_to_account_currency
|
||||
},
|
||||
callback: function(r, rt) {
|
||||
if(r.message) {
|
||||
$.each(r.message, function(field, value) {
|
||||
frappe.model.set_value(cdt, cdn, field, value);
|
||||
})
|
||||
frm.refresh_fields();
|
||||
if (row.reference_name && row.reference_doctype) {
|
||||
return frappe.call({
|
||||
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_reference_details",
|
||||
args: {
|
||||
reference_doctype: row.reference_doctype,
|
||||
reference_name: row.reference_name,
|
||||
party_account_currency: frm.doc.payment_type=="Receive" ?
|
||||
frm.doc.paid_from_account_currency : frm.doc.paid_to_account_currency
|
||||
},
|
||||
callback: function(r, rt) {
|
||||
if(r.message) {
|
||||
$.each(r.message, function(field, value) {
|
||||
frappe.model.set_value(cdt, cdn, field, value);
|
||||
})
|
||||
|
||||
let allocated_amount = frm.doc.unallocated_amount > row.outstanding_amount ?
|
||||
row.outstanding_amount : frm.doc.unallocated_amount;
|
||||
|
||||
frappe.model.set_value(cdt, cdn, 'allocated_amount', allocated_amount);
|
||||
frm.refresh_fields();
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
allocated_amount: function(frm) {
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -72,7 +71,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 1,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -104,7 +102,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -134,7 +131,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -166,7 +162,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -198,7 +193,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -230,7 +224,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -262,7 +255,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -294,9 +286,8 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -329,7 +320,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -359,7 +349,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -392,7 +381,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -423,7 +411,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -455,7 +442,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -488,7 +474,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -521,7 +506,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -554,7 +538,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -584,7 +567,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -617,7 +599,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -650,7 +631,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -683,7 +663,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -716,7 +695,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -749,7 +727,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -781,7 +758,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -814,7 +790,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -844,7 +819,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -877,7 +851,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -909,7 +882,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -942,7 +914,6 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -975,7 +946,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1008,7 +978,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1041,7 +1010,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1073,7 +1041,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1105,7 +1072,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1138,7 +1104,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1169,7 +1134,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1199,7 +1163,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1231,7 +1194,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1264,7 +1226,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1296,7 +1257,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1329,7 +1289,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1361,7 +1320,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1392,7 +1350,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1424,7 +1381,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1454,7 +1410,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1484,9 +1439,8 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1518,7 +1472,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1551,7 +1504,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1584,7 +1536,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1604,7 +1555,7 @@
|
||||
"in_standard_filter": 0,
|
||||
"label": "Remarks",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@@ -1615,7 +1566,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1645,7 +1595,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1677,7 +1626,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1709,7 +1657,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1740,7 +1687,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1772,7 +1718,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1803,7 +1748,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
@@ -1834,7 +1778,6 @@
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
@@ -1848,7 +1791,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-02-19 16:58:23.899015",
|
||||
"modified": "2018-08-10 16:34:46.771275",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Entry",
|
||||
|
||||
@@ -337,14 +337,15 @@ class PaymentEntry(AccountsController):
|
||||
total_negative_outstanding = sum([abs(flt(d.outstanding_amount))
|
||||
for d in self.get("references") if flt(d.outstanding_amount) < 0])
|
||||
|
||||
party_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount
|
||||
paid_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount
|
||||
additional_charges = sum([flt(d.amount) for d in self.deductions])
|
||||
|
||||
if not total_negative_outstanding:
|
||||
frappe.throw(_("Cannot {0} {1} {2} without any negative outstanding invoice")
|
||||
.format(self.payment_type, ("to" if self.party_type=="Customer" else "from"),
|
||||
self.party_type), InvalidPaymentEntry)
|
||||
|
||||
elif party_amount > total_negative_outstanding:
|
||||
elif paid_amount - additional_charges > total_negative_outstanding:
|
||||
frappe.throw(_("Paid Amount cannot be greater than total negative outstanding amount {0}")
|
||||
.format(total_negative_outstanding), InvalidPaymentEntry)
|
||||
|
||||
@@ -724,8 +725,11 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
|
||||
exchange_rate = ref_doc.get("conversion_rate") or \
|
||||
get_exchange_rate(party_account_currency, company_currency, ref_doc.posting_date)
|
||||
|
||||
if reference_doctype in ("Sales Invoice", "Purchase Invoice", "Expense Claim"):
|
||||
if reference_doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||
outstanding_amount = ref_doc.get("outstanding_amount")
|
||||
elif reference_doctype == "Expense Claim":
|
||||
outstanding_amount = flt(ref_doc.get("total_sanctioned_amount")) \
|
||||
- flt(ref_doc.get("total_amount+reimbursed")) - flt(ref_doc.get("total_advance_amount"))
|
||||
elif reference_doctype == "Employee Advance":
|
||||
outstanding_amount = ref_doc.advance_amount - flt(ref_doc.paid_amount)
|
||||
else:
|
||||
|
||||
@@ -21,8 +21,6 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
||||
if(!this.frm.doc.supplier && this.frm.doc.credit_to) {
|
||||
this.frm.set_df_property("credit_to", "print_hide", 0);
|
||||
}
|
||||
} else {
|
||||
this.frm.set_value("disable_rounded_total", cint(frappe.sys_defaults.disable_rounded_total));
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -1239,7 +1239,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_bulk_edit": 1,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -3973,7 +3973,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2018-05-28 02:38:40.310899",
|
||||
"modified": "2018-07-06 02:38:40.310899",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice",
|
||||
|
||||
@@ -388,16 +388,20 @@ class PurchaseInvoice(BuyingController):
|
||||
expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
|
||||
warehouse_account = get_warehouse_account_map()
|
||||
|
||||
voucher_wise_stock_value = {}
|
||||
if self.update_stock:
|
||||
for d in frappe.get_all('Stock Ledger Entry',
|
||||
fields = ["voucher_detail_no", "stock_value_difference"], filters={'voucher_no': self.name}):
|
||||
voucher_wise_stock_value.setdefault(d.voucher_detail_no, d.stock_value_difference)
|
||||
|
||||
for item in self.get("items"):
|
||||
if flt(item.base_net_amount):
|
||||
account_currency = get_account_currency(item.expense_account)
|
||||
|
||||
if self.update_stock and self.auto_accounting_for_stock and item.item_code in stock_items:
|
||||
val_rate_db_precision = 6 if cint(item.precision("valuation_rate")) <= 6 else 9
|
||||
|
||||
# warehouse account
|
||||
warehouse_debit_amount = flt(flt(item.valuation_rate, val_rate_db_precision)
|
||||
* flt(item.qty) * flt(item.conversion_factor), item.precision("base_net_amount"))
|
||||
warehouse_debit_amount = self.make_stock_adjustment_entry(gl_entries,
|
||||
item, voucher_wise_stock_value, account_currency)
|
||||
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
@@ -469,6 +473,36 @@ class PurchaseInvoice(BuyingController):
|
||||
self.negative_expense_to_be_booked += flt(item.item_tax_amount, \
|
||||
item.precision("item_tax_amount"))
|
||||
|
||||
def make_stock_adjustment_entry(self, gl_entries, item, voucher_wise_stock_value, account_currency):
|
||||
net_amt_precision = item.precision("base_net_amount")
|
||||
val_rate_db_precision = 6 if cint(item.precision("valuation_rate")) <= 6 else 9
|
||||
|
||||
warehouse_debit_amount = flt(flt(item.valuation_rate, val_rate_db_precision)
|
||||
* flt(item.qty) * flt(item.conversion_factor), net_amt_precision)
|
||||
|
||||
# Stock ledger value is not matching with the warehouse amount
|
||||
if (self.update_stock and voucher_wise_stock_value.get(item.name) and
|
||||
warehouse_debit_amount != flt(voucher_wise_stock_value.get(item.name), net_amt_precision)):
|
||||
|
||||
cost_of_goods_sold_account = self.get_company_default("default_expense_account")
|
||||
stock_amount = flt(voucher_wise_stock_value.get(item.name), net_amt_precision)
|
||||
stock_adjustment_amt = warehouse_debit_amount - stock_amount
|
||||
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
"account": cost_of_goods_sold_account,
|
||||
"against": item.expense_account,
|
||||
"debit": stock_adjustment_amt,
|
||||
"remarks": self.get("remarks") or _("Stock Adjustment"),
|
||||
"cost_center": item.cost_center,
|
||||
"project": item.project
|
||||
}, account_currency)
|
||||
)
|
||||
|
||||
warehouse_debit_amount = stock_amount
|
||||
|
||||
return warehouse_debit_amount
|
||||
|
||||
def make_tax_gl_entries(self, gl_entries):
|
||||
# tax table gl entries
|
||||
valuation_tax = {}
|
||||
|
||||
@@ -585,6 +585,38 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "discount_percentage",
|
||||
"fieldname": "discount_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": "Discount Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "currency",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2156,7 +2188,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-30 14:21:00.962126",
|
||||
"modified": "2018-08-06 05:17:38.205356",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice Item",
|
||||
|
||||
@@ -506,6 +506,7 @@ def save_invoice(doc, name, name_list):
|
||||
frappe.db.commit()
|
||||
name_list.append(name)
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
|
||||
return name_list
|
||||
|
||||
@@ -639,6 +639,66 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_21",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: doc.is_return && doc.return_against",
|
||||
"fieldname": "update_billed_amount_in_sales_order",
|
||||
"fieldtype": "Check",
|
||||
"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": "Update Billed Amount in Sales Order",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -1459,7 +1519,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_bulk_edit": 1,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -4713,7 +4773,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2018-05-28 04:47:29.879475",
|
||||
"modified": "2018-07-17 13:46:52.449142",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice",
|
||||
@@ -4804,7 +4864,7 @@
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 1,
|
||||
"search_fields": "posting_date, due_date, customer, base_grand_total, outstanding_amount",
|
||||
"search_fields": "posting_date,due_date,customer,base_grand_total,outstanding_amount",
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
|
||||
@@ -116,7 +116,7 @@ class SalesInvoice(SellingController):
|
||||
|
||||
self.check_prev_docstatus()
|
||||
|
||||
if self.is_return:
|
||||
if self.is_return and not self.update_billed_amount_in_sales_order:
|
||||
# NOTE status updating bypassed for is_return
|
||||
self.status_updater = []
|
||||
|
||||
@@ -161,7 +161,7 @@ class SalesInvoice(SellingController):
|
||||
if frappe.db.get_single_value('Accounts Settings', 'unlink_payment_on_cancellation_of_invoice'):
|
||||
unlink_ref_doc_from_payment_entries(self)
|
||||
|
||||
if self.is_return:
|
||||
if self.is_return and not self.update_billed_amount_in_sales_order:
|
||||
# NOTE status updating bypassed for is_return
|
||||
self.status_updater = []
|
||||
|
||||
@@ -318,6 +318,7 @@ class SalesInvoice(SellingController):
|
||||
if not for_validate and not self.customer:
|
||||
self.customer = pos.customer
|
||||
|
||||
self.ignore_pricing_rule = pos.ignore_pricing_rule
|
||||
if pos.get('account_for_change_amount'):
|
||||
self.account_for_change_amount = pos.get('account_for_change_amount')
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,8 +20,8 @@ from erpnext import get_default_currency, get_company_currency
|
||||
class DuplicatePartyAccountError(frappe.ValidationError): pass
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_party_details(party=None, account=None, party_type="Customer", company=None,
|
||||
posting_date=None, price_list=None, currency=None, doctype=None, ignore_permissions=False):
|
||||
def get_party_details(party=None, account=None, party_type="Customer", company=None, posting_date=None,
|
||||
price_list=None, currency=None, doctype=None, ignore_permissions=False, fetch_payment_terms_template=True):
|
||||
|
||||
if not party:
|
||||
return {}
|
||||
@@ -30,10 +30,10 @@ def get_party_details(party=None, account=None, party_type="Customer", company=N
|
||||
frappe.throw(_("{0}: {1} does not exists").format(party_type, party))
|
||||
|
||||
return _get_party_details(party, account, party_type,
|
||||
company, posting_date, price_list, currency, doctype, ignore_permissions)
|
||||
company, posting_date, price_list, currency, doctype, ignore_permissions, fetch_payment_terms_template)
|
||||
|
||||
def _get_party_details(party=None, account=None, party_type="Customer", company=None,
|
||||
posting_date=None, price_list=None, currency=None, doctype=None, ignore_permissions=False):
|
||||
def _get_party_details(party=None, account=None, party_type="Customer", company=None, posting_date=None,
|
||||
price_list=None, currency=None, doctype=None, ignore_permissions=False, fetch_payment_terms_template=True):
|
||||
|
||||
out = frappe._dict(set_account_and_due_date(party, account, party_type, company, posting_date, doctype))
|
||||
|
||||
@@ -50,7 +50,9 @@ def _get_party_details(party=None, account=None, party_type="Customer", company=
|
||||
set_other_values(out, party, party_type)
|
||||
set_price_list(out, party, party_type, price_list)
|
||||
out["taxes_and_charges"] = set_taxes(party.name, party_type, posting_date, company, out.customer_group, out.supplier_type)
|
||||
out["payment_terms_template"] = get_pyt_term_template(party.name, party_type, company)
|
||||
|
||||
if fetch_payment_terms_template:
|
||||
out["payment_terms_template"] = get_pyt_term_template(party.name, party_type, company)
|
||||
|
||||
if not out.get("currency"):
|
||||
out["currency"] = currency
|
||||
@@ -272,6 +274,7 @@ def get_due_date(posting_date, party_type, party, company=None):
|
||||
if posting_date and party:
|
||||
due_date = posting_date
|
||||
template_name = get_pyt_term_template(party, party_type, company)
|
||||
|
||||
if template_name:
|
||||
due_date = get_due_date_from_template(template_name, posting_date).strftime("%Y-%m-%d")
|
||||
else:
|
||||
@@ -304,11 +307,13 @@ def get_due_date_from_template(template_name, posting_date):
|
||||
|
||||
return due_date
|
||||
|
||||
def validate_due_date(posting_date, due_date, party_type, party, company=None):
|
||||
def validate_due_date(posting_date, due_date, party_type, party, company=None, template_name=None):
|
||||
if getdate(due_date) < getdate(posting_date):
|
||||
frappe.throw(_("Due Date cannot be before Posting Date"))
|
||||
else:
|
||||
default_due_date = get_due_date(posting_date, party_type, party, company)
|
||||
if not template_name: return
|
||||
|
||||
default_due_date = get_due_date_from_template(template_name, posting_date).strftime("%Y-%m-%d")
|
||||
if not default_due_date:
|
||||
return
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ frappe.query_reports["Accounts Payable"] = {
|
||||
"fieldname":"ageing_based_on",
|
||||
"label": __("Ageing Based On"),
|
||||
"fieldtype": "Select",
|
||||
"options": 'Posting Date\nDue Date',
|
||||
"options": 'Posting Date\nDue Date\nSupplier Invoice Date',
|
||||
"default": "Posting Date"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -161,21 +161,21 @@
|
||||
</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"]) %}</td>
|
||||
{%= format_currency(data[i]["invoiced_amount"], data[i]["currency"]) %}</td>
|
||||
|
||||
{% if(!filters.show_pdc_in_print) { %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Paid Amount"], data[i]["currency"]) %}</td>
|
||||
{%= format_currency(data[i]["paid_amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">
|
||||
{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["Credit Note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %}</td>
|
||||
{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Outstanding Amount"], data[i]["currency"]) %}</td>
|
||||
{%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %}</td>
|
||||
|
||||
{% if(filters.show_pdc_in_print) { %}
|
||||
{% if(report.report_name === "Accounts Receivable") { %}
|
||||
<td style="text-align: right">
|
||||
{%= data[i][__("Customer LPO")] %}</td>
|
||||
{%= data[i]["po_no"] %}</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">{%= frappe.datetime.str_to_user(data[i][__("PDC/LC Date")]) %}</td>
|
||||
<td style="text-align: right">{%= data[i][__("PDC/LC Ref")] %}</td>
|
||||
|
||||
@@ -60,6 +60,7 @@ class ReceivablePayableReport(object):
|
||||
for label in ("Invoiced Amount", "Paid Amount", credit_or_debit_note, "Outstanding Amount"):
|
||||
columns.append({
|
||||
"label": label,
|
||||
"fieldname": frappe.scrub(label),
|
||||
"fieldtype": "Currency",
|
||||
"options": "currency",
|
||||
"width": 120
|
||||
@@ -103,9 +104,13 @@ class ReceivablePayableReport(object):
|
||||
]
|
||||
|
||||
if args.get('party_type') == 'Customer':
|
||||
columns += [_("Customer LPO") + ":Data:100"]
|
||||
columns.append({
|
||||
"label": _("Customer LPO"),
|
||||
"fieldtype": "Data",
|
||||
"fieldname": "po_no",
|
||||
"width": 100,
|
||||
})
|
||||
columns += [_("Delivery Note") + ":Data:100"]
|
||||
|
||||
if args.get("party_type") == "Customer":
|
||||
columns += [
|
||||
_("Territory") + ":Link/Territory:80",
|
||||
@@ -123,9 +128,6 @@ class ReceivablePayableReport(object):
|
||||
currency_precision = get_currency_precision() or 2
|
||||
dr_or_cr = "debit" if args.get("party_type") == "Customer" else "credit"
|
||||
|
||||
dn_details = get_dn_details(args.get("party_type"))
|
||||
voucher_details = self.get_voucher_details(args.get("party_type"), dn_details)
|
||||
|
||||
future_vouchers = self.get_entries_after(self.filters.report_date, args.get("party_type"))
|
||||
|
||||
if not self.filters.get("company"):
|
||||
@@ -138,7 +140,14 @@ class ReceivablePayableReport(object):
|
||||
data = []
|
||||
pdc_details = get_pdc_details(args.get("party_type"), self.filters.report_date)
|
||||
|
||||
for gle in self.get_entries_till(self.filters.report_date, args.get("party_type")):
|
||||
gl_entries_data = self.get_entries_till(self.filters.report_date, args.get("party_type"))
|
||||
|
||||
if gl_entries_data:
|
||||
voucher_nos = [d.voucher_no for d in gl_entries_data] or []
|
||||
dn_details = get_dn_details(args.get("party_type"), voucher_nos)
|
||||
voucher_details = get_voucher_details(args.get("party_type"), voucher_nos, dn_details)
|
||||
|
||||
for gle in gl_entries_data:
|
||||
if self.is_receivable_or_payable(gle, dr_or_cr, future_vouchers):
|
||||
outstanding_amount, credit_note_amount = self.get_outstanding_amount(gle,
|
||||
self.filters.report_date, dr_or_cr, return_entries, currency_precision)
|
||||
@@ -151,6 +160,7 @@ class ReceivablePayableReport(object):
|
||||
|
||||
# get due date
|
||||
due_date = voucher_details.get(gle.voucher_no, {}).get("due_date", "")
|
||||
bill_date = voucher_details.get(gle.voucher_no, {}).get("bill_date", "")
|
||||
|
||||
row += [gle.voucher_type, gle.voucher_no, due_date]
|
||||
|
||||
@@ -167,15 +177,25 @@ class ReceivablePayableReport(object):
|
||||
row += [invoiced_amount, paid_amt, credit_note_amount, outstanding_amount]
|
||||
|
||||
# ageing data
|
||||
entry_date = due_date if self.filters.ageing_based_on == "Due Date" else gle.posting_date
|
||||
if self.filters.ageing_based_on == "Due Date":
|
||||
entry_date = due_date
|
||||
elif self.filters.ageing_based_on == "Supplier Invoice Date":
|
||||
entry_date = bill_date
|
||||
else:
|
||||
entry_date = gle.posting_date
|
||||
row += get_ageing_data(cint(self.filters.range1), cint(self.filters.range2),
|
||||
cint(self.filters.range3), self.age_as_on, entry_date, outstanding_amount)
|
||||
|
||||
|
||||
# issue 6371-Ageing buckets should not have amounts if due date is not reached
|
||||
if self.filters.ageing_based_on == "Due Date" \
|
||||
and getdate(due_date) > getdate(self.filters.report_date):
|
||||
row[-1]=row[-2]=row[-3]=row[-4]=0
|
||||
|
||||
if self.filters.ageing_based_on == "Supplier Invoice Date" \
|
||||
and getdate(bill_date) > getdate(self.filters.report_date):
|
||||
row[-1]=row[-2]=row[-3]=row[-4]=0
|
||||
|
||||
if self.filters.get(scrub(args.get("party_type"))):
|
||||
row.append(gle.account_currency)
|
||||
else:
|
||||
@@ -207,12 +227,11 @@ class ReceivablePayableReport(object):
|
||||
|
||||
def get_entries_after(self, report_date, party_type):
|
||||
# returns a distinct list
|
||||
return list(set([(e.voucher_type, e.voucher_no) for e in self.get_gl_entries(party_type)
|
||||
if getdate(e.posting_date) > report_date]))
|
||||
return list(set([(e.voucher_type, e.voucher_no) for e in self.get_gl_entries(party_type, report_date, for_future=True)]))
|
||||
|
||||
def get_entries_till(self, report_date, party_type):
|
||||
# returns a generator
|
||||
return (e for e in self.get_gl_entries(party_type) if getdate(e.posting_date) <= report_date)
|
||||
return self.get_gl_entries(party_type, report_date)
|
||||
|
||||
def is_receivable_or_payable(self, gle, dr_or_cr, future_vouchers):
|
||||
return (
|
||||
@@ -239,14 +258,16 @@ class ReceivablePayableReport(object):
|
||||
|
||||
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:
|
||||
amount = flt(e.get(reverse_dr_or_cr)) - flt(e.get(dr_or_cr))
|
||||
amount = flt(e.get(reverse_dr_or_cr), currency_precision) - flt(e.get(dr_or_cr), currency_precision)
|
||||
if e.voucher_no not in return_entries:
|
||||
payment_amount += amount
|
||||
else:
|
||||
credit_note_amount += amount
|
||||
|
||||
outstanding_amount = flt((flt(gle.get(dr_or_cr)) - flt(gle.get(reverse_dr_or_cr)) \
|
||||
- payment_amount - credit_note_amount), currency_precision)
|
||||
outstanding_amount = (flt((flt(gle.get(dr_or_cr), currency_precision)
|
||||
- flt(gle.get(reverse_dr_or_cr), currency_precision)
|
||||
- payment_amount - credit_note_amount), currency_precision))
|
||||
|
||||
credit_note_amount = flt(credit_note_amount, currency_precision)
|
||||
|
||||
return outstanding_amount, credit_note_amount
|
||||
@@ -275,42 +296,31 @@ class ReceivablePayableReport(object):
|
||||
|
||||
return self.party_map
|
||||
|
||||
def get_voucher_details(self, party_type, dn_details):
|
||||
voucher_details = frappe._dict()
|
||||
def get_gl_entries(self, party_type, date=None, for_future=False):
|
||||
conditions, values = self.prepare_conditions(party_type)
|
||||
|
||||
if party_type == "Customer":
|
||||
for si in frappe.db.sql("""select name, due_date, po_no
|
||||
from `tabSales Invoice` where docstatus=1""", as_dict=1):
|
||||
si['delivery_note'] = dn_details.get(si.name)
|
||||
voucher_details.setdefault(si.name, si)
|
||||
if self.filters.get(scrub(party_type)):
|
||||
select_fields = "sum(debit_in_account_currency) as debit, sum(credit_in_account_currency) as credit"
|
||||
else:
|
||||
select_fields = "sum(debit) as debit, sum(credit) as credit"
|
||||
|
||||
if party_type == "Supplier":
|
||||
for pi in frappe.db.sql("""select name, due_date, bill_no, bill_date
|
||||
from `tabPurchase Invoice` where docstatus = 1
|
||||
union
|
||||
select name, due_date, bill_no, bill_date from `tabJournal Entry`
|
||||
where docstatus = 1 and bill_no is not NULL""", as_dict=1):
|
||||
voucher_details.setdefault(pi.name, pi)
|
||||
if date and not for_future:
|
||||
conditions += " and posting_date <= '%s'" % date
|
||||
|
||||
return voucher_details
|
||||
if date and for_future:
|
||||
conditions += " and posting_date > '%s'" % date
|
||||
|
||||
def get_gl_entries(self, party_type):
|
||||
if not hasattr(self, "gl_entries"):
|
||||
conditions, values = self.prepare_conditions(party_type)
|
||||
|
||||
if self.filters.get(scrub(party_type)):
|
||||
select_fields = "sum(debit_in_account_currency) as debit, sum(credit_in_account_currency) as credit"
|
||||
else:
|
||||
select_fields = "sum(debit) as debit, sum(credit) as credit"
|
||||
|
||||
self.gl_entries = frappe.db.sql("""select name, posting_date, account, party_type, party,
|
||||
voucher_type, voucher_no, against_voucher_type, against_voucher,
|
||||
account_currency, remarks, {0}
|
||||
from `tabGL Entry`
|
||||
where docstatus < 2 and party_type=%s and (party is not null and party != '') {1}
|
||||
self.gl_entries = frappe.db.sql("""
|
||||
select
|
||||
name, posting_date, account, party_type, party, voucher_type, voucher_no,
|
||||
against_voucher_type, against_voucher, account_currency, remarks, {0}
|
||||
from
|
||||
`tabGL Entry`
|
||||
where
|
||||
docstatus < 2 and party_type=%s and (party is not null and party != '') {1}
|
||||
group by voucher_type, voucher_no, against_voucher_type, against_voucher, party
|
||||
order by posting_date, party"""
|
||||
.format(select_fields, conditions), values, as_dict=True)
|
||||
.format(select_fields, conditions), values, as_dict=True)
|
||||
|
||||
return self.gl_entries
|
||||
|
||||
@@ -446,18 +456,57 @@ def get_pdc_details(party_type, report_date):
|
||||
|
||||
return pdc_details
|
||||
|
||||
def get_dn_details(party_type):
|
||||
def get_dn_details(party_type, voucher_nos):
|
||||
dn_details = frappe._dict()
|
||||
|
||||
if party_type == "Customer":
|
||||
for si in frappe.db.sql("""select parent, GROUP_CONCAT(delivery_note SEPARATOR ', ') as dn
|
||||
from `tabSales Invoice Item`
|
||||
where docstatus=1 and delivery_note is not null and delivery_note != '' group by parent
|
||||
Union
|
||||
select against_sales_invoice as parent, GROUP_CONCAT(parent SEPARATOR ', ') as dn
|
||||
from `tabDelivery Note Item`
|
||||
where docstatus=1 and against_sales_invoice is not null
|
||||
and against_sales_invoice != '' group by against_sales_invoice""", as_dict=1):
|
||||
for si in frappe.db.sql("""
|
||||
select
|
||||
parent, GROUP_CONCAT(delivery_note SEPARATOR ', ') as dn
|
||||
from
|
||||
`tabSales Invoice Item`
|
||||
where
|
||||
docstatus=1 and delivery_note is not null and delivery_note != ''
|
||||
and parent in (%s) group by parent
|
||||
""" %(','.join(['%s'] * len(voucher_nos))), tuple(voucher_nos) , as_dict=1):
|
||||
dn_details.setdefault(si.parent, si.dn)
|
||||
|
||||
for si in frappe.db.sql("""
|
||||
select
|
||||
against_sales_invoice as parent, GROUP_CONCAT(parent SEPARATOR ', ') as dn
|
||||
from
|
||||
`tabDelivery Note Item`
|
||||
where
|
||||
docstatus=1 and against_sales_invoice is not null and against_sales_invoice != ''
|
||||
and against_sales_invoice in (%s)
|
||||
group by against_sales_invoice
|
||||
""" %(','.join(['%s'] * len(voucher_nos))), tuple(voucher_nos) , as_dict=1):
|
||||
if si.parent in dn_details:
|
||||
dn_details[si.parent] += ', %s' %(si.dn)
|
||||
else:
|
||||
dn_details.setdefault(si.parent, si.dn)
|
||||
|
||||
return dn_details
|
||||
|
||||
def get_voucher_details(party_type, voucher_nos, dn_details):
|
||||
voucher_details = frappe._dict()
|
||||
|
||||
if party_type == "Customer":
|
||||
for si in frappe.db.sql("""select name, due_date, po_no
|
||||
from `tabSales Invoice` where docstatus=1 and name in (%s)
|
||||
""" %(','.join(['%s'] *len(voucher_nos))), (tuple(voucher_nos)), as_dict=1):
|
||||
si['delivery_note'] = dn_details.get(si.name)
|
||||
voucher_details.setdefault(si.name, si)
|
||||
|
||||
if party_type == "Supplier":
|
||||
for pi in frappe.db.sql("""select name, due_date, bill_no, bill_date
|
||||
from `tabPurchase Invoice` where docstatus = 1 and name in (%s)
|
||||
""" %(','.join(['%s'] *len(voucher_nos))), (tuple(voucher_nos)), as_dict=1):
|
||||
voucher_details.setdefault(pi.name, pi)
|
||||
|
||||
for pi in frappe.db.sql("""select name, due_date, bill_no, bill_date from
|
||||
`tabJournal Entry` where docstatus = 1 and bill_no is not NULL and name in (%s)
|
||||
""" %(','.join(['%s'] *len(voucher_nos))), (tuple(voucher_nos)), as_dict=1):
|
||||
voucher_details.setdefault(pi.name, pi)
|
||||
|
||||
return voucher_details
|
||||
|
||||
@@ -3,47 +3,75 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils import flt
|
||||
from frappe import _
|
||||
|
||||
def execute(filters=None):
|
||||
columns, data = get_columns(), get_data(filters)
|
||||
return columns, data
|
||||
|
||||
|
||||
def get_data(filters):
|
||||
data = frappe.db.sql("""
|
||||
select
|
||||
a.name as asset, a.asset_category, a.status,
|
||||
a.depreciation_method, a.purchase_date, a.gross_purchase_amount,
|
||||
ds.schedule_date as depreciation_date, ds.depreciation_amount,
|
||||
ds.accumulated_depreciation_amount,
|
||||
(a.gross_purchase_amount - ds.accumulated_depreciation_amount) as amount_after_depreciation,
|
||||
ds.journal_entry as depreciation_entry
|
||||
from
|
||||
`tabAsset` a, `tabDepreciation Schedule` ds
|
||||
where
|
||||
a.name = ds.parent
|
||||
and a.docstatus=1
|
||||
and ifnull(ds.journal_entry, '') != ''
|
||||
and ds.schedule_date between %(from_date)s and %(to_date)s
|
||||
and a.company = %(company)s
|
||||
{conditions}
|
||||
order by
|
||||
a.name asc, ds.schedule_date asc
|
||||
""".format(conditions=get_filter_conditions(filters)), filters, as_dict=1)
|
||||
|
||||
return data
|
||||
|
||||
def get_filter_conditions(filters):
|
||||
conditions = ""
|
||||
|
||||
data = []
|
||||
depreciation_accounts = frappe.db.sql_list(""" select name from tabAccount
|
||||
where ifnull(account_type, '') = 'Depreciation' """)
|
||||
|
||||
filters_data = [["company", "=", filters.get('company')],
|
||||
["posting_date", ">=", filters.get('from_date')],
|
||||
["posting_date", "<=", filters.get('to_date')],
|
||||
["against_voucher_type", "=", "Asset"],
|
||||
["account", "in", depreciation_accounts]]
|
||||
|
||||
if filters.get("asset"):
|
||||
conditions += " and a.name = %(asset)s"
|
||||
|
||||
filters_data.append(["against_voucher", "=", filters.get("asset")])
|
||||
|
||||
if filters.get("asset_category"):
|
||||
conditions += " and a.asset_category = %(asset_category)s"
|
||||
|
||||
return conditions
|
||||
assets = frappe.db.sql_list("""select name from tabAsset
|
||||
where asset_category = %s and docstatus=1""", filters.get("asset_category"))
|
||||
|
||||
filters_data.append(["against_voucher", "in", assets])
|
||||
|
||||
gl_entries = frappe.get_all('GL Entry',
|
||||
filters= filters_data,
|
||||
fields = ["against_voucher", "debit_in_account_currency as debit", "voucher_no", "posting_date"],
|
||||
order_by= "against_voucher, posting_date")
|
||||
|
||||
if not gl_entries:
|
||||
return data
|
||||
|
||||
assets = [d.against_voucher for d in gl_entries]
|
||||
assets_details = get_assets_details(assets)
|
||||
|
||||
for d in gl_entries:
|
||||
asset_data = assets_details.get(d.against_voucher)
|
||||
if not asset_data.get("accumulated_depreciation_amount"):
|
||||
asset_data.accumulated_depreciation_amount = d.debit
|
||||
else:
|
||||
asset_data.accumulated_depreciation_amount += d.debit
|
||||
|
||||
row = frappe._dict(asset_data)
|
||||
row.update({
|
||||
"depreciation_amount": d.debit,
|
||||
"depreciation_date": d.posting_date,
|
||||
"amount_after_depreciation": (flt(row.gross_purchase_amount) -
|
||||
flt(row.accumulated_depreciation_amount)),
|
||||
"depreciation_entry": d.voucher_no
|
||||
})
|
||||
|
||||
data.append(row)
|
||||
|
||||
return data
|
||||
|
||||
def get_assets_details(assets):
|
||||
assets_details = {}
|
||||
|
||||
fields = ["name as asset", "gross_purchase_amount",
|
||||
"asset_category", "status", "depreciation_method", "purchase_date"]
|
||||
|
||||
for d in frappe.get_all("Asset", fields = fields, filters = {'name': ('in', assets)}):
|
||||
assets_details.setdefault(d.asset, d)
|
||||
|
||||
return assets_details
|
||||
|
||||
def get_columns():
|
||||
return [
|
||||
{
|
||||
|
||||
@@ -39,6 +39,12 @@ frappe.query_reports["Budget Variance Report"] = {
|
||||
options: ["Cost Center", "Project"],
|
||||
default: "Cost Center",
|
||||
reqd: 1
|
||||
}
|
||||
},
|
||||
{
|
||||
fieldname: "cost_center",
|
||||
label: __("Cost Center"),
|
||||
fieldtype: "Link",
|
||||
options: "Cost Center"
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -10,9 +10,13 @@ from erpnext.controllers.trends import get_period_date_ranges, get_period_month_
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
|
||||
validate_filters(filters)
|
||||
columns = get_columns(filters)
|
||||
cost_centers = get_cost_centers(filters)
|
||||
if filters.get("cost_center"):
|
||||
cost_centers = [filters.get("cost_center")]
|
||||
else:
|
||||
cost_centers = get_cost_centers(filters)
|
||||
|
||||
period_month_ranges = get_period_month_ranges(filters["period"], filters["fiscal_year"])
|
||||
cam_map = get_cost_center_account_month_map(filters)
|
||||
|
||||
@@ -39,6 +43,10 @@ def execute(filters=None):
|
||||
|
||||
return columns, data
|
||||
|
||||
def validate_filters(filters):
|
||||
if filters.get("budget_against")=="Project" and filters.get("cost_center"):
|
||||
frappe.throw(_("Filter based on Cost Center is only applicable if Budget Against is selected as Cost Center"))
|
||||
|
||||
def get_columns(filters):
|
||||
columns = [_(filters.get("budget_against")) + ":Link/%s:120"%(filters.get("budget_against")), _("Account") + ":Link/Account:120"]
|
||||
|
||||
@@ -66,12 +74,16 @@ def get_cost_centers(filters):
|
||||
|
||||
#Get cost center & target details
|
||||
def get_cost_center_target_details(filters):
|
||||
cond = ""
|
||||
if filters.get("cost_center"):
|
||||
cond += " and b.cost_center='%s'" % frappe.db.escape(filters.get("cost_center"))
|
||||
|
||||
return frappe.db.sql("""
|
||||
select b.{budget_against} as budget_against, b.monthly_distribution, ba.account, ba.budget_amount
|
||||
from `tabBudget` b, `tabBudget Account` ba
|
||||
where b.name=ba.parent and b.docstatus = 1 and b.fiscal_year=%s
|
||||
and b.budget_against = %s and b.company=%s
|
||||
""".format(budget_against=filters.get("budget_against").replace(" ", "_").lower()),
|
||||
and b.budget_against = %s and b.company=%s {cond}
|
||||
""".format(budget_against=filters.get("budget_against").replace(" ", "_").lower(), cond=cond),
|
||||
(filters.fiscal_year, filters.budget_against, filters.company), as_dict=True)
|
||||
|
||||
#Get target distribution details of accounts of cost center
|
||||
|
||||
@@ -185,14 +185,15 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency):
|
||||
has_value = False
|
||||
total = 0
|
||||
row = frappe._dict({
|
||||
"account_name": _(d.account_name),
|
||||
"account": _(d.name),
|
||||
"parent_account": _(d.parent_account),
|
||||
"indent": flt(d.indent),
|
||||
"year_start_date": year_start_date,
|
||||
"year_end_date": year_end_date,
|
||||
"currency": company_currency,
|
||||
"opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be=="Debit" else -1)
|
||||
"opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be=="Debit" else -1),
|
||||
"account_name": ('{} - {}'.format(_(d.account_number), _(d.account_name))
|
||||
if d.account_number else _(d.account_name))
|
||||
})
|
||||
for period in period_list:
|
||||
if d.get(period.key) and balance_must_be=="Credit":
|
||||
@@ -253,7 +254,7 @@ def add_total_row(out, root_type, balance_must_be, period_list, company_currency
|
||||
out.append({})
|
||||
|
||||
def get_accounts(company, root_type):
|
||||
return frappe.db.sql("""select name, parent_account, lft, rgt, root_type, report_type, account_name from `tabAccount`
|
||||
return frappe.db.sql("""select name, account_number, parent_account, lft, rgt, root_type, report_type, account_name from `tabAccount`
|
||||
where company=%s and root_type=%s order by lft""", (company, root_type), as_dict=True)
|
||||
|
||||
def filter_accounts(accounts, depth=10):
|
||||
|
||||
@@ -171,7 +171,7 @@ class GrossProfitGenerator(object):
|
||||
row.qty += returned_item_row.qty
|
||||
row.base_amount += returned_item_row.base_amount
|
||||
row.buying_amount = row.qty * row.buying_rate
|
||||
if row.qty:
|
||||
if row.qty or row.base_amount:
|
||||
row = self.set_average_rate(row)
|
||||
self.grouped_data.append(row)
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
delivery_note, d.income_account, d.cost_center, d.stock_qty, d.stock_uom
|
||||
]
|
||||
|
||||
row += [d.base_net_rate/d.stock_qty, d.base_net_amount] \
|
||||
row += [(d.base_net_rate * d.qty)/d.stock_qty, d.base_net_amount] \
|
||||
if d.stock_uom != d.uom else [d.base_net_rate, d.base_net_amount]
|
||||
|
||||
total_tax = 0
|
||||
@@ -133,7 +133,7 @@ def get_items(filters, additional_query_columns):
|
||||
`tabSales Invoice Item`.stock_uom, `tabSales Invoice Item`.base_net_rate,
|
||||
`tabSales Invoice Item`.base_net_amount, `tabSales Invoice`.customer_name,
|
||||
`tabSales Invoice`.customer_group, `tabSales Invoice Item`.so_detail,
|
||||
`tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom {0}
|
||||
`tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom, `tabSales Invoice Item`.qty {0}
|
||||
from `tabSales Invoice`, `tabSales Invoice Item`
|
||||
where `tabSales Invoice`.name = `tabSales Invoice Item`.parent
|
||||
and `tabSales Invoice`.docstatus = 1 %s %s
|
||||
@@ -157,6 +157,9 @@ def get_delivery_notes_against_sales_order(item_list):
|
||||
|
||||
return so_dn_map
|
||||
|
||||
def get_deducted_taxes():
|
||||
return frappe.db.sql_list("select name from `tabPurchase Taxes and Charges` where add_deduct_tax = 'Deduct'")
|
||||
|
||||
def get_tax_accounts(item_list, columns, company_currency,
|
||||
doctype="Sales Invoice", tax_doctype="Sales Taxes and Charges"):
|
||||
import json
|
||||
@@ -176,9 +179,10 @@ def get_tax_accounts(item_list, columns, company_currency,
|
||||
if doctype == "Purchase Invoice":
|
||||
conditions = " and category in ('Total', 'Valuation and Total') and base_tax_amount_after_discount_amount != 0"
|
||||
|
||||
deducted_tax = get_deducted_taxes()
|
||||
tax_details = frappe.db.sql("""
|
||||
select
|
||||
parent, description, item_wise_tax_detail,
|
||||
name, parent, description, item_wise_tax_detail,
|
||||
charge_type, base_tax_amount_after_discount_amount
|
||||
from `tab%s`
|
||||
where
|
||||
@@ -190,7 +194,7 @@ def get_tax_accounts(item_list, columns, company_currency,
|
||||
""" % (tax_doctype, '%s', ', '.join(['%s']*len(invoice_item_row)), conditions),
|
||||
tuple([doctype] + invoice_item_row.keys()))
|
||||
|
||||
for parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
|
||||
for name, parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
|
||||
description = handle_html(description)
|
||||
if description not in tax_columns and tax_amount:
|
||||
# as description is text editor earlier and markup can break the column convention in reports
|
||||
@@ -219,9 +223,13 @@ def get_tax_accounts(item_list, columns, company_currency,
|
||||
item_tax_amount = flt((tax_amount * d.base_net_amount) / item_net_amount) \
|
||||
if item_net_amount else 0
|
||||
if item_tax_amount:
|
||||
tax_value = flt(item_tax_amount, tax_amount_precision)
|
||||
tax_value = (tax_value * -1
|
||||
if (doctype == 'Purchase Invoice' and name in deducted_tax) else tax_value)
|
||||
|
||||
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
|
||||
"tax_rate": tax_rate,
|
||||
"tax_amount": flt(item_tax_amount, tax_amount_precision)
|
||||
"tax_amount": tax_value
|
||||
})
|
||||
|
||||
except ValueError:
|
||||
|
||||
@@ -51,7 +51,7 @@ def validate_filters(filters):
|
||||
filters.to_date = filters.year_end_date
|
||||
|
||||
def get_data(filters):
|
||||
accounts = frappe.db.sql("""select name, parent_account, account_name, root_type, report_type, lft, rgt
|
||||
accounts = frappe.db.sql("""select name, account_number, parent_account, account_name, root_type, report_type, lft, rgt
|
||||
from `tabAccount` where company=%s order by lft""", filters.company, as_dict=True)
|
||||
company_currency = erpnext.get_company_currency(filters.company)
|
||||
|
||||
@@ -162,8 +162,6 @@ def calculate_values(accounts, gl_entries_by_account, opening_balances, filters,
|
||||
total_row["credit"] += d["credit"]
|
||||
total_row["opening_debit"] += d["opening_debit"]
|
||||
total_row["opening_credit"] += d["opening_credit"]
|
||||
total_row["closing_debit"] += (d["opening_debit"] + d["debit"])
|
||||
total_row["closing_credit"] += (d["opening_credit"] + d["credit"])
|
||||
|
||||
return total_row
|
||||
|
||||
@@ -176,16 +174,19 @@ def accumulate_values_into_parents(accounts, accounts_by_name):
|
||||
def prepare_data(accounts, filters, total_row, parent_children_map, company_currency):
|
||||
data = []
|
||||
|
||||
total_row["closing_debit"] = total_row["closing_credit"] = 0
|
||||
|
||||
for d in accounts:
|
||||
has_value = False
|
||||
row = {
|
||||
"account_name": d.account_name,
|
||||
"account": d.name,
|
||||
"parent_account": d.parent_account,
|
||||
"indent": d.indent,
|
||||
"from_date": filters.from_date,
|
||||
"to_date": filters.to_date,
|
||||
"currency": company_currency
|
||||
"currency": company_currency,
|
||||
"account_name": ('{} - {}'.format(d.account_number, d.account_name)
|
||||
if d.account_number else d.account_name)
|
||||
}
|
||||
|
||||
prepare_opening_and_closing(d)
|
||||
@@ -200,6 +201,10 @@ def prepare_data(accounts, filters, total_row, parent_children_map, company_curr
|
||||
row["has_value"] = has_value
|
||||
data.append(row)
|
||||
|
||||
if not d.parent_account:
|
||||
total_row["closing_debit"] += (d["debit"] - d["credit"]) if (d["debit"] - d["credit"]) > 0 else 0
|
||||
total_row["closing_credit"] += abs(d["debit"] - d["credit"]) if (d["debit"] - d["credit"]) < 0 else 0
|
||||
|
||||
data.extend([{},total_row])
|
||||
|
||||
return data
|
||||
|
||||
@@ -23,6 +23,14 @@ frappe.ui.form.on('Asset', {
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("cost_center", function() {
|
||||
return {
|
||||
"filters": {
|
||||
"company": frm.doc.company,
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
@@ -59,11 +67,33 @@ frappe.ui.form.on('Asset', {
|
||||
frm.trigger("create_asset_maintenance");
|
||||
}, __("Make"));
|
||||
}
|
||||
|
||||
if (!frm.doc.calculate_depreciation) {
|
||||
frm.add_custom_button(__("Depreciation Entry"), function() {
|
||||
frm.trigger("make_journal_entry");
|
||||
}, __("Make"));
|
||||
}
|
||||
|
||||
frm.page.set_inner_btn_group_as_primary(__("Make"));
|
||||
frm.trigger("setup_chart");
|
||||
}
|
||||
},
|
||||
|
||||
make_journal_entry: function(frm) {
|
||||
frappe.call({
|
||||
method: "erpnext.assets.doctype.asset.asset.make_journal_entry",
|
||||
args: {
|
||||
asset_name: frm.doc.name
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message) {
|
||||
var doclist = frappe.model.sync(r.message);
|
||||
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
setup_chart: function(frm) {
|
||||
var x_intervals = [frm.doc.purchase_date];
|
||||
var asset_values = [frm.doc.gross_purchase_amount];
|
||||
|
||||
@@ -415,6 +415,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "cost_center",
|
||||
"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": "Cost Center",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Cost Center",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -1221,7 +1252,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-19 12:58:44.137460",
|
||||
"modified": "2018-07-17 06:30:25.506194",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Assets",
|
||||
"name": "Asset",
|
||||
|
||||
@@ -283,3 +283,34 @@ def get_item_details(item_code):
|
||||
})
|
||||
|
||||
return ret
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_journal_entry(asset_name):
|
||||
asset = frappe.get_doc("Asset", asset_name)
|
||||
fixed_asset_account, accumulated_depreciation_account, depreciation_expense_account = \
|
||||
get_depreciation_accounts(asset)
|
||||
|
||||
depreciation_cost_center, depreciation_series = frappe.db.get_value("Company", asset.company,
|
||||
["depreciation_cost_center", "series_for_depreciation_entry"])
|
||||
depreciation_cost_center = asset.cost_center or depreciation_cost_center
|
||||
|
||||
je = frappe.new_doc("Journal Entry")
|
||||
je.voucher_type = "Depreciation Entry"
|
||||
je.naming_series = depreciation_series
|
||||
je.company = asset.company
|
||||
je.remark = "Depreciation Entry against asset {0}".format(asset_name)
|
||||
|
||||
je.append("accounts", {
|
||||
"account": depreciation_expense_account,
|
||||
"reference_type": "Asset",
|
||||
"reference_name": asset.name,
|
||||
"cost_center": depreciation_cost_center
|
||||
})
|
||||
|
||||
je.append("accounts", {
|
||||
"account": accumulated_depreciation_account,
|
||||
"reference_type": "Asset",
|
||||
"reference_name": asset.name
|
||||
})
|
||||
|
||||
return je
|
||||
@@ -5,13 +5,13 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import flt, today, getdate
|
||||
from frappe.utils import flt, today, getdate, cint
|
||||
|
||||
def post_depreciation_entries(date=None):
|
||||
# Return if automatic booking of asset depreciation is disabled
|
||||
if not frappe.db.get_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically"):
|
||||
if not cint(frappe.db.get_value("Accounts Settings", None, "book_asset_depreciation_entry_automatically")):
|
||||
return
|
||||
|
||||
|
||||
if not date:
|
||||
date = today()
|
||||
for asset in get_depreciable_assets(date):
|
||||
@@ -38,7 +38,7 @@ def make_depreciation_entry(asset_name, date=None):
|
||||
|
||||
depreciation_cost_center, depreciation_series = frappe.db.get_value("Company", asset.company,
|
||||
["depreciation_cost_center", "series_for_depreciation_entry"])
|
||||
|
||||
depreciation_cost_center = asset.cost_center or depreciation_cost_center
|
||||
|
||||
for d in asset.get("schedules"):
|
||||
if not d.journal_entry and getdate(d.schedule_date) <= getdate(date):
|
||||
@@ -154,6 +154,7 @@ def restore_asset(asset_name):
|
||||
def get_gl_entries_on_asset_disposal(asset, selling_amount=0):
|
||||
fixed_asset_account, accumulated_depr_account, depr_expense_account = get_depreciation_accounts(asset)
|
||||
disposal_account, depreciation_cost_center = get_disposal_account_and_cost_center(asset.company)
|
||||
depreciation_cost_center = asset.cost_center or depreciation_cost_center
|
||||
|
||||
accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(asset.value_after_depreciation)
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ frappe.ui.form.on('Asset Category', {
|
||||
var d = locals[cdt][cdn];
|
||||
return {
|
||||
"filters": {
|
||||
"root_type": "Asset",
|
||||
"account_type": "Accumulated Depreciation",
|
||||
"is_group": 0,
|
||||
"company": d.company_name
|
||||
}
|
||||
@@ -41,4 +41,4 @@ frappe.ui.form.on('Asset Category', {
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "field:maintenance_task",
|
||||
"autoname": "",
|
||||
"beta": 0,
|
||||
"creation": "2017-10-20 07:10:55.903571",
|
||||
"custom": 0,
|
||||
@@ -42,7 +42,7 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 1
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
@@ -625,7 +625,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-28 12:22:34.151430",
|
||||
"modified": "2018-06-18 16:12:04.330021",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Assets",
|
||||
"name": "Asset Maintenance Task",
|
||||
|
||||
@@ -7,4 +7,5 @@ import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class AssetMaintenanceTask(Document):
|
||||
pass
|
||||
def autoname(self):
|
||||
self.name = self.maintenance_task
|
||||
|
||||
@@ -1,231 +1,276 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2013-06-25 11:04:03",
|
||||
"custom": 0,
|
||||
"description": "Settings for Buying Module",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "Other",
|
||||
"editable_grid": 0,
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Supplier Name",
|
||||
"fieldname": "supp_master_name",
|
||||
"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": 0,
|
||||
"label": "Supplier Naming By",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Supplier Name\nNaming Series",
|
||||
"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,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "supplier_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": "Default Supplier Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Supplier Type",
|
||||
"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,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "buying_price_list",
|
||||
"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": "Default Buying Price List",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Price List",
|
||||
"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,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"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,
|
||||
"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_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "po_required",
|
||||
"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": 0,
|
||||
"label": "Purchase Order Required",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "No\nYes",
|
||||
"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,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "pr_required",
|
||||
"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": 0,
|
||||
"label": "Purchase Receipt Required",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "No\nYes",
|
||||
"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,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "maintain_same_rate",
|
||||
"fieldtype": "Check",
|
||||
"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": "Maintain same rate throughout purchase cycle",
|
||||
"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,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "allow_multiple_items",
|
||||
"fieldtype": "Check",
|
||||
"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": "Allow Item to be added multiple times in a 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": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"description": "If enabled, last purchase details of items will not be fetched from previous purchase order or purchase receipt",
|
||||
"fieldname": "disable_fetch_last_purchase_rate",
|
||||
"fieldtype": "Check",
|
||||
"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": "Disable Fetching Last Purchase Details in Purchase Order",
|
||||
"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,
|
||||
"icon": "fa fa-cog",
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"modified": "2017-12-27 15:20:06.052342",
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-07-18 07:52:38.062488",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Buying Settings",
|
||||
@@ -252,6 +297,10 @@
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -32,12 +32,7 @@ frappe.ui.form.on("Purchase Order", {
|
||||
erpnext.queries.setup_queries(frm, "Warehouse", function() {
|
||||
return erpnext.queries.warehouse(frm.doc);
|
||||
});
|
||||
|
||||
if (frm.doc.__onload) {
|
||||
frm.toggle_display('get_last_purchase_rate',
|
||||
frm.doc.__onload.disable_fetch_last_purchase_rate);
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Purchase Order Item", {
|
||||
@@ -318,6 +313,73 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
||||
})
|
||||
}, __("Add items from"));
|
||||
|
||||
this.frm.add_custom_button(__('Update rate as per last purchase'),
|
||||
function() {
|
||||
frappe.call({
|
||||
"method": "get_last_purchase_rate",
|
||||
"doc": me.frm.doc,
|
||||
callback: function(r, rt) {
|
||||
me.frm.dirty();
|
||||
me.frm.cscript.calculate_taxes_and_totals();
|
||||
}
|
||||
})
|
||||
}, __("Tools"));
|
||||
|
||||
this.frm.add_custom_button(__('Link to Material Request'),
|
||||
function() {
|
||||
var my_items = [];
|
||||
for (var i in me.frm.doc.items) {
|
||||
if(!me.frm.doc.items[i].material_request){
|
||||
my_items.push(me.frm.doc.items[i].item_code);
|
||||
}
|
||||
}
|
||||
frappe.call({
|
||||
method: "erpnext.buying.utils.get_linked_material_requests",
|
||||
args:{
|
||||
items: my_items
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.exc) return;
|
||||
|
||||
var i = 0;
|
||||
var item_length = me.frm.doc.items.length;
|
||||
while (i < item_length) {
|
||||
var qty = me.frm.doc.items[i].qty;
|
||||
(r.message[0] || []).forEach(function(d) {
|
||||
if (d.qty > 0 && qty > 0 && me.frm.doc.items[i].item_code == d.item_code && !me.frm.doc.items[i].material_request_item)
|
||||
{
|
||||
me.frm.doc.items[i].material_request = d.mr_name;
|
||||
me.frm.doc.items[i].material_request_item = d.mr_item;
|
||||
var my_qty = Math.min(qty, d.qty);
|
||||
qty = qty - my_qty;
|
||||
d.qty = d.qty - my_qty;
|
||||
me.frm.doc.items[i].stock_qty = my_qty * me.frm.doc.items[i].conversion_factor;
|
||||
me.frm.doc.items[i].qty = my_qty;
|
||||
|
||||
frappe.msgprint("Assigning " + d.mr_name + " to " + d.item_code + " (row " + me.frm.doc.items[i].idx + ")");
|
||||
if (qty > 0) {
|
||||
frappe.msgprint("Splitting " + qty + " units of " + d.item_code);
|
||||
var new_row = frappe.model.add_child(me.frm.doc, me.frm.doc.items[i].doctype, "items");
|
||||
item_length++;
|
||||
|
||||
for (var key in me.frm.doc.items[i]) {
|
||||
new_row[key] = me.frm.doc.items[i][key];
|
||||
}
|
||||
|
||||
new_row.idx = item_length;
|
||||
new_row["stock_qty"] = new_row.conversion_factor * qty;
|
||||
new_row["qty"] = qty;
|
||||
new_row["material_request"] = "";
|
||||
new_row["material_request_item"] = "";
|
||||
}
|
||||
}
|
||||
});
|
||||
i++;
|
||||
}
|
||||
refresh_field("items");
|
||||
}
|
||||
});
|
||||
}, __("Tools"));
|
||||
},
|
||||
|
||||
tc_name: function() {
|
||||
@@ -346,17 +408,6 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
|
||||
cur_frm.cscript.update_status('Deliver', 'Delivered')
|
||||
},
|
||||
|
||||
get_last_purchase_rate: function() {
|
||||
frappe.call({
|
||||
"method": "get_last_purchase_rate",
|
||||
"doc": cur_frm.doc,
|
||||
callback: function(r, rt) {
|
||||
cur_frm.dirty();
|
||||
cur_frm.cscript.calculate_taxes_and_totals();
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
items_on_form_rendered: function() {
|
||||
set_schedule_date(this.frm);
|
||||
},
|
||||
|
||||
@@ -1207,7 +1207,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_bulk_edit": 1,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1238,68 +1238,6 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.docstatus===0 && (doc.items && doc.items.length)",
|
||||
"fieldname": "get_last_purchase_rate",
|
||||
"fieldtype": "Button",
|
||||
"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": "Get last purchase rate",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.docstatus===0 && (doc.items && doc.items.length)",
|
||||
"fieldname": "link_to_mrs",
|
||||
"fieldtype": "Button",
|
||||
"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": "Link to material requests",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2440,6 +2378,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "rounded_total",
|
||||
"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": "Rounded Total",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "currency",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2471,6 +2440,36 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "disable_rounded_total",
|
||||
"fieldtype": "Check",
|
||||
"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": "Disable Rounded Total",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -3355,7 +3354,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-02-17 11:00:05.037716",
|
||||
"modified": "2018-08-01 15:18:33.155409",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order",
|
||||
|
||||
@@ -33,12 +33,6 @@ class PurchaseOrder(BuyingController):
|
||||
'percent_join_field': 'material_request'
|
||||
}]
|
||||
|
||||
def onload(self):
|
||||
super(PurchaseOrder, self).onload()
|
||||
|
||||
self.set_onload('disable_fetch_last_purchase_rate',
|
||||
cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")))
|
||||
|
||||
def validate(self):
|
||||
super(PurchaseOrder, self).validate()
|
||||
|
||||
@@ -122,7 +116,6 @@ class PurchaseOrder(BuyingController):
|
||||
|
||||
def get_last_purchase_rate(self):
|
||||
"""get last purchase rates for all items"""
|
||||
if cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")): return
|
||||
|
||||
conversion_rate = flt(self.get('conversion_rate')) or 1.0
|
||||
for d in self.get("items"):
|
||||
@@ -286,7 +279,6 @@ class PurchaseOrder(BuyingController):
|
||||
|
||||
def item_last_purchase_rate(name, conversion_rate, item_code, conversion_factor= 1.0):
|
||||
"""get last purchase rate for an item"""
|
||||
if cint(frappe.db.get_single_value("Buying Settings", "disable_fetch_last_purchase_rate")): return
|
||||
|
||||
conversion_rate = flt(conversion_rate) or 1.0
|
||||
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
QUnit.module('Buying');
|
||||
|
||||
QUnit.test("test: purchase order with last purchase rate", function(assert) {
|
||||
assert.expect(9);
|
||||
let done = assert.async();
|
||||
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{is_subcontracted: 'No'},
|
||||
{currency: 'INR'},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": 'Test Product 4'},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"qty": 1},
|
||||
{"rate": 800},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
],
|
||||
[
|
||||
{"item_code": 'Test Product 1'},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"qty": 1},
|
||||
{"rate": 400},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
|
||||
() => {
|
||||
// Get item details
|
||||
assert.ok(cur_frm.doc.items[0].item_name == 'Test Product 4', "Item 1 name correct");
|
||||
assert.ok(cur_frm.doc.items[1].item_name == 'Test Product 1', "Item 2 name correct");
|
||||
},
|
||||
|
||||
() => frappe.timeout(1),
|
||||
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(3),
|
||||
|
||||
() => frappe.tests.click_button('Close'),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{is_subcontracted: 'No'},
|
||||
{currency: 'INR'},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": 'Test Product 4'},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"qty": 1},
|
||||
{"rate": 600},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
],
|
||||
[
|
||||
{"item_code": 'Test Product 1'},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"qty": 1},
|
||||
{"rate": 200},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
|
||||
() => frappe.timeout(2),
|
||||
|
||||
// Get the last purchase rate of items
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.items[0].last_purchase_rate == 800, "Last purchase rate of item 1 correct");
|
||||
assert.ok(cur_frm.doc.items[1].last_purchase_rate != 0);
|
||||
},
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.items[1].last_purchase_rate == 400, "Last purchase rate of item 2 correct");
|
||||
assert.ok(cur_frm.doc.items[1].last_purchase_rate != 0);
|
||||
},
|
||||
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(3),
|
||||
|
||||
() => frappe.tests.click_button('Close'),
|
||||
|
||||
() => frappe.timeout(1),
|
||||
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.status == 'To Receive and Bill', "Submitted successfully");
|
||||
},
|
||||
|
||||
// enable allow_last_purchase_rate
|
||||
() => {
|
||||
return frappe.tests.make('Buying Settings', [
|
||||
// values to be set
|
||||
{"disable_fetch_last_purchase_rate": 1}
|
||||
]);
|
||||
},
|
||||
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{is_subcontracted: 'No'},
|
||||
{currency: 'INR'},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": 'Test Product 4'},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"qty": 1},
|
||||
{"rate": 800},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
],
|
||||
[
|
||||
{"item_code": 'Test Product 1'},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"qty": 1},
|
||||
{"rate": 400},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
|
||||
() => {
|
||||
// Get item details
|
||||
assert.ok(cur_frm.doc.items[0].last_purchase_rate == 0);
|
||||
assert.ok(cur_frm.doc.items[1].last_purchase_rate == 0);
|
||||
},
|
||||
|
||||
() => frappe.timeout(1),
|
||||
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(3),
|
||||
|
||||
() => frappe.tests.click_button('Close'),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
// enable allow_last_purchase_rate
|
||||
() => frappe.tests.make('Buying Settings', [
|
||||
// values to be set
|
||||
{"disable_fetch_last_purchase_rate": 0}
|
||||
]),
|
||||
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -629,6 +629,38 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "discount_percentage",
|
||||
"fieldname": "discount_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": "Discount Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "currency",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -680,7 +712,7 @@
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
@@ -1897,7 +1929,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-12-14 09:36:40.837027",
|
||||
"modified": "2018-08-06 05:16:58.258276",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order Item",
|
||||
|
||||
@@ -781,7 +781,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_bulk_edit": 1,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1983,6 +1983,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "rounded_total",
|
||||
"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": "Rounded Total",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "currency",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2014,6 +2045,36 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "disable_rounded_total",
|
||||
"fieldtype": "Check",
|
||||
"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": "Disable Rounded Total",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2177,65 +2238,65 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "group_same_items",
|
||||
"fieldtype": "Check",
|
||||
"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": "Group same items",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"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,
|
||||
"fieldname": "group_same_items",
|
||||
"fieldtype": "Check",
|
||||
"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": "Group same items",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_72",
|
||||
"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,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_72",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "letter_head",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@@ -2549,7 +2610,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2018-05-28 02:45:48.616334",
|
||||
"modified": "2018-08-01 15:18:23.265621",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Supplier Quotation",
|
||||
|
||||
@@ -60,7 +60,12 @@ class SupplierQuotation(BuyingController):
|
||||
for rfq in rfq_list:
|
||||
doc = frappe.get_doc('Request for Quotation', rfq)
|
||||
doc_sup = frappe.get_all('Request for Quotation Supplier', filters=
|
||||
{'parent': doc.name, 'supplier': self.supplier}, fields=['name', 'quote_status'])[0]
|
||||
{'parent': doc.name, 'supplier': self.supplier}, fields=['name', 'quote_status'])
|
||||
|
||||
doc_sup = doc_sup[0] if doc_sup else None
|
||||
if not doc_sup:
|
||||
frappe.throw(_("Supplier {0} not found in {1}").format(self.supplier,
|
||||
"<a href='desk#Form/Request for Quotation/{0}'> Request for Quotation {0} </a>".format(doc.name)))
|
||||
|
||||
quote_status = _('Received')
|
||||
for item in doc.items:
|
||||
@@ -152,4 +157,4 @@ def make_quotation(source_name, target_doc=None):
|
||||
}
|
||||
}, target_doc)
|
||||
|
||||
return doclist
|
||||
return doclist
|
||||
|
||||
@@ -470,6 +470,38 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "discount_percentage",
|
||||
"fieldname": "discount_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": "Discount Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "currency",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -1645,7 +1677,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-01-25 15:04:40.171617",
|
||||
"modified": "2018-08-06 05:33:07.404385",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Supplier Quotation Item",
|
||||
|
||||
@@ -291,14 +291,6 @@ def get_data():
|
||||
"label": _("Healthcare"),
|
||||
"hidden": 1
|
||||
},
|
||||
{
|
||||
"module_name": "Hub",
|
||||
"color": "#009248",
|
||||
"icon": "/assets/erpnext/images/hub_logo.svg",
|
||||
"type": "page",
|
||||
"link": "hub",
|
||||
"label": _("Hub")
|
||||
},
|
||||
{
|
||||
"module_name": "Data Import",
|
||||
"color": "#FFF168",
|
||||
|
||||
@@ -36,13 +36,13 @@ def get_data():
|
||||
"items": [
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Job Applicant",
|
||||
"description": _("Applicant for a Job."),
|
||||
"name": "Job Opening",
|
||||
"description": _("Opening for a Job."),
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Job Opening",
|
||||
"description": _("Opening for a Job."),
|
||||
"name": "Job Applicant",
|
||||
"description": _("Applicant for a Job."),
|
||||
},
|
||||
{
|
||||
"type": "doctype",
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
from __future__ import unicode_literals
|
||||
from frappe import _
|
||||
|
||||
def get_data():
|
||||
return [
|
||||
{
|
||||
"label": _("Setup"),
|
||||
"items": [
|
||||
{
|
||||
"type": "doctype",
|
||||
"name": "Hub Settings"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": _("Hub"),
|
||||
"items": [
|
||||
{
|
||||
"type": "page",
|
||||
"name": "hub"
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
@@ -131,14 +131,18 @@ class AccountsController(TransactionBase):
|
||||
self.meta.get_label(date_field), self)
|
||||
|
||||
def validate_due_date(self):
|
||||
if self.get('is_pos'): return
|
||||
|
||||
from erpnext.accounts.party import validate_due_date
|
||||
if self.doctype == "Sales Invoice":
|
||||
if not self.due_date:
|
||||
frappe.throw(_("Due Date is mandatory"))
|
||||
|
||||
validate_due_date(self.posting_date, self.due_date, "Customer", self.customer, self.company)
|
||||
validate_due_date(self.posting_date, self.due_date,
|
||||
"Customer", self.customer, self.company, self.payment_terms_template)
|
||||
elif self.doctype == "Purchase Invoice":
|
||||
validate_due_date(self.posting_date, self.due_date, "Supplier", self.supplier, self.company)
|
||||
validate_due_date(self.posting_date, self.due_date,
|
||||
"Supplier", self.supplier, self.company, self.payment_terms_template)
|
||||
|
||||
def set_price_list_currency(self, buying_or_selling):
|
||||
if self.meta.get_field("posting_date"):
|
||||
|
||||
@@ -99,9 +99,16 @@ class BuyingController(StockController):
|
||||
def set_total_in_words(self):
|
||||
from frappe.utils import money_in_words
|
||||
if self.meta.get_field("base_in_words"):
|
||||
self.base_in_words = money_in_words(self.base_grand_total, self.company_currency)
|
||||
amount = (self.base_rounded_total
|
||||
if not self.get("disable_rounded_total") else self.base_grand_total)
|
||||
|
||||
self.base_in_words = money_in_words(amount, self.company_currency)
|
||||
|
||||
if self.meta.get_field("in_words"):
|
||||
self.in_words = money_in_words(self.grand_total, self.currency)
|
||||
amount = (self.rounded_total
|
||||
if not self.get("disable_rounded_total") else self.grand_total)
|
||||
|
||||
self.in_words = money_in_words(amount, self.currency)
|
||||
|
||||
# update valuation rate
|
||||
def update_valuation_rate(self, parentfield):
|
||||
@@ -459,6 +466,7 @@ class BuyingController(StockController):
|
||||
|
||||
def validate_items(self):
|
||||
# validate items to see if they have is_purchase_item or is_subcontracted_item enabled
|
||||
if self.doctype=="Material Request": return
|
||||
|
||||
if hasattr(self, "is_subcontracted") and self.is_subcontracted == 'Yes':
|
||||
validate_item_type(self, "is_sub_contracted_item", "subcontracted")
|
||||
|
||||
@@ -176,6 +176,14 @@ def create_variant(item, args):
|
||||
@frappe.whitelist()
|
||||
def enqueue_multiple_variant_creation(item, args):
|
||||
# There can be innumerable attribute combinations, enqueue
|
||||
if isinstance(args, basestring):
|
||||
variants = json.loads(args)
|
||||
total_variants = 1
|
||||
for key in variants:
|
||||
total_variants *= len(variants[key])
|
||||
if total_variants >= 600:
|
||||
frappe.msgprint("Please do not create more than 500 items at a time", raise_exception=1)
|
||||
return
|
||||
frappe.enqueue("erpnext.controllers.item_variant.create_multiple_variants",
|
||||
item=item, args=args, now=frappe.flags.in_test);
|
||||
|
||||
|
||||
@@ -218,7 +218,8 @@ def bom(doctype, txt, searchfield, start, page_len, filters):
|
||||
def get_project_name(doctype, txt, searchfield, start, page_len, filters):
|
||||
cond = ''
|
||||
if filters.get('customer'):
|
||||
cond = '(`tabProject`.customer = "' + filters['customer'] + '" or ifnull(`tabProject`.customer,"")="") and'
|
||||
cond = """(`tabProject`.customer = '%s' or
|
||||
ifnull(`tabProject`.customer,"")="") and""" %(frappe.db.escape(filters.get("customer")))
|
||||
|
||||
return frappe.db.sql("""select `tabProject`.name from `tabProject`
|
||||
where `tabProject`.status not in ("Completed", "Cancelled")
|
||||
|
||||
@@ -139,7 +139,7 @@ def validate_quantity(doc, args, ref, valid_items, already_returned_items):
|
||||
.format(args.item_code), StockOverReturnError)
|
||||
elif abs(current_stock_qty) > max_returnable_qty:
|
||||
frappe.throw(_("Row # {0}: Cannot return more than {1} for Item {2}")
|
||||
.format(args.idx, reference_qty, args.item_code), StockOverReturnError)
|
||||
.format(args.idx, max_returnable_qty, args.item_code), StockOverReturnError)
|
||||
|
||||
def get_ref_item_dict(valid_items, ref_item_row):
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||
@@ -151,6 +151,7 @@ def get_ref_item_dict(valid_items, ref_item_row):
|
||||
"rejected_qty": 0,
|
||||
"received_qty": 0,
|
||||
"serial_no": [],
|
||||
"conversion_factor": ref_item_row.get("conversion_factor", 1),
|
||||
"batch_no": []
|
||||
}))
|
||||
item_dict = valid_items[ref_item_row.item_code]
|
||||
|
||||
@@ -52,9 +52,15 @@ class SellingController(StockController):
|
||||
def set_missing_lead_customer_details(self):
|
||||
if getattr(self, "customer", None):
|
||||
from erpnext.accounts.party import _get_party_details
|
||||
fetch_payment_terms_template = False
|
||||
if (self.get("__islocal") or
|
||||
self.company != frappe.db.get_value(self.doctype, self.name, 'company')):
|
||||
fetch_payment_terms_template = True
|
||||
|
||||
party_details = _get_party_details(self.customer,
|
||||
ignore_permissions=self.flags.ignore_permissions,
|
||||
doctype=self.doctype, company=self.company)
|
||||
doctype=self.doctype, company=self.company,
|
||||
fetch_payment_terms_template=fetch_payment_terms_template)
|
||||
if not self.meta.get_field("sales_team"):
|
||||
party_details.pop("sales_team")
|
||||
|
||||
|
||||
@@ -51,12 +51,12 @@ def enroll_random_student(current_date):
|
||||
|
||||
def assign_student_group(student, student_name, program, courses, batch):
|
||||
course_list = [d["course"] for d in courses]
|
||||
for d in frappe.get_list("Student Group", fields=("name"), filters={"program": program, "course":("in", course_list)}):
|
||||
for d in frappe.get_list("Student Group", fields=("name"), filters={"program": program, "course":("in", course_list), "disabled": 0}):
|
||||
student_group = frappe.get_doc("Student Group", d.name)
|
||||
student_group.append("students", {"student": student, "student_name": student_name,
|
||||
"group_roll_number":len(student_group.students)+1, "active":1})
|
||||
student_group.save()
|
||||
student_batch = frappe.get_list("Student Group", fields=("name"), filters={"program": program, "group_based_on":"Batch", "batch":batch})[0]
|
||||
student_batch = frappe.get_list("Student Group", fields=("name"), filters={"program": program, "group_based_on":"Batch", "batch":batch, "disabled": 0})[0]
|
||||
student_batch_doc = frappe.get_doc("Student Group", student_batch.name)
|
||||
student_batch_doc.append("students", {"student": student, "student_name": student_name,
|
||||
"group_roll_number":len(student_batch_doc.students)+1, "active":1})
|
||||
@@ -65,7 +65,7 @@ def assign_student_group(student, student_name, program, courses, batch):
|
||||
|
||||
def mark_student_attendance(current_date):
|
||||
status = ["Present", "Absent"]
|
||||
for d in frappe.db.get_list("Student Group", filters={"group_based_on": "Batch"}):
|
||||
for d in frappe.db.get_list("Student Group", filters={"group_based_on": "Batch", "disabled": 0}):
|
||||
students = get_student_group_students(d.name)
|
||||
for stud in students:
|
||||
make_attendance_records(stud.student, stud.student_name, status[weighted_choice([9,4])], None, d.name, current_date)
|
||||
@@ -77,7 +77,7 @@ def make_fees():
|
||||
|
||||
def make_assessment_plan(date):
|
||||
for d in range(1,4):
|
||||
random_group = get_random("Student Group", {"group_based_on": "Course"}, True)
|
||||
random_group = get_random("Student Group", {"group_based_on": "Course", "disabled": 0}, True)
|
||||
doc = frappe.new_doc("Assessment Plan")
|
||||
doc.student_group = random_group.name
|
||||
doc.course = random_group.course
|
||||
|
||||
@@ -88,16 +88,14 @@ def make_attendance_records(student, student_name, status, course_schedule=None,
|
||||
:param course_schedule: Course Schedule.
|
||||
:param status: Status (Present/Absent)
|
||||
"""
|
||||
student_attendance_list = frappe.get_list("Student Attendance", fields = ['name'], filters = {
|
||||
student_attendance = frappe.get_doc({
|
||||
"doctype": "Student Attendance",
|
||||
"student": student,
|
||||
"course_schedule": course_schedule,
|
||||
"student_group": student_group,
|
||||
"date": date
|
||||
})
|
||||
|
||||
if student_attendance_list:
|
||||
student_attendance = frappe.get_doc("Student Attendance", student_attendance_list[0])
|
||||
else:
|
||||
if not student_attendance:
|
||||
student_attendance = frappe.new_doc("Student Attendance")
|
||||
student_attendance.student = student
|
||||
student_attendance.student_name = student_name
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "RES.######",
|
||||
"beta": 0,
|
||||
@@ -662,7 +662,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-01-09 14:14:30.090317",
|
||||
"modified": "2018-08-20 11:21:19.248393",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Assessment Result",
|
||||
|
||||
@@ -195,6 +195,38 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"description": "If enabled, field Academic Term will be Mandatory in Program Enrollment Tool.",
|
||||
"fieldname": "academic_term_reqd",
|
||||
"fieldtype": "Check",
|
||||
"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": "Make Academic Term Mandatory",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -267,7 +299,7 @@
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-28 15:45:30.324324",
|
||||
"modified": "2018-07-26 04:43:35.406690",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Education Settings",
|
||||
|
||||
@@ -31,7 +31,8 @@ frappe.ui.form.on('Fee Schedule', {
|
||||
return {
|
||||
"program": frm.doc.program,
|
||||
"academic_term": frm.doc.academic_term,
|
||||
"academic_year": frm.doc.academic_year
|
||||
"academic_year": frm.doc.academic_year,
|
||||
"disabled": 0
|
||||
};
|
||||
});
|
||||
frappe.realtime.on("fee_schedule_progress", function(data) {
|
||||
|
||||
@@ -671,7 +671,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-12-27 10:59:36.838548",
|
||||
"modified": "2018-07-26 04:44:03.781418",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Program Enrollment",
|
||||
|
||||
@@ -26,7 +26,6 @@ class ProgramEnrollment(Document):
|
||||
"student": self.student,
|
||||
"program": self.program,
|
||||
"academic_year": self.academic_year,
|
||||
"academic_term": self.academic_term,
|
||||
"docstatus": ("<", 2),
|
||||
"name": ("!=", self.name)
|
||||
})
|
||||
@@ -86,7 +85,6 @@ def get_program_courses(doctype, txt, searchfield, start, page_len, filters):
|
||||
"program": filters['program']
|
||||
})
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_students(doctype, txt, searchfield, start, page_len, filters):
|
||||
if not filters.get("academic_term"):
|
||||
|
||||
@@ -5,6 +5,9 @@ frappe.ui.form.on("Program Enrollment Tool", {
|
||||
setup: function(frm) {
|
||||
frm.add_fetch("student", "title", "student_name");
|
||||
frm.add_fetch("student_applicant", "title", "student_name");
|
||||
if(frm.doc.__onload && frm.doc.__onload.academic_term_reqd) {
|
||||
frm.toggle_reqd("academic_term", true);
|
||||
}
|
||||
},
|
||||
|
||||
"refresh": function(frm) {
|
||||
|
||||
@@ -513,7 +513,7 @@
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2018-01-02 11:59:40.230689",
|
||||
"modified": "2018-07-26 04:44:13.232146",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Program Enrollment Tool",
|
||||
|
||||
@@ -7,8 +7,13 @@ import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from erpnext.education.api import enroll_student
|
||||
from frappe.utils import cint
|
||||
|
||||
class ProgramEnrollmentTool(Document):
|
||||
def onload(self):
|
||||
academic_term_reqd = cint(frappe.db.get_single_value('Education Settings', 'academic_term_reqd'))
|
||||
self.set_onload("academic_term_reqd", academic_term_reqd)
|
||||
|
||||
def get_students(self):
|
||||
students = []
|
||||
if not self.get_students_from:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"autoname": "SA.######",
|
||||
"autoname": "",
|
||||
"beta": 0,
|
||||
"creation": "2015-11-05 15:20:23.045996",
|
||||
"custom": 0,
|
||||
@@ -40,7 +40,7 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
@@ -101,7 +101,7 @@
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"search_index": 1,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
@@ -239,7 +239,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-11-10 19:09:51.041960",
|
||||
"modified": "2018-07-27 10:48:22.301531",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Student Attendance",
|
||||
|
||||
@@ -7,7 +7,8 @@ frappe.ui.form.on('Student Attendance Tool', {
|
||||
frm.set_query("student_group", function() {
|
||||
return {
|
||||
"filters": {
|
||||
"group_based_on": frm.doc.group_based_on
|
||||
"group_based_on": frm.doc.group_based_on,
|
||||
"disabled": 0
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -293,6 +293,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"fieldname": "disabled",
|
||||
"fieldtype": "Check",
|
||||
"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": "Disabled",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -459,7 +490,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-11-10 19:09:37.370864",
|
||||
"modified": "2018-07-26 04:17:10.836912",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Education",
|
||||
"name": "Student Group",
|
||||
|
||||
@@ -33,7 +33,7 @@ class StudentGroup(Document):
|
||||
program_enrollment = get_program_enrollment(self.academic_year, self.academic_term, self.program, self.batch, self.course)
|
||||
students = [d.student for d in program_enrollment] if program_enrollment else []
|
||||
for d in self.students:
|
||||
if not frappe.db.get_value("Student", d.student, "enabled") and d.active:
|
||||
if not frappe.db.get_value("Student", d.student, "enabled") and d.active and not self.disabled:
|
||||
frappe.throw(_("{0} - {1} is inactive student".format(d.group_roll_number, d.student_name)))
|
||||
|
||||
if (self.group_based_on == "Batch") and cint(frappe.defaults.get_defaults().validate_batch)\
|
||||
|
||||
@@ -99,7 +99,7 @@ def get_guardian_map(student_list):
|
||||
|
||||
def get_student_roll_no(academic_year, program, batch):
|
||||
student_group = frappe.get_all("Student Group",
|
||||
filters={"academic_year":academic_year, "program":program, "batch":batch})
|
||||
filters={"academic_year":academic_year, "program":program, "batch":batch, "disabled": 0})
|
||||
if student_group:
|
||||
roll_no_dict = dict(frappe.db.sql('''select student, group_roll_number from `tabStudent Group Student` where parent=%s''',
|
||||
(student_group[0].name)))
|
||||
|
||||
@@ -34,7 +34,7 @@ class LabTestTemplate(Document):
|
||||
# remove template refernce from item and disable item
|
||||
if(self.item):
|
||||
try:
|
||||
frappe.delete_doc("Item",self.item)
|
||||
frappe.delete_doc("Item",self.item, force=True)
|
||||
except Exception:
|
||||
frappe.throw("""Not permitted. Please disable the Test Template""")
|
||||
|
||||
|
||||
@@ -111,6 +111,7 @@ frappe.ui.form.on('Patient Appointment', {
|
||||
frm.set_value('appointment_time', selected_slot);
|
||||
frm.set_value('duration', data.time_per_appointment);
|
||||
d.hide();
|
||||
frm.enable_save();
|
||||
frm.save();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -292,10 +292,10 @@ def get_events(start, end, filters=None):
|
||||
conditions = get_event_conditions("Patient Appointment", filters)
|
||||
data = frappe.db.sql("""select name, patient, physician, status,
|
||||
duration, timestamp(appointment_date, appointment_time) as
|
||||
'start' from `tabPatient Appointment` where
|
||||
'appointment_date' from `tabPatient Appointment` where
|
||||
(appointment_date between %(start)s and %(end)s)
|
||||
and docstatus < 2 {conditions}""".format(conditions=conditions),
|
||||
{"start": start, "end": end}, as_dict=True, update={"allDay": 0})
|
||||
for item in data:
|
||||
item.end = item.start + datetime.timedelta(minutes = item.duration)
|
||||
item.appointment_datetime = item.appointment_date + datetime.timedelta(minutes = item.duration)
|
||||
return data
|
||||
|
||||
@@ -24,6 +24,7 @@ cur_frm.cscript.refresh = function(doc,cdt,cdn){
|
||||
}
|
||||
|
||||
cur_frm.cscript.kra_template = function(doc, dt, dn) {
|
||||
doc.goals = [];
|
||||
erpnext.utils.map_current_doc({
|
||||
method: "erpnext.hr.doctype.appraisal.appraisal.fetch_appraisal_template",
|
||||
source_name: cur_frm.doc.kra_template,
|
||||
|
||||
@@ -45,14 +45,21 @@ class Employee(NestedSet):
|
||||
self.validate_prefered_email()
|
||||
|
||||
if self.user_id:
|
||||
self.validate_for_enabled_user_id()
|
||||
self.validate_duplicate_user_id()
|
||||
self.validate_user_details()
|
||||
else:
|
||||
existing_user_id = frappe.db.get_value("Employee", self.name, "user_id")
|
||||
if existing_user_id:
|
||||
frappe.permissions.remove_user_permission(
|
||||
"Employee", self.name, existing_user_id)
|
||||
|
||||
def validate_user_details(self):
|
||||
data = frappe.db.get_value('User',
|
||||
self.user_id, ['enabled', 'user_image'], as_dict=1)
|
||||
|
||||
self.image = data.get("user_image")
|
||||
self.validate_for_enabled_user_id(data.get("enabled", 0))
|
||||
self.validate_duplicate_user_id()
|
||||
|
||||
def update_nsm_model(self):
|
||||
frappe.utils.nestedset.update_nsm(self)
|
||||
|
||||
@@ -133,10 +140,10 @@ class Employee(NestedSet):
|
||||
if self.status == 'Left' and not self.relieving_date:
|
||||
throw(_("Please enter relieving date."))
|
||||
|
||||
def validate_for_enabled_user_id(self):
|
||||
def validate_for_enabled_user_id(self, enabled):
|
||||
if not self.status == 'Active':
|
||||
return
|
||||
enabled = frappe.db.get_value("User", self.user_id, "enabled")
|
||||
|
||||
if enabled is None:
|
||||
frappe.throw(_("User {0} does not exist").format(self.user_id))
|
||||
if enabled == 0:
|
||||
|
||||
@@ -71,19 +71,22 @@ frappe.ui.form.on('Employee Loan', {
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
mode_of_payment: function (frm) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_bank_cash_account",
|
||||
args: {
|
||||
"mode_of_payment": frm.doc.mode_of_payment,
|
||||
"company": frm.doc.company
|
||||
},
|
||||
callback: function (r, rt) {
|
||||
if (r.message) {
|
||||
frm.set_value("payment_account", r.message.account);
|
||||
if (frm.doc.mode_of_payment && frm.doc.company) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_bank_cash_account",
|
||||
args: {
|
||||
"mode_of_payment": frm.doc.mode_of_payment,
|
||||
"company": frm.doc.company
|
||||
},
|
||||
callback: function (r, rt) {
|
||||
if (r.message) {
|
||||
frm.set_value("payment_account", r.message.account);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
employee_loan_application: function (frm) {
|
||||
|
||||
@@ -29,8 +29,13 @@ class EmployeeLoanApplication(Document):
|
||||
if self.repayment_method == "Repay Fixed Amount per Period":
|
||||
monthly_interest_rate = flt(self.rate_of_interest) / (12 *100)
|
||||
if monthly_interest_rate:
|
||||
monthly_interest_amount = self.loan_amount * monthly_interest_rate
|
||||
if monthly_interest_amount >= self.repayment_amount:
|
||||
frappe.throw(_("Repayment amount {} should be greater than monthly interest amount {}").
|
||||
format(self.repayment_amount, monthly_interest_amount))
|
||||
|
||||
self.repayment_periods = math.ceil((math.log(self.repayment_amount) -
|
||||
math.log(self.repayment_amount - (self.loan_amount*monthly_interest_rate))) /
|
||||
math.log(self.repayment_amount - (monthly_interest_amount))) /
|
||||
(math.log(1 + monthly_interest_rate)))
|
||||
else:
|
||||
self.repayment_periods = self.loan_amount / self.repayment_amount
|
||||
|
||||
@@ -30,7 +30,7 @@ class ExpenseClaim(AccountsController):
|
||||
self.validate_expense_approver()
|
||||
self.calculate_total_amount()
|
||||
set_employee_name(self)
|
||||
self.set_expense_account()
|
||||
self.set_expense_account(validate=True)
|
||||
self.set_payable_account()
|
||||
self.set_cost_center()
|
||||
self.set_status()
|
||||
@@ -224,10 +224,11 @@ class ExpenseClaim(AccountsController):
|
||||
self.total_advance_amount += flt(d.allocated_amount)
|
||||
|
||||
if self.total_advance_amount:
|
||||
if flt(self.total_advance_amount) > flt(self.total_claimed_amount):
|
||||
precision = self.precision("total_advance_amount")
|
||||
if flt(self.total_advance_amount, precision) > flt(self.total_claimed_amount, precision):
|
||||
frappe.throw(_("Total advance amount cannot be greater than total claimed amount"))
|
||||
if self.total_sanctioned_amount \
|
||||
and flt(self.total_advance_amount) > flt(self.total_sanctioned_amount):
|
||||
and flt(self.total_advance_amount, precision) > flt(self.total_sanctioned_amount, precision):
|
||||
frappe.throw(_("Total advance amount cannot be greater than total sanctioned amount"))
|
||||
|
||||
def validate_sanctioned_amount(self):
|
||||
@@ -235,9 +236,9 @@ class ExpenseClaim(AccountsController):
|
||||
if flt(d.sanctioned_amount) > flt(d.claim_amount):
|
||||
frappe.throw(_("Sanctioned Amount cannot be greater than Claim Amount in Row {0}.").format(d.idx))
|
||||
|
||||
def set_expense_account(self):
|
||||
def set_expense_account(self, validate=False):
|
||||
for expense in self.expenses:
|
||||
if not expense.default_account:
|
||||
if not expense.default_account or not validate:
|
||||
expense.default_account = get_expense_claim_account(expense.expense_type, self.company)["account"]
|
||||
|
||||
def update_reimbursed_amount(doc):
|
||||
|
||||
@@ -117,7 +117,7 @@ class LeaveApplication(Document):
|
||||
frappe.db.sql("""update `tabAttendance` set status = %s, leave_type = %s\
|
||||
where name = %s""",(status, self.leave_type, d.name))
|
||||
|
||||
elif self.to_date <= nowdate():
|
||||
elif getdate(self.to_date) <= getdate(nowdate()):
|
||||
for dt in daterange(getdate(self.from_date), getdate(self.to_date)):
|
||||
date = dt.strftime("%Y-%m-%d")
|
||||
if not date == self.half_day_date:
|
||||
@@ -355,7 +355,7 @@ def get_approvers(doctype, txt, searchfield, start, page_len, filters):
|
||||
@frappe.whitelist()
|
||||
def get_number_of_leave_days(employee, leave_type, from_date, to_date, half_day = None, half_day_date = None):
|
||||
number_of_days = 0
|
||||
if half_day == 1:
|
||||
if cint(half_day) == 1:
|
||||
if from_date == to_date:
|
||||
number_of_days = 0.5
|
||||
else:
|
||||
|
||||
@@ -113,20 +113,17 @@ frappe.ui.form.on('Salary Slip Timesheet', {
|
||||
// Get leave details
|
||||
//---------------------------------------------------------------------
|
||||
var get_emp_and_leave_details = function(doc, dt, dn) {
|
||||
if(!doc.start_date){
|
||||
return frappe.call({
|
||||
method: 'get_emp_and_leave_details',
|
||||
doc: locals[dt][dn],
|
||||
callback: function(r, rt) {
|
||||
cur_frm.refresh();
|
||||
calculate_all(doc, dt, dn);
|
||||
}
|
||||
});
|
||||
}
|
||||
return frappe.call({
|
||||
method: 'get_emp_and_leave_details',
|
||||
doc: locals[dt][dn],
|
||||
callback: function(r, rt) {
|
||||
cur_frm.refresh();
|
||||
calculate_all(doc, dt, dn);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
cur_frm.cscript.employee = function(doc,dt,dn){
|
||||
doc.salary_structure = ''
|
||||
get_emp_and_leave_details(doc, dt, dn);
|
||||
}
|
||||
|
||||
@@ -249,4 +246,4 @@ var total_work_hours = function(frm, dt, dn) {
|
||||
frm.refresh_field('gross_pay');
|
||||
calculate_net_pay(frm.doc, dt, dn);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +181,8 @@ class SalarySlip(TransactionBase):
|
||||
if len(st_name) > 1:
|
||||
frappe.msgprint(_("Multiple active Salary Structures found for employee {0} for the given dates")
|
||||
.format(self.employee), title=_('Warning'))
|
||||
return st_name and st_name[0][0] or ''
|
||||
self.salary_structure = st_name and st_name[0][0] or ''
|
||||
return self.salary_structure
|
||||
else:
|
||||
self.salary_structure = None
|
||||
frappe.msgprint(_("No active or default Salary Structure found for employee {0} for the given dates")
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils import cstr, add_days, date_diff
|
||||
from frappe.utils import cstr, add_days, date_diff, getdate
|
||||
from frappe import _
|
||||
from frappe.utils.csvutils import UnicodeWriter
|
||||
from frappe.model.document import Document
|
||||
@@ -48,8 +48,9 @@ def add_data(w, args):
|
||||
for employee in employees:
|
||||
existing_attendance = {}
|
||||
if existing_attendance_records \
|
||||
and tuple([date, employee.name]) in existing_attendance_records:
|
||||
existing_attendance = existing_attendance_records[tuple([date, employee.name])]
|
||||
and tuple([getdate(date), employee.name]) in existing_attendance_records:
|
||||
existing_attendance = existing_attendance_records[tuple([getdate(date), employee.name])]
|
||||
|
||||
row = [
|
||||
existing_attendance and existing_attendance.name or "",
|
||||
employee.name, employee.employee_name, date,
|
||||
@@ -114,6 +115,7 @@ def upload():
|
||||
if not row: continue
|
||||
row_idx = i + 5
|
||||
d = frappe._dict(zip(columns, row))
|
||||
|
||||
d["doctype"] = "Attendance"
|
||||
if d.name:
|
||||
d["docstatus"] = frappe.db.get_value("Attendance", d.name, "docstatus")
|
||||
@@ -121,6 +123,8 @@ def upload():
|
||||
try:
|
||||
check_record(d)
|
||||
ret.append(import_doc(d, "Attendance", 1, row_idx, submit=True))
|
||||
except AttributeError:
|
||||
pass
|
||||
except Exception as e:
|
||||
error = True
|
||||
ret.append('Error for row (#%d) %s : %s' % (row_idx,
|
||||
|
||||
@@ -24,6 +24,7 @@ def get_columns(leave_types):
|
||||
]
|
||||
|
||||
for leave_type in leave_types:
|
||||
columns.append(_(leave_type) + " " + _("Opening") + ":Float:160")
|
||||
columns.append(_(leave_type) + " " + _("Taken") + ":Float:160")
|
||||
columns.append(_(leave_type) + " " + _("Balance") + ":Float:160")
|
||||
|
||||
@@ -32,6 +33,7 @@ def get_columns(leave_types):
|
||||
def get_data(filters, leave_types):
|
||||
user = frappe.session.user
|
||||
allocation_records_based_on_to_date = get_leave_allocation_records(filters.to_date)
|
||||
allocation_records_based_on_from_date = get_leave_allocation_records(filters.from_date)
|
||||
|
||||
active_employees = frappe.get_all("Employee",
|
||||
filters = { "status": "Active", "company": filters.company},
|
||||
@@ -48,13 +50,17 @@ def get_data(filters, leave_types):
|
||||
# leaves taken
|
||||
leaves_taken = get_approved_leaves_for_period(employee.name, leave_type,
|
||||
filters.from_date, filters.to_date)
|
||||
|
||||
|
||||
# opening balance
|
||||
opening = get_leave_balance_on(employee.name, leave_type, filters.from_date,
|
||||
allocation_records_based_on_from_date.get(employee.name, frappe._dict()))
|
||||
|
||||
# closing balance
|
||||
closing = get_leave_balance_on(employee.name, leave_type, filters.to_date,
|
||||
allocation_records_based_on_to_date.get(employee.name, frappe._dict()))
|
||||
|
||||
row += [leaves_taken, closing]
|
||||
row += [opening, leaves_taken, closing]
|
||||
|
||||
data.append(row)
|
||||
|
||||
return data
|
||||
return data
|
||||
|
||||
@@ -9,7 +9,7 @@ from frappe.utils import flt,cstr
|
||||
from erpnext.accounts.report.financial_statements import get_period_list
|
||||
|
||||
def execute(filters=None):
|
||||
columns, data = [], []
|
||||
columns, data, chart = [], [], []
|
||||
if filters.get('fiscal_year'):
|
||||
company = erpnext.get_default_company()
|
||||
period_list = get_period_list(filters.get('fiscal_year'), filters.get('fiscal_year'),"Monthly", company)
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe, requests, json
|
||||
from frappe.utils import now, nowdate, cint
|
||||
from frappe.utils.nestedset import get_root_of
|
||||
from frappe.contacts.doctype.contact.contact import get_default_contact
|
||||
|
||||
@frappe.whitelist()
|
||||
def enable_hub():
|
||||
hub_settings = frappe.get_doc('Hub Settings')
|
||||
hub_settings.register()
|
||||
frappe.db.commit()
|
||||
return hub_settings
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_items(start=0, limit=20, category=None, order_by=None, company=None, text=None):
|
||||
connection = get_client_connection()
|
||||
filters = {
|
||||
'hub_category': category,
|
||||
}
|
||||
if text:
|
||||
filters.update({'item_name': ('like', '%' + text + '%')})
|
||||
if company:
|
||||
filters.update({'company_name': company})
|
||||
|
||||
response = connection.get_list('Hub Item',
|
||||
limit_start=start, limit_page_length=limit,
|
||||
filters=filters)
|
||||
return response
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_categories():
|
||||
connection = get_client_connection()
|
||||
response = connection.get_list('Hub Category')
|
||||
return response
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_item_details(hub_sync_id=None):
|
||||
if not hub_sync_id:
|
||||
return
|
||||
connection = get_client_connection()
|
||||
return connection.get_doc('Hub Item', hub_sync_id)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_company_details(hub_sync_id):
|
||||
connection = get_client_connection()
|
||||
return connection.get_doc('Hub Company', hub_sync_id)
|
||||
|
||||
def get_client_connection():
|
||||
# frappeclient connection
|
||||
hub_connection = get_hub_connection()
|
||||
return hub_connection.connection
|
||||
|
||||
def get_hub_connection():
|
||||
hub_connector = frappe.get_doc(
|
||||
'Data Migration Connector', 'Hub Connector')
|
||||
hub_connection = hub_connector.get_connection()
|
||||
return hub_connection
|
||||
|
||||
def make_opportunity(buyer_name, email_id):
|
||||
buyer_name = "HUB-" + buyer_name
|
||||
|
||||
if not frappe.db.exists('Lead', {'email_id': email_id}):
|
||||
lead = frappe.new_doc("Lead")
|
||||
lead.lead_name = buyer_name
|
||||
lead.email_id = email_id
|
||||
lead.save(ignore_permissions=True)
|
||||
|
||||
o = frappe.new_doc("Opportunity")
|
||||
o.enquiry_from = "Lead"
|
||||
o.lead = frappe.get_all("Lead", filters={"email_id": email_id}, fields = ["name"])[0]["name"]
|
||||
o.save(ignore_permissions=True)
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_rfq_and_send_opportunity(item, supplier):
|
||||
supplier = make_supplier(supplier)
|
||||
contact = make_contact(supplier)
|
||||
item = make_item(item)
|
||||
rfq = make_rfq(item, supplier, contact)
|
||||
status = send_opportunity(contact)
|
||||
|
||||
return {
|
||||
'rfq': rfq,
|
||||
'hub_document_created': status
|
||||
}
|
||||
|
||||
def make_supplier(supplier):
|
||||
# make supplier if not already exists
|
||||
supplier = frappe._dict(json.loads(supplier))
|
||||
|
||||
if not frappe.db.exists('Supplier', {'supplier_name': supplier.supplier_name}):
|
||||
supplier_doc = frappe.get_doc({
|
||||
'doctype': 'Supplier',
|
||||
'supplier_name': supplier.supplier_name,
|
||||
'supplier_type': supplier.supplier_type,
|
||||
'supplier_email': supplier.supplier_email
|
||||
}).insert()
|
||||
else:
|
||||
supplier_doc = frappe.get_doc('Supplier', supplier.supplier_name)
|
||||
|
||||
return supplier_doc
|
||||
|
||||
def make_contact(supplier):
|
||||
contact_name = get_default_contact('Supplier', supplier.supplier_name)
|
||||
# make contact if not already exists
|
||||
if not contact_name:
|
||||
contact = frappe.get_doc({
|
||||
'doctype': 'Contact',
|
||||
'first_name': supplier.supplier_name,
|
||||
'email_id': supplier.supplier_email,
|
||||
'is_primary_contact': 1,
|
||||
'links': [
|
||||
{'link_doctype': 'Supplier', 'link_name': supplier.supplier_name}
|
||||
]
|
||||
}).insert()
|
||||
else:
|
||||
contact = frappe.get_doc('Contact', contact_name)
|
||||
|
||||
return contact
|
||||
|
||||
def make_item(item):
|
||||
# make item if not already exists
|
||||
item = frappe._dict(json.loads(item))
|
||||
|
||||
if not frappe.db.exists('Item', {'item_code': item.item_code}):
|
||||
item_doc = frappe.get_doc({
|
||||
'doctype': 'Item',
|
||||
'item_code': item.item_code,
|
||||
'item_group': item.item_group,
|
||||
'is_item_from_hub': 1
|
||||
}).insert()
|
||||
else:
|
||||
item_doc = frappe.get_doc('Item', item.item_code)
|
||||
|
||||
return item_doc
|
||||
|
||||
def make_rfq(item, supplier, contact):
|
||||
# make rfq
|
||||
rfq = frappe.get_doc({
|
||||
'doctype': 'Request for Quotation',
|
||||
'transaction_date': nowdate(),
|
||||
'status': 'Draft',
|
||||
'company': frappe.db.get_single_value('Hub Settings', 'company'),
|
||||
'message_for_supplier': 'Please supply the specified items at the best possible rates',
|
||||
'suppliers': [
|
||||
{ 'supplier': supplier.name, 'contact': contact.name }
|
||||
],
|
||||
'items': [
|
||||
{
|
||||
'item_code': item.item_code,
|
||||
'qty': 1,
|
||||
'schedule_date': nowdate(),
|
||||
'warehouse': item.default_warehouse or get_root_of("Warehouse"),
|
||||
'description': item.description,
|
||||
'uom': item.stock_uom
|
||||
}
|
||||
]
|
||||
}).insert()
|
||||
|
||||
rfq.save()
|
||||
rfq.submit()
|
||||
return rfq
|
||||
|
||||
def send_opportunity(contact):
|
||||
# Make Hub Message on Hub with lead data
|
||||
doc = {
|
||||
'doctype': 'Lead',
|
||||
'lead_name': frappe.db.get_single_value('Hub Settings', 'company'),
|
||||
'email_id': frappe.db.get_single_value('Hub Settings', 'user')
|
||||
}
|
||||
|
||||
args = frappe._dict(dict(
|
||||
doctype='Hub Message',
|
||||
reference_doctype='Lead',
|
||||
data=json.dumps(doc),
|
||||
user=contact.email_id
|
||||
))
|
||||
|
||||
connection = get_hub_connection()
|
||||
response = connection.insert('Hub Message', args)
|
||||
|
||||
return response.ok
|
||||
@@ -1,45 +0,0 @@
|
||||
{
|
||||
"condition": "{'name': ('=', frappe.db.get_single_value('Hub Settings', 'company'))}",
|
||||
"creation": "2017-09-07 11:38:43.169065",
|
||||
"docstatus": 0,
|
||||
"doctype": "Data Migration Mapping",
|
||||
"fields": [
|
||||
{
|
||||
"is_child_table": 0,
|
||||
"local_fieldname": "name",
|
||||
"remote_fieldname": "company_name"
|
||||
},
|
||||
{
|
||||
"is_child_table": 0,
|
||||
"local_fieldname": "country",
|
||||
"remote_fieldname": "country"
|
||||
},
|
||||
{
|
||||
"is_child_table": 0,
|
||||
"local_fieldname": "\"city\"",
|
||||
"remote_fieldname": "seller_city"
|
||||
},
|
||||
{
|
||||
"is_child_table": 0,
|
||||
"local_fieldname": "eval:frappe.local.site",
|
||||
"remote_fieldname": "site_name"
|
||||
},
|
||||
{
|
||||
"is_child_table": 0,
|
||||
"local_fieldname": "eval:frappe.session.user",
|
||||
"remote_fieldname": "user"
|
||||
}
|
||||
],
|
||||
"idx": 2,
|
||||
"local_doctype": "Company",
|
||||
"mapping_name": "Company to Hub Company",
|
||||
"mapping_type": "Push",
|
||||
"migration_id_field": "hub_sync_id",
|
||||
"modified": "2017-10-09 17:30:17.853929",
|
||||
"modified_by": "Administrator",
|
||||
"name": "Company to Hub Company",
|
||||
"owner": "Administrator",
|
||||
"page_length": 10,
|
||||
"remote_objectname": "Hub Company",
|
||||
"remote_primary_key": "name"
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import frappe, json
|
||||
|
||||
def pre_process(doc):
|
||||
return json.loads(doc['data'])
|
||||
|
||||
def post_process(remote_doc=None, local_doc=None, **kwargs):
|
||||
if not local_doc:
|
||||
return
|
||||
|
||||
hub_message = remote_doc
|
||||
# update hub message on hub
|
||||
hub_connector = frappe.get_doc('Data Migration Connector', 'Hub Connector')
|
||||
connection = hub_connector.get_connection()
|
||||
connection.update('Hub Message', dict(
|
||||
status='Synced'
|
||||
), hub_message['name'])
|
||||
|
||||
# make opportunity after lead is created
|
||||
lead = local_doc
|
||||
opportunity = frappe.get_doc({
|
||||
'doctype': 'Opportunity',
|
||||
'naming_series': 'OPTY-',
|
||||
'opportunity_type': 'Hub',
|
||||
'enquiry_from': 'Lead',
|
||||
'status': 'Open',
|
||||
'lead': lead.name,
|
||||
'company': lead.company,
|
||||
'transaction_date': frappe.utils.today()
|
||||
}).insert()
|
||||
@@ -1,31 +0,0 @@
|
||||
{
|
||||
"condition": "{'reference_doctype': 'Lead', 'user': frappe.db.get_single_value('Hub Settings', 'user'), 'status': 'Pending'}",
|
||||
"creation": "2017-09-20 15:06:40.279930",
|
||||
"docstatus": 0,
|
||||
"doctype": "Data Migration Mapping",
|
||||
"fields": [
|
||||
{
|
||||
"is_child_table": 0,
|
||||
"local_fieldname": "email_id",
|
||||
"remote_fieldname": "email_id"
|
||||
},
|
||||
{
|
||||
"is_child_table": 0,
|
||||
"local_fieldname": "lead_name",
|
||||
"remote_fieldname": "lead_name"
|
||||
}
|
||||
],
|
||||
"idx": 0,
|
||||
"local_doctype": "Lead",
|
||||
"local_primary_key": "email_id",
|
||||
"mapping_name": "Hub Message to Lead",
|
||||
"mapping_type": "Pull",
|
||||
"migration_id_field": "hub_sync_id",
|
||||
"modified": "2017-10-09 17:30:17.908830",
|
||||
"modified_by": "Administrator",
|
||||
"name": "Hub Message to Lead",
|
||||
"owner": "frappetest@gmail.com",
|
||||
"page_length": 10,
|
||||
"remote_objectname": "Hub Message",
|
||||
"remote_primary_key": "name"
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
{
|
||||
"condition": "{\"publish_in_hub\": 1}",
|
||||
"creation": "2017-09-07 13:27:52.726350",
|
||||
"docstatus": 0,
|
||||
"doctype": "Data Migration Mapping",
|
||||
"fields": [
|
||||
{
|
||||
"is_child_table": 0,
|
||||
"local_fieldname": "item_code",
|
||||
"remote_fieldname": "item_code"
|
||||
},
|
||||
{
|
||||
"is_child_table": 0,
|
||||
"local_fieldname": "item_name",
|
||||
"remote_fieldname": "item_name"
|
||||
},
|
||||
{
|
||||
"is_child_table": 0,
|
||||
"local_fieldname": "eval:frappe.db.get_default(\"company\")",
|
||||
"remote_fieldname": "company_name"
|
||||
},
|
||||
{
|
||||
"is_child_table": 0,
|
||||
"local_fieldname": "image",
|
||||
"remote_fieldname": "image"
|
||||
},
|
||||
{
|
||||
"is_child_table": 0,
|
||||
"local_fieldname": "item_group",
|
||||
"remote_fieldname": "item_group"
|
||||
},
|
||||
{
|
||||
"is_child_table": 0,
|
||||
"local_fieldname": "eval:frappe.session.user",
|
||||
"remote_fieldname": "seller"
|
||||
},
|
||||
{
|
||||
"is_child_table": 0,
|
||||
"local_fieldname": "eval:frappe.db.get_default(\"country\")",
|
||||
"remote_fieldname": "country"
|
||||
}
|
||||
],
|
||||
"idx": 1,
|
||||
"local_doctype": "Item",
|
||||
"mapping_name": "Item to Hub Item",
|
||||
"mapping_type": "Push",
|
||||
"migration_id_field": "hub_sync_id",
|
||||
"modified": "2017-10-09 17:30:17.890337",
|
||||
"modified_by": "Administrator",
|
||||
"name": "Item to Hub Item",
|
||||
"owner": "Administrator",
|
||||
"page_length": 10,
|
||||
"remote_objectname": "Hub Item",
|
||||
"remote_primary_key": "item_code"
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"creation": "2017-09-07 11:39:38.445902",
|
||||
"docstatus": 0,
|
||||
"doctype": "Data Migration Plan",
|
||||
"idx": 1,
|
||||
"mappings": [
|
||||
{
|
||||
"enabled": 1,
|
||||
"mapping": "Company to Hub Company"
|
||||
},
|
||||
{
|
||||
"enabled": 1,
|
||||
"mapping": "Item to Hub Item"
|
||||
},
|
||||
{
|
||||
"enabled": 1,
|
||||
"mapping": "Hub Message to Lead"
|
||||
}
|
||||
],
|
||||
"modified": "2017-10-09 17:30:17.680059",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Hub Node",
|
||||
"name": "Hub Sync",
|
||||
"owner": "Administrator",
|
||||
"plan_name": "Hub Sync"
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Hub Category', {
|
||||
refresh: function(frm) {
|
||||
|
||||
}
|
||||
});
|
||||
@@ -1,275 +0,0 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"autoname": "field:hub_category_name",
|
||||
"beta": 0,
|
||||
"creation": "2017-08-22 11:31:10.410322",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "hub_category_name",
|
||||
"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": "Category Name",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "parent_hub_category",
|
||||
"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": "Parent Category",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Hub Category",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "is_group",
|
||||
"fieldtype": "Check",
|
||||
"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": "Is Group",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text Editor",
|
||||
"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": "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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "lft",
|
||||
"fieldtype": "Int",
|
||||
"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": "Left",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "rgt",
|
||||
"fieldtype": "Int",
|
||||
"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": "Right",
|
||||
"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,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "old_parent",
|
||||
"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": "Old Parent",
|
||||
"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,
|
||||
"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": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-09-03 22:04:22.958831",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Hub Node",
|
||||
"name": "Hub Category",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 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
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "hub_category_name",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils.nestedset import NestedSet
|
||||
from frappe.model.document import Document
|
||||
|
||||
class HubCategory(NestedSet):
|
||||
pass
|
||||
@@ -1,4 +0,0 @@
|
||||
frappe.treeview_settings["Hub Category"] = {
|
||||
title: __("Hub Category"),
|
||||
breadcrumb: "Hub"
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Hub Category", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new Hub Category
|
||||
() => frappe.tests.make('Hub Category', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user