Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
@@ -5,7 +5,7 @@ import frappe
|
|||||||
from erpnext.hooks import regional_overrides
|
from erpnext.hooks import regional_overrides
|
||||||
from frappe.utils import getdate
|
from frappe.utils import getdate
|
||||||
|
|
||||||
__version__ = '10.1.44'
|
__version__ = '10.1.48'
|
||||||
|
|
||||||
def get_default_company(user=None):
|
def get_default_company(user=None):
|
||||||
'''Get default company for user'''
|
'''Get default company for user'''
|
||||||
|
|||||||
@@ -53,6 +53,12 @@ frappe.ui.form.on('Account', {
|
|||||||
frm.trigger("update_account_number");
|
frm.trigger("update_account_number");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!frm.doc.__islocal) {
|
||||||
|
frm.add_custom_button(__('Merge Account'), function () {
|
||||||
|
frm.trigger("merge_account");
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
account_type: function (frm) {
|
account_type: function (frm) {
|
||||||
if (frm.doc.is_group == 0) {
|
if (frm.doc.is_group == 0) {
|
||||||
@@ -98,6 +104,44 @@ frappe.ui.form.on('Account', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
merge_account: function(frm) {
|
||||||
|
var d = new frappe.ui.Dialog({
|
||||||
|
title: __('Merge with Existing Account'),
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
"label" : "Name",
|
||||||
|
"fieldname": "name",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"reqd": 1,
|
||||||
|
"default": frm.doc.name
|
||||||
|
}
|
||||||
|
],
|
||||||
|
primary_action: function() {
|
||||||
|
var data = d.get_values();
|
||||||
|
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) {
|
update_account_number: function(frm) {
|
||||||
var d = new frappe.ui.Dialog({
|
var d = new frappe.ui.Dialog({
|
||||||
title: __('Update Account Number / Name'),
|
title: __('Update Account Number / Name'),
|
||||||
|
|||||||
@@ -217,3 +217,23 @@ def update_account_number(name, account_name, account_number=None):
|
|||||||
if name != new_name:
|
if name != new_name:
|
||||||
frappe.rename_doc("Account", name, new_name, ignore_permissions=1)
|
frappe.rename_doc("Account", name, new_name, ignore_permissions=1)
|
||||||
return new_name
|
return new_name
|
||||||
|
|
||||||
|
@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
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import unittest
|
|||||||
import frappe
|
import frappe
|
||||||
from erpnext.stock import get_warehouse_account, get_company_default_inventory_account
|
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 update_account_number
|
||||||
|
from erpnext.accounts.doctype.account.account import merge_account
|
||||||
|
|
||||||
class TestAccount(unittest.TestCase):
|
class TestAccount(unittest.TestCase):
|
||||||
def test_rename_account(self):
|
def test_rename_account(self):
|
||||||
@@ -25,7 +26,7 @@ class TestAccount(unittest.TestCase):
|
|||||||
new_account_number = "1211-11-4 - 6 - "
|
new_account_number = "1211-11-4 - 6 - "
|
||||||
new_account_name = "Debtors 1 - Test - "
|
new_account_name = "Debtors 1 - Test - "
|
||||||
|
|
||||||
update_account_number("1210 - Debtors - _TC", new_account_number, new_account_name)
|
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",
|
new_acc = frappe.db.get_value("Account", "1211-11-4 - 6 - - Debtors 1 - Test - - _TC",
|
||||||
["account_name", "account_number"], as_dict=1)
|
["account_name", "account_number"], as_dict=1)
|
||||||
@@ -35,6 +36,67 @@ class TestAccount(unittest.TestCase):
|
|||||||
|
|
||||||
frappe.delete_doc("Account", "1211-11-4 - 6 - Debtors 1 - Test - - _TC")
|
frappe.delete_doc("Account", "1211-11-4 - 6 - Debtors 1 - Test - - _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):
|
def _make_test_records(verbose):
|
||||||
from frappe.test_runner import make_test_objects
|
from frappe.test_runner import make_test_objects
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
|||||||
if(!this.frm.doc.supplier && this.frm.doc.credit_to) {
|
if(!this.frm.doc.supplier && this.frm.doc.credit_to) {
|
||||||
this.frm.set_df_property("credit_to", "print_hide", 0);
|
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));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ frappe.query_reports["Accounts Payable"] = {
|
|||||||
"fieldname":"ageing_based_on",
|
"fieldname":"ageing_based_on",
|
||||||
"label": __("Ageing Based On"),
|
"label": __("Ageing Based On"),
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"options": 'Posting Date\nDue Date',
|
"options": 'Posting Date\nDue Date\nSupplier Invoice Date',
|
||||||
"default": "Posting Date"
|
"default": "Posting Date"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ class ReceivablePayableReport(object):
|
|||||||
|
|
||||||
# get due date
|
# get due date
|
||||||
due_date = voucher_details.get(gle.voucher_no, {}).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]
|
row += [gle.voucher_type, gle.voucher_no, due_date]
|
||||||
|
|
||||||
@@ -167,15 +168,25 @@ class ReceivablePayableReport(object):
|
|||||||
row += [invoiced_amount, paid_amt, credit_note_amount, outstanding_amount]
|
row += [invoiced_amount, paid_amt, credit_note_amount, outstanding_amount]
|
||||||
|
|
||||||
# ageing data
|
# 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),
|
row += get_ageing_data(cint(self.filters.range1), cint(self.filters.range2),
|
||||||
cint(self.filters.range3), self.age_as_on, entry_date, outstanding_amount)
|
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
|
# issue 6371-Ageing buckets should not have amounts if due date is not reached
|
||||||
if self.filters.ageing_based_on == "Due Date" \
|
if self.filters.ageing_based_on == "Due Date" \
|
||||||
and getdate(due_date) > getdate(self.filters.report_date):
|
and getdate(due_date) > getdate(self.filters.report_date):
|
||||||
row[-1]=row[-2]=row[-3]=row[-4]=0
|
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"))):
|
if self.filters.get(scrub(args.get("party_type"))):
|
||||||
row.append(gle.account_currency)
|
row.append(gle.account_currency)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -185,14 +185,15 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency):
|
|||||||
has_value = False
|
has_value = False
|
||||||
total = 0
|
total = 0
|
||||||
row = frappe._dict({
|
row = frappe._dict({
|
||||||
"account_name": _(d.account_name),
|
|
||||||
"account": _(d.name),
|
"account": _(d.name),
|
||||||
"parent_account": _(d.parent_account),
|
"parent_account": _(d.parent_account),
|
||||||
"indent": flt(d.indent),
|
"indent": flt(d.indent),
|
||||||
"year_start_date": year_start_date,
|
"year_start_date": year_start_date,
|
||||||
"year_end_date": year_end_date,
|
"year_end_date": year_end_date,
|
||||||
"currency": company_currency,
|
"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:
|
for period in period_list:
|
||||||
if d.get(period.key) and balance_must_be=="Credit":
|
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({})
|
out.append({})
|
||||||
|
|
||||||
def get_accounts(company, root_type):
|
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)
|
where company=%s and root_type=%s order by lft""", (company, root_type), as_dict=True)
|
||||||
|
|
||||||
def filter_accounts(accounts, depth=10):
|
def filter_accounts(accounts, depth=10):
|
||||||
|
|||||||
@@ -223,13 +223,13 @@ def get_tax_accounts(item_list, columns, company_currency,
|
|||||||
item_tax_amount = flt((tax_amount * d.base_net_amount) / item_net_amount) \
|
item_tax_amount = flt((tax_amount * d.base_net_amount) / item_net_amount) \
|
||||||
if item_net_amount else 0
|
if item_net_amount else 0
|
||||||
if item_tax_amount:
|
if item_tax_amount:
|
||||||
tax_amount = flt(item_tax_amount, tax_amount_precision)
|
tax_value = flt(item_tax_amount, tax_amount_precision)
|
||||||
tax_amount = (tax_amount * -1
|
tax_value = (tax_value * -1
|
||||||
if (doctype == 'Purchase Invoice' and name in deducted_tax) else tax_amount)
|
if (doctype == 'Purchase Invoice' and name in deducted_tax) else tax_value)
|
||||||
|
|
||||||
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
|
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
|
||||||
"tax_rate": tax_rate,
|
"tax_rate": tax_rate,
|
||||||
"tax_amount": tax_amount
|
"tax_amount": tax_value
|
||||||
})
|
})
|
||||||
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ def validate_filters(filters):
|
|||||||
filters.to_date = filters.year_end_date
|
filters.to_date = filters.year_end_date
|
||||||
|
|
||||||
def get_data(filters):
|
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)
|
from `tabAccount` where company=%s order by lft""", filters.company, as_dict=True)
|
||||||
company_currency = erpnext.get_company_currency(filters.company)
|
company_currency = erpnext.get_company_currency(filters.company)
|
||||||
|
|
||||||
@@ -179,13 +179,14 @@ def prepare_data(accounts, filters, total_row, parent_children_map, company_curr
|
|||||||
for d in accounts:
|
for d in accounts:
|
||||||
has_value = False
|
has_value = False
|
||||||
row = {
|
row = {
|
||||||
"account_name": d.account_name,
|
|
||||||
"account": d.name,
|
"account": d.name,
|
||||||
"parent_account": d.parent_account,
|
"parent_account": d.parent_account,
|
||||||
"indent": d.indent,
|
"indent": d.indent,
|
||||||
"from_date": filters.from_date,
|
"from_date": filters.from_date,
|
||||||
"to_date": filters.to_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)
|
prepare_opening_and_closing(d)
|
||||||
|
|||||||
@@ -2378,6 +2378,37 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 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_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@@ -2409,6 +2440,36 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 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_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@@ -3293,7 +3354,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-07-18 07:49:53.131408",
|
"modified": "2018-08-01 15:18:33.155409",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Purchase Order",
|
"name": "Purchase Order",
|
||||||
|
|||||||
@@ -1983,6 +1983,37 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 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_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@@ -2014,6 +2045,36 @@
|
|||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"unique": 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_bulk_edit": 0,
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
@@ -2549,7 +2610,7 @@
|
|||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"menu_index": 0,
|
"menu_index": 0,
|
||||||
"modified": "2018-07-06 02:45:48.616334",
|
"modified": "2018-08-01 15:18:23.265621",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Supplier Quotation",
|
"name": "Supplier Quotation",
|
||||||
|
|||||||
@@ -99,9 +99,16 @@ class BuyingController(StockController):
|
|||||||
def set_total_in_words(self):
|
def set_total_in_words(self):
|
||||||
from frappe.utils import money_in_words
|
from frappe.utils import money_in_words
|
||||||
if self.meta.get_field("base_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"):
|
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
|
# update valuation rate
|
||||||
def update_valuation_rate(self, parentfield):
|
def update_valuation_rate(self, parentfield):
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ class ProgramEnrollment(Document):
|
|||||||
"student": self.student,
|
"student": self.student,
|
||||||
"program": self.program,
|
"program": self.program,
|
||||||
"academic_year": self.academic_year,
|
"academic_year": self.academic_year,
|
||||||
"academic_term": self.academic_term,
|
|
||||||
"docstatus": ("<", 2),
|
"docstatus": ("<", 2),
|
||||||
"name": ("!=", self.name)
|
"name": ("!=", self.name)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class StudentGroup(Document):
|
|||||||
program_enrollment = get_program_enrollment(self.academic_year, self.academic_term, self.program, self.batch, self.course)
|
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 []
|
students = [d.student for d in program_enrollment] if program_enrollment else []
|
||||||
for d in self.students:
|
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)))
|
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)\
|
if (self.group_based_on == "Batch") and cint(frappe.defaults.get_defaults().validate_batch)\
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class LabTestTemplate(Document):
|
|||||||
# remove template refernce from item and disable item
|
# remove template refernce from item and disable item
|
||||||
if(self.item):
|
if(self.item):
|
||||||
try:
|
try:
|
||||||
frappe.delete_doc("Item",self.item)
|
frappe.delete_doc("Item",self.item, force=True)
|
||||||
except Exception:
|
except Exception:
|
||||||
frappe.throw("""Not permitted. Please disable the Test Template""")
|
frappe.throw("""Not permitted. Please disable the Test Template""")
|
||||||
|
|
||||||
|
|||||||
@@ -292,10 +292,10 @@ def get_events(start, end, filters=None):
|
|||||||
conditions = get_event_conditions("Patient Appointment", filters)
|
conditions = get_event_conditions("Patient Appointment", filters)
|
||||||
data = frappe.db.sql("""select name, patient, physician, status,
|
data = frappe.db.sql("""select name, patient, physician, status,
|
||||||
duration, timestamp(appointment_date, appointment_time) as
|
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)
|
(appointment_date between %(start)s and %(end)s)
|
||||||
and docstatus < 2 {conditions}""".format(conditions=conditions),
|
and docstatus < 2 {conditions}""".format(conditions=conditions),
|
||||||
{"start": start, "end": end}, as_dict=True, update={"allDay": 0})
|
{"start": start, "end": end}, as_dict=True, update={"allDay": 0})
|
||||||
for item in data:
|
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
|
return data
|
||||||
|
|||||||
@@ -71,7 +71,9 @@ frappe.ui.form.on('Employee Loan', {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
mode_of_payment: function (frm) {
|
mode_of_payment: function (frm) {
|
||||||
|
if (frm.doc.mode_of_payment && frm.doc.company) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_bank_cash_account",
|
method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.get_bank_cash_account",
|
||||||
args: {
|
args: {
|
||||||
@@ -84,6 +86,7 @@ frappe.ui.form.on('Employee Loan', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
employee_loan_application: function (frm) {
|
employee_loan_application: function (frm) {
|
||||||
|
|||||||
@@ -29,8 +29,13 @@ class EmployeeLoanApplication(Document):
|
|||||||
if self.repayment_method == "Repay Fixed Amount per Period":
|
if self.repayment_method == "Repay Fixed Amount per Period":
|
||||||
monthly_interest_rate = flt(self.rate_of_interest) / (12 *100)
|
monthly_interest_rate = flt(self.rate_of_interest) / (12 *100)
|
||||||
if monthly_interest_rate:
|
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) -
|
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)))
|
(math.log(1 + monthly_interest_rate)))
|
||||||
else:
|
else:
|
||||||
self.repayment_periods = self.loan_amount / self.repayment_amount
|
self.repayment_periods = self.loan_amount / self.repayment_amount
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class ExpenseClaim(AccountsController):
|
|||||||
self.validate_expense_approver()
|
self.validate_expense_approver()
|
||||||
self.calculate_total_amount()
|
self.calculate_total_amount()
|
||||||
set_employee_name(self)
|
set_employee_name(self)
|
||||||
self.set_expense_account()
|
self.set_expense_account(validate=True)
|
||||||
self.set_payable_account()
|
self.set_payable_account()
|
||||||
self.set_cost_center()
|
self.set_cost_center()
|
||||||
self.set_status()
|
self.set_status()
|
||||||
@@ -235,9 +235,9 @@ class ExpenseClaim(AccountsController):
|
|||||||
if flt(d.sanctioned_amount) > flt(d.claim_amount):
|
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))
|
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:
|
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"]
|
expense.default_account = get_expense_claim_account(expense.expense_type, self.company)["account"]
|
||||||
|
|
||||||
def update_reimbursed_amount(doc):
|
def update_reimbursed_amount(doc):
|
||||||
|
|||||||
@@ -52,7 +52,14 @@ class Project(Document):
|
|||||||
if self.name is None:
|
if self.name is None:
|
||||||
return {}
|
return {}
|
||||||
else:
|
else:
|
||||||
return frappe.get_all("Task", "*", {"project": self.name}, order_by="exp_start_date asc")
|
filters = {"project": self.name}
|
||||||
|
|
||||||
|
if self.get("deleted_task_list"):
|
||||||
|
filters.update({
|
||||||
|
'name': ("not in", self.deleted_task_list)
|
||||||
|
})
|
||||||
|
|
||||||
|
return frappe.get_all("Task", "*", filters, order_by="exp_start_date asc")
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_project_name()
|
self.validate_project_name()
|
||||||
@@ -82,12 +89,26 @@ class Project(Document):
|
|||||||
|
|
||||||
def sync_tasks(self):
|
def sync_tasks(self):
|
||||||
"""sync tasks and remove table"""
|
"""sync tasks and remove table"""
|
||||||
|
if not hasattr(self, "deleted_task_list"):
|
||||||
|
self.set("deleted_task_list", [])
|
||||||
|
|
||||||
if self.flags.dont_sync_tasks: return
|
if self.flags.dont_sync_tasks: return
|
||||||
task_names = []
|
task_names = []
|
||||||
|
|
||||||
existing_task_data = {}
|
existing_task_data = {}
|
||||||
|
|
||||||
|
fields = ["title", "status", "start_date", "end_date", "description", "task_weight", "task_id"]
|
||||||
|
exclude_fieldtype = ["Button", "Column Break",
|
||||||
|
"Section Break", "Table", "Read Only", "Attach", "Attach Image", "Color", "Geolocation", "HTML", "Image"]
|
||||||
|
|
||||||
|
custom_fields = frappe.get_all("Custom Field", {"dt": "Project Task",
|
||||||
|
"fieldtype": ("not in", exclude_fieldtype)}, "fieldname")
|
||||||
|
|
||||||
|
for d in custom_fields:
|
||||||
|
fields.append(d.fieldname)
|
||||||
|
|
||||||
for d in frappe.get_all('Project Task',
|
for d in frappe.get_all('Project Task',
|
||||||
fields = ["title", "status", "start_date", "end_date", "description", "task_weight", "task_id"],
|
fields = fields,
|
||||||
filters = {'parent': self.name}):
|
filters = {'parent': self.name}):
|
||||||
existing_task_data.setdefault(d.task_id, d)
|
existing_task_data.setdefault(d.task_id, d)
|
||||||
|
|
||||||
@@ -98,7 +119,7 @@ class Project(Document):
|
|||||||
task = frappe.new_doc("Task")
|
task = frappe.new_doc("Task")
|
||||||
task.project = self.name
|
task.project = self.name
|
||||||
|
|
||||||
if not t.task_id or self.is_row_updated(t, existing_task_data):
|
if not t.task_id or self.is_row_updated(t, existing_task_data, fields):
|
||||||
task.update({
|
task.update({
|
||||||
"subject": t.title,
|
"subject": t.title,
|
||||||
"status": t.status,
|
"status": t.status,
|
||||||
@@ -120,7 +141,7 @@ class Project(Document):
|
|||||||
"modified": now()
|
"modified": now()
|
||||||
})
|
})
|
||||||
|
|
||||||
task.validate()
|
task.run_method("validate")
|
||||||
task.db_update()
|
task.db_update()
|
||||||
else:
|
else:
|
||||||
task.save(ignore_permissions = True)
|
task.save(ignore_permissions = True)
|
||||||
@@ -130,20 +151,19 @@ class Project(Document):
|
|||||||
|
|
||||||
# delete
|
# delete
|
||||||
for t in frappe.get_all("Task", ["name"], {"project": self.name, "name": ("not in", task_names)}):
|
for t in frappe.get_all("Task", ["name"], {"project": self.name, "name": ("not in", task_names)}):
|
||||||
frappe.delete_doc("Task", t.name)
|
self.deleted_task_list.append(t.name)
|
||||||
|
|
||||||
def update_costing_and_percentage_complete(self):
|
def update_costing_and_percentage_complete(self):
|
||||||
self.update_percent_complete()
|
self.update_percent_complete()
|
||||||
self.update_costing()
|
self.update_costing()
|
||||||
|
|
||||||
def is_row_updated(self, row, existing_task_data):
|
def is_row_updated(self, row, existing_task_data, fields):
|
||||||
if self.get("__islocal") or not existing_task_data: return True
|
if self.get("__islocal") or not existing_task_data: return True
|
||||||
|
|
||||||
d = existing_task_data.get(row.task_id)
|
d = existing_task_data.get(row.task_id)
|
||||||
|
|
||||||
if (d and (row.title != d.title or row.status != d.status
|
for field in fields:
|
||||||
or getdate(row.start_date) != getdate(d.start_date) or getdate(row.end_date) != getdate(d.end_date)
|
if row.get(field) != d.get(field):
|
||||||
or row.description != d.description or row.task_weight != d.task_weight)):
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def map_custom_fields(self, source, target):
|
def map_custom_fields(self, source, target):
|
||||||
@@ -263,9 +283,19 @@ class Project(Document):
|
|||||||
user.welcome_email_sent=1
|
user.welcome_email_sent=1
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
|
self.delete_task()
|
||||||
|
self.load_tasks()
|
||||||
self.update_costing_and_percentage_complete()
|
self.update_costing_and_percentage_complete()
|
||||||
self.update_dependencies_on_duplicated_project()
|
self.update_dependencies_on_duplicated_project()
|
||||||
|
|
||||||
|
def delete_task(self):
|
||||||
|
if not self.get('deleted_task_list'): return
|
||||||
|
|
||||||
|
for d in self.get('deleted_task_list'):
|
||||||
|
frappe.delete_doc("Task", d)
|
||||||
|
|
||||||
|
self.deleted_task_list = []
|
||||||
|
|
||||||
def update_dependencies_on_duplicated_project(self):
|
def update_dependencies_on_duplicated_project(self):
|
||||||
if self.flags.dont_sync_tasks: return
|
if self.flags.dont_sync_tasks: return
|
||||||
if not self.copied_from:
|
if not self.copied_from:
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (this.frm.doc.__islocal
|
||||||
|
&& frappe.meta.has_field(this.frm.doc.doctype, "disable_rounded_total")) {
|
||||||
|
this.frm.set_value("disable_rounded_total", cint(frappe.sys_defaults.disable_rounded_total));
|
||||||
|
}
|
||||||
|
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// no idea where me is coming from
|
// no idea where me is coming from
|
||||||
if(this.frm.get_field('shipping_address')) {
|
if(this.frm.get_field('shipping_address')) {
|
||||||
|
|||||||
Reference in New Issue
Block a user