Allow cost center in entry of balance sheet accounts (#14972)

* Allow Cost Center In Entry of Balance Sheet Account

* Add parent cost center in get payment entry

* Add Tests for Allow Cost Center In Entry of Balance Sheet Account

* Add tests for cost center wise account and party balance

* set parent cost center in taxes

* 1. Remove copy parent cost_center to child
2. Improve update party and account balance functionality on cost_center change
3. Add cost_center filter to get_outstanding_documents

* fix Codacy and Travis issue
This commit is contained in:
Sanjay Kumar
2018-09-06 13:09:35 +04:00
committed by Nabin Hait
parent b94008dab3
commit 1b49f3a4e7
28 changed files with 998 additions and 88 deletions

View File

@@ -296,6 +296,37 @@
"translatable": 0, "translatable": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "allow_cost_center_in_entry_of_bs_account",
"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 Cost Center In Entry of Balance Sheet Account",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
@@ -543,6 +574,7 @@
"reqd": 0, "reqd": 0,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0,
"unique": 0 "unique": 0
}, },
{ {
@@ -575,6 +607,7 @@
"reqd": 0, "reqd": 0,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0,
"unique": 0 "unique": 0
} }
], ],
@@ -589,7 +622,7 @@
"issingle": 1, "issingle": 1,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2018-02-21 16:47:38.043115", "modified": "2018-05-14 15:58:27.638576",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Accounts Settings", "name": "Accounts Settings",
@@ -597,7 +630,6 @@
"permissions": [ "permissions": [
{ {
"amend": 0, "amend": 0,
"apply_user_permissions": 0,
"cancel": 0, "cancel": 0,
"create": 1, "create": 1,
"delete": 0, "delete": 0,
@@ -617,7 +649,6 @@
}, },
{ {
"amend": 0, "amend": 0,
"apply_user_permissions": 0,
"cancel": 0, "cancel": 0,
"create": 0, "create": 0,
"delete": 0, "delete": 0,
@@ -637,7 +668,6 @@
}, },
{ {
"amend": 0, "amend": 0,
"apply_user_permissions": 0,
"cancel": 0, "cancel": 0,
"create": 0, "create": 0,
"delete": 0, "delete": 0,

View File

@@ -17,6 +17,7 @@ class AccountsSettings(Document):
def validate(self): def validate(self):
self.validate_stale_days() self.validate_stale_days()
self.enable_payment_schedule_in_print() self.enable_payment_schedule_in_print()
self.enable_fields_for_cost_center_settings()
def validate_stale_days(self): def validate_stale_days(self):
if not self.allow_stale and cint(self.stale_days) <= 0: if not self.allow_stale and cint(self.stale_days) <= 0:
@@ -29,3 +30,8 @@ class AccountsSettings(Document):
for doctype in ("Sales Order", "Sales Invoice", "Purchase Order", "Purchase Invoice"): for doctype in ("Sales Order", "Sales Invoice", "Purchase Order", "Purchase Invoice"):
make_property_setter(doctype, "due_date", "print_hide", show_in_print, "Check") make_property_setter(doctype, "due_date", "print_hide", show_in_print, "Check")
make_property_setter(doctype, "payment_schedule", "print_hide", 0 if show_in_print else 1, "Check") make_property_setter(doctype, "payment_schedule", "print_hide", 0 if show_in_print else 1, "Check")
def enable_fields_for_cost_center_settings(self):
show_field = 0 if cint(self.allow_cost_center_in_entry_of_bs_account) else 1
for doctype in ("Sales Invoice", "Purchase Invoice", "Payment Entry"):
make_property_setter(doctype, "cost_center", "hidden", show_field, "Check")

View File

@@ -5,3 +5,22 @@ from __future__ import unicode_literals
import frappe import frappe
test_records = frappe.get_test_records('Cost Center') test_records = frappe.get_test_records('Cost Center')
def create_cost_center(**args):
args = frappe._dict(args)
if args.cost_center_name:
company = args.company or "_Test Company"
company_abbr = frappe.db.get_value("Company", company, "abbr")
cc_name = args.cost_center_name + " - " + company_abbr
if not frappe.db.exists("Cost Center", cc_name):
cc = frappe.new_doc("Cost Center")
cc.company = args.company or "_Test Company"
cc.cost_center_name = args.cost_center_name
cc.is_group = args.is_group or 0
cc.parent_cost_center = args.parent_cost_center or "_Test Company - _TC"
cc.insert()

View File

@@ -67,7 +67,8 @@ class GLEntry(Document):
frappe.throw(_("{0} {1}: Cost Center is required for 'Profit and Loss' account {2}. Please set up a default Cost Center for the Company.") frappe.throw(_("{0} {1}: Cost Center is required for 'Profit and Loss' account {2}. Please set up a default Cost Center for the Company.")
.format(self.voucher_type, self.voucher_no, self.account)) .format(self.voucher_type, self.voucher_no, self.account))
else: else:
if self.cost_center: from erpnext.accounts.utils import get_allow_cost_center_in_entry_of_bs_account
if not get_allow_cost_center_in_entry_of_bs_account() and self.cost_center:
self.cost_center = None self.cost_center = None
if self.project: if self.project:
self.project = None self.project = None

View File

@@ -414,37 +414,18 @@ frappe.ui.form.on("Journal Entry Account", {
args: { args: {
company: frm.doc.company, company: frm.doc.company,
party_type: d.party_type, party_type: d.party_type,
party: d.party party: d.party,
cost_center: d.cost_center
} }
}); });
} }
}, },
cost_center: function(frm, dt, dn) {
erpnext.journal_entry.set_account_balance(frm, dt, dn);
},
account: function(frm, dt, dn) { account: function(frm, dt, dn) {
var d = locals[dt][dn]; erpnext.journal_entry.set_account_balance(frm, dt, dn);
if(d.account) {
if(!frm.doc.company) frappe.throw(__("Please select Company first"));
if(!frm.doc.posting_date) frappe.throw(__("Please select Posting Date first"));
return frappe.call({
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_account_balance_and_party_type",
args: {
account: d.account,
date: frm.doc.posting_date,
company: frm.doc.company,
debit: flt(d.debit_in_account_currency),
credit: flt(d.credit_in_account_currency),
exchange_rate: d.exchange_rate
},
callback: function(r) {
if(r.message) {
$.extend(d, r.message);
erpnext.journal_entry.set_debit_credit_in_company_currency(frm, dt, dn);
refresh_field('accounts');
}
}
});
}
}, },
debit_in_account_currency: function(frm, cdt, cdn) { debit_in_account_currency: function(frm, cdt, cdn) {
@@ -637,3 +618,33 @@ $.extend(erpnext.journal_entry, {
cur_frm.reload_doc(); cur_frm.reload_doc();
} }
}); });
$.extend(erpnext.journal_entry, {
set_account_balance: function(frm, dt, dn) {
var d = locals[dt][dn];
if(d.account) {
if(!frm.doc.company) frappe.throw(__("Please select Company first"));
if(!frm.doc.posting_date) frappe.throw(__("Please select Posting Date first"));
return frappe.call({
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_account_balance_and_party_type",
args: {
account: d.account,
date: frm.doc.posting_date,
company: frm.doc.company,
debit: flt(d.debit_in_account_currency),
credit: flt(d.credit_in_account_currency),
exchange_rate: d.exchange_rate,
cost_center: d.cost_center
},
callback: function(r) {
if(r.message) {
$.extend(d, r.message);
erpnext.journal_entry.set_debit_credit_in_company_currency(frm, dt, dn);
refresh_field('accounts');
}
}
});
}
},
});

View File

@@ -716,7 +716,7 @@ def get_payment_entry_against_invoice(dt, dn, amount=None, debit_in_account_cur
def get_payment_entry(ref_doc, args): def get_payment_entry(ref_doc, args):
cost_center = frappe.get_cached_value('Company', ref_doc.company, "cost_center") cost_center = ref_doc.get("cost_center") or frappe.get_cached_value('Company', ref_doc.company, "cost_center")
exchange_rate = 1 exchange_rate = 1
if args.get("party_account"): if args.get("party_account"):
# Modified to include the posting date for which the exchange rate is required. # Modified to include the posting date for which the exchange rate is required.
@@ -849,14 +849,14 @@ def get_outstanding(args):
} }
@frappe.whitelist() @frappe.whitelist()
def get_party_account_and_balance(company, party_type, party): def get_party_account_and_balance(company, party_type, party, cost_center=None):
if not frappe.has_permission("Account"): if not frappe.has_permission("Account"):
frappe.msgprint(_("No Permission"), raise_exception=1) frappe.msgprint(_("No Permission"), raise_exception=1)
account = get_party_account(party_type, party, company) account = get_party_account(party_type, party, company)
account_balance = get_balance_on(account=account) account_balance = get_balance_on(account=account, cost_center=cost_center)
party_balance = get_balance_on(party_type=party_type, party=party, company=company) party_balance = get_balance_on(party_type=party_type, party=party, company=company, cost_center=cost_center)
return { return {
"account": account, "account": account,
@@ -867,7 +867,7 @@ def get_party_account_and_balance(company, party_type, party):
@frappe.whitelist() @frappe.whitelist()
def get_account_balance_and_party_type(account, date, company, debit=None, credit=None, exchange_rate=None): def get_account_balance_and_party_type(account, date, company, debit=None, credit=None, exchange_rate=None, cost_center=None):
"""Returns dict of account balance and party type to be set in Journal Entry on selection of account.""" """Returns dict of account balance and party type to be set in Journal Entry on selection of account."""
if not frappe.has_permission("Account"): if not frappe.has_permission("Account"):
frappe.msgprint(_("No Permission"), raise_exception=1) frappe.msgprint(_("No Permission"), raise_exception=1)
@@ -886,7 +886,7 @@ def get_account_balance_and_party_type(account, date, company, debit=None, credi
party_type = "" party_type = ""
grid_values = { grid_values = {
"balance": get_balance_on(account, date), "balance": get_balance_on(account, date, cost_center=cost_center),
"party_type": party_type, "party_type": party_type,
"account_type": account_details.account_type, "account_type": account_details.account_type,
"account_currency": account_details.account_currency or company_currency, "account_currency": account_details.account_currency or company_currency,

View File

@@ -204,12 +204,72 @@ class TestJournalEntry(unittest.TestCase):
self.assertEqual(jv.inter_company_journal_entry_reference, "") self.assertEqual(jv.inter_company_journal_entry_reference, "")
self.assertEqual(jv1.inter_company_journal_entry_reference, "") self.assertEqual(jv1.inter_company_journal_entry_reference, "")
def test_jv_for_enable_allow_cost_center_in_entry_of_bs_account(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
jv = make_journal_entry("_Test Cash - _TC", "_Test Bank - _TC", 100, cost_center = cost_center, save=False)
jv.voucher_type = "Bank Entry"
jv.multi_currency = 0
jv.cheque_no = "112233"
jv.cheque_date = nowdate()
jv.insert()
jv.submit()
expected_values = {
"_Test Cash - _TC": {
"cost_center": cost_center
},
"_Test Bank - _TC": {
"cost_center": cost_center
}
}
gl_entries = frappe.db.sql("""select account, cost_center, debit, credit
from `tabGL Entry` where voucher_type='Journal Entry' and voucher_no=%s
order by account asc""", jv.name, as_dict=1)
self.assertTrue(gl_entries)
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
def test_jv_account_and_party_balance_for_enable_allow_cost_center_in_entry_of_bs_account(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
from erpnext.accounts.utils import get_balance_on
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
jv = make_journal_entry("_Test Cash - _TC", "_Test Bank - _TC", 100, cost_center = cost_center, save=False)
account_balance = get_balance_on(account="_Test Bank - _TC", cost_center=cost_center)
jv.voucher_type = "Bank Entry"
jv.multi_currency = 0
jv.cheque_no = "112233"
jv.cheque_date = nowdate()
jv.insert()
jv.submit()
expected_account_balance = account_balance - 100
account_balance = get_balance_on(account="_Test Bank - _TC", cost_center=cost_center)
self.assertEqual(expected_account_balance, account_balance)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
def make_journal_entry(account1, account2, amount, cost_center=None, posting_date=None, exchange_rate=1, save=True, submit=False, project=None): def make_journal_entry(account1, account2, amount, cost_center=None, posting_date=None, exchange_rate=1, save=True, submit=False, project=None):
if not cost_center: if not cost_center:
cost_center = "_Test Cost Center - _TC" cost_center = "_Test Cost Center - _TC"
jv = frappe.new_doc("Journal Entry") jv = frappe.new_doc("Journal Entry")
jv.posting_date = posting_date or "2013-02-14" jv.posting_date = posting_date or nowdate()
jv.company = "_Test Company" jv.company = "_Test Company"
jv.user_remark = "test" jv.user_remark = "test"
jv.multi_currency = 1 jv.multi_currency = 1

View File

@@ -245,7 +245,8 @@ frappe.ui.form.on('Payment Entry', {
company: frm.doc.company, company: frm.doc.company,
party_type: frm.doc.party_type, party_type: frm.doc.party_type,
party: frm.doc.party, party: frm.doc.party,
date: frm.doc.posting_date date: frm.doc.posting_date,
cost_center: frm.doc.cost_center
}, },
callback: function(r, rt) { callback: function(r, rt) {
if(r.message) { if(r.message) {
@@ -317,7 +318,8 @@ frappe.ui.form.on('Payment Entry', {
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_account_details", method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_account_details",
args: { args: {
"account": account, "account": account,
"date": frm.doc.posting_date "date": frm.doc.posting_date,
"cost_center": frm.doc.cost_center
}, },
callback: function(r, rt) { callback: function(r, rt) {
if(r.message) { if(r.message) {
@@ -505,7 +507,8 @@ frappe.ui.form.on('Payment Entry', {
"party_type": frm.doc.party_type, "party_type": frm.doc.party_type,
"payment_type": frm.doc.payment_type, "payment_type": frm.doc.payment_type,
"party": frm.doc.party, "party": frm.doc.party,
"party_account": frm.doc.payment_type=="Receive" ? frm.doc.paid_from : frm.doc.paid_to "party_account": frm.doc.payment_type=="Receive" ? frm.doc.paid_from : frm.doc.paid_to,
"cost_center": frm.doc.cost_center
} }
}, },
callback: function(r, rt) { callback: function(r, rt) {
@@ -859,3 +862,38 @@ frappe.ui.form.on('Payment Entry Deduction', {
frm.events.set_unallocated_amount(frm); frm.events.set_unallocated_amount(frm);
} }
}) })
frappe.ui.form.on('Payment Entry', {
cost_center: function(frm){
if (frm.doc.posting_date && (frm.doc.paid_from||frm.doc.paid_to)) {
return frappe.call({
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_party_and_account_balance",
args: {
company: frm.doc.company,
date: frm.doc.posting_date,
paid_from: frm.doc.paid_from,
paid_to: frm.doc.paid_to,
ptype: frm.doc.party_type,
pty: frm.doc.party,
cost_center: frm.doc.cost_center
},
callback: function(r, rt) {
if(r.message) {
frappe.run_serially([
() => {
frm.set_value("paid_from_account_balance", r.message.paid_from_account_balance);
frm.set_value("paid_to_account_balance", r.message.paid_to_account_balance);
frm.set_value("party_balance", r.message.party_balance);
},
() => {
if(frm.doc.payment_type != "Internal") {
frm.events.get_outstanding_documents(frm);
}
}
]);
}
}
});
}
},
})

View File

@@ -208,6 +208,39 @@
"translatable": 0, "translatable": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"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,
"translatable": 0,
"unique": 0
},
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,

View File

@@ -127,12 +127,12 @@ class PaymentEntry(AccountsController):
self.party_account = party_account self.party_account = party_account
if self.paid_from and not (self.paid_from_account_currency or self.paid_from_account_balance): if self.paid_from and not (self.paid_from_account_currency or self.paid_from_account_balance):
acc = get_account_details(self.paid_from, self.posting_date) acc = get_account_details(self.paid_from, self.posting_date, self.cost_center)
self.paid_from_account_currency = acc.account_currency self.paid_from_account_currency = acc.account_currency
self.paid_from_account_balance = acc.account_balance self.paid_from_account_balance = acc.account_balance
if self.paid_to and not (self.paid_to_account_currency or self.paid_to_account_balance): if self.paid_to and not (self.paid_to_account_currency or self.paid_to_account_balance):
acc = get_account_details(self.paid_to, self.posting_date) acc = get_account_details(self.paid_to, self.posting_date, self.cost_center)
self.paid_to_account_currency = acc.account_currency self.paid_to_account_currency = acc.account_currency
self.paid_to_account_balance = acc.account_balance self.paid_to_account_balance = acc.account_balance
@@ -419,7 +419,8 @@ class PaymentEntry(AccountsController):
"party_type": self.party_type, "party_type": self.party_type,
"party": self.party, "party": self.party,
"against": against_account, "against": against_account,
"account_currency": self.party_account_currency "account_currency": self.party_account_currency,
"cost_center": self.cost_center
}) })
dr_or_cr = "credit" if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit" dr_or_cr = "credit" if erpnext.get_party_account_type(self.party_type) == 'Receivable' else "debit"
@@ -462,7 +463,8 @@ class PaymentEntry(AccountsController):
"account_currency": self.paid_from_account_currency, "account_currency": self.paid_from_account_currency,
"against": self.party if self.payment_type=="Pay" else self.paid_to, "against": self.party if self.payment_type=="Pay" else self.paid_to,
"credit_in_account_currency": self.paid_amount, "credit_in_account_currency": self.paid_amount,
"credit": self.base_paid_amount "credit": self.base_paid_amount,
"cost_center": self.cost_center
}) })
) )
if self.payment_type in ("Receive", "Internal Transfer"): if self.payment_type in ("Receive", "Internal Transfer"):
@@ -472,7 +474,8 @@ class PaymentEntry(AccountsController):
"account_currency": self.paid_to_account_currency, "account_currency": self.paid_to_account_currency,
"against": self.party if self.payment_type=="Receive" else self.paid_from, "against": self.party if self.payment_type=="Receive" else self.paid_from,
"debit_in_account_currency": self.received_amount, "debit_in_account_currency": self.received_amount,
"debit": self.base_received_amount "debit": self.base_received_amount,
"cost_center": self.cost_center
}) })
) )
@@ -549,6 +552,10 @@ def get_outstanding_reference_documents(args):
condition = " and voucher_type='{0}' and voucher_no='{1}'"\ condition = " and voucher_type='{0}' and voucher_no='{1}'"\
.format(frappe.db.escape(args["voucher_type"]), frappe.db.escape(args["voucher_no"])) .format(frappe.db.escape(args["voucher_type"]), frappe.db.escape(args["voucher_no"]))
# Add cost center condition
if args.get("cost_center"):
condition += " and cost_center='%s'" % args.get("cost_center")
outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"), outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
args.get("party_account"), condition=condition) args.get("party_account"), condition=condition)
@@ -573,7 +580,7 @@ def get_outstanding_reference_documents(args):
return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
def get_orders_to_be_billed(posting_date, party_type, party, party_account_currency, company_currency): def get_orders_to_be_billed(posting_date, party_type, party, party_account_currency, company_currency, cost_center=None):
if party_type == "Customer": if party_type == "Customer":
voucher_type = 'Sales Order' voucher_type = 'Sales Order'
elif party_type == "Supplier": elif party_type == "Supplier":
@@ -581,6 +588,12 @@ def get_orders_to_be_billed(posting_date, party_type, party, party_account_curre
elif party_type == "Employee": elif party_type == "Employee":
voucher_type = None voucher_type = None
# Add cost center condition
doc = frappe.get_doc({"doctype": voucher_type})
condition = ""
if doc and hasattr(doc, 'cost_center'):
condition = " and cost_center='%s'" % cost_center
orders = [] orders = []
if voucher_type: if voucher_type:
ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total" ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
@@ -599,12 +612,14 @@ def get_orders_to_be_billed(posting_date, party_type, party, party_account_curre
and ifnull(status, "") != "Closed" and ifnull(status, "") != "Closed"
and {ref_field} > advance_paid and {ref_field} > advance_paid
and abs(100 - per_billed) > 0.01 and abs(100 - per_billed) > 0.01
{condition}
order by order by
transaction_date, name transaction_date, name
""".format(**{ """.format(**{
"ref_field": ref_field, "ref_field": ref_field,
"voucher_type": voucher_type, "voucher_type": voucher_type,
"party_type": scrub(party_type) "party_type": scrub(party_type),
"condition": condition
}), party, as_dict=True) }), party, as_dict=True)
order_list = [] order_list = []
@@ -616,7 +631,7 @@ def get_orders_to_be_billed(posting_date, party_type, party, party_account_curre
return order_list return order_list
def get_negative_outstanding_invoices(party_type, party, party_account, party_account_currency, company_currency): def get_negative_outstanding_invoices(party_type, party, party_account, party_account_currency, company_currency, cost_center=None):
voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice" voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice"
supplier_condition = "" supplier_condition = ""
if voucher_type == "Purchase Invoice": if voucher_type == "Purchase Invoice":
@@ -647,22 +662,23 @@ def get_negative_outstanding_invoices(party_type, party, party_account, party_ac
"grand_total_field": grand_total_field, "grand_total_field": grand_total_field,
"voucher_type": voucher_type, "voucher_type": voucher_type,
"party_type": scrub(party_type), "party_type": scrub(party_type),
"party_account": "debit_to" if party_type == "Customer" else "credit_to" "party_account": "debit_to" if party_type == "Customer" else "credit_to",
"cost_center": cost_center
}), (party, party_account), as_dict=True) }), (party, party_account), as_dict=True)
@frappe.whitelist() @frappe.whitelist()
def get_party_details(company, party_type, party, date): def get_party_details(company, party_type, party, date, cost_center=None):
if not frappe.db.exists(party_type, party): if not frappe.db.exists(party_type, party):
frappe.throw(_("Invalid {0}: {1}").format(party_type, party)) frappe.throw(_("Invalid {0}: {1}").format(party_type, party))
party_account = get_party_account(party_type, party, company) party_account = get_party_account(party_type, party, company)
account_currency = get_account_currency(party_account) account_currency = get_account_currency(party_account)
account_balance = get_balance_on(party_account, date) account_balance = get_balance_on(party_account, date, cost_center=cost_center)
_party_name = "title" if party_type == "Student" else party_type.lower() + "_name" _party_name = "title" if party_type == "Student" else party_type.lower() + "_name"
party_name = frappe.db.get_value(party_type, party, _party_name) party_name = frappe.db.get_value(party_type, party, _party_name)
party_balance = get_balance_on(party_type=party_type, party=party) party_balance = get_balance_on(party_type=party_type, party=party, cost_center=cost_center)
return { return {
"party_account": party_account, "party_account": party_account,
@@ -674,11 +690,11 @@ def get_party_details(company, party_type, party, date):
@frappe.whitelist() @frappe.whitelist()
def get_account_details(account, date): def get_account_details(account, date, cost_center=None):
frappe.has_permission('Payment Entry', throw=True) frappe.has_permission('Payment Entry', throw=True)
return frappe._dict({ return frappe._dict({
"account_currency": get_account_currency(account), "account_currency": get_account_currency(account),
"account_balance": get_balance_on(account, date), "account_balance": get_balance_on(account, date, cost_center=cost_center),
"account_type": frappe.db.get_value("Account", account, "account_type") "account_type": frappe.db.get_value("Account", account, "account_type")
}) })
@@ -855,6 +871,7 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
pe = frappe.new_doc("Payment Entry") pe = frappe.new_doc("Payment Entry")
pe.payment_type = payment_type pe.payment_type = payment_type
pe.company = doc.company pe.company = doc.company
pe.cost_center = doc.get("cost_center")
pe.posting_date = nowdate() pe.posting_date = nowdate()
pe.mode_of_payment = doc.get("mode_of_payment") pe.mode_of_payment = doc.get("mode_of_payment")
pe.party_type = party_type pe.party_type = party_type
@@ -913,3 +930,11 @@ def get_paid_amount(dt, dn, party_type, party, account, due_date):
""".format(dr_or_cr=dr_or_cr), (dt, dn, party_type, party, account, due_date)) """.format(dr_or_cr=dr_or_cr), (dt, dn, party_type, party, account, due_date))
return paid_amount[0][0] if paid_amount else 0 return paid_amount[0][0] if paid_amount else 0
@frappe.whitelist()
def get_party_and_account_balance(company, date, paid_from, paid_to=None, ptype=None, pty=None, cost_center=None):
return frappe._dict({
"party_balance": get_balance_on(party_type=ptype, party=pty, cost_center=cost_center),
"paid_from_account_balance": get_balance_on(paid_from, date, cost_center=cost_center),
"paid_to_account_balance": get_balance_on(paid_to, date=date, cost_center=cost_center)
})

View File

@@ -8,8 +8,8 @@ import unittest
from frappe.utils import flt, nowdate from frappe.utils import flt, nowdate
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry, InvalidPaymentEntry from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry, InvalidPaymentEntry
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice, create_sales_invoice_against_cost_center
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice, make_purchase_invoice_against_cost_center
from erpnext.hr.doctype.expense_claim.test_expense_claim import make_expense_claim from erpnext.hr.doctype.expense_claim.test_expense_claim import make_expense_claim
test_dependencies = ["Item"] test_dependencies = ["Item"]
@@ -322,7 +322,7 @@ class TestPaymentEntry(unittest.TestCase):
self.assertTrue(gl_entries) self.assertTrue(gl_entries)
for i, gle in enumerate(gl_entries): for gle in gl_entries:
self.assertEqual(expected_gle[gle.account][0], gle.account) self.assertEqual(expected_gle[gle.account][0], gle.account)
self.assertEqual(expected_gle[gle.account][1], gle.debit) self.assertEqual(expected_gle[gle.account][1], gle.debit)
self.assertEqual(expected_gle[gle.account][2], gle.credit) self.assertEqual(expected_gle[gle.account][2], gle.credit)
@@ -394,3 +394,176 @@ class TestPaymentEntry(unittest.TestCase):
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount")) outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
self.assertEqual(outstanding_amount, 0) self.assertEqual(outstanding_amount, 0)
def test_payment_entry_against_sales_invoice_for_enable_allow_cost_center_in_entry_of_bs_account(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
si = create_sales_invoice_against_cost_center(cost_center=cost_center, debit_to="Debtors - _TC")
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
self.assertEqual(pe.cost_center, si.cost_center)
pe.reference_no = "112211-1"
pe.reference_date = nowdate()
pe.paid_to = "_Test Bank - _TC"
pe.paid_amount = si.grand_total
pe.insert()
pe.submit()
expected_values = {
"_Test Bank - _TC": {
"cost_center": cost_center
},
"Debtors - _TC": {
"cost_center": cost_center
}
}
gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
debit_in_account_currency, credit_in_account_currency
from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
order by account asc""", pe.name, as_dict=1)
self.assertTrue(gl_entries)
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
def test_payment_entry_against_sales_invoice_for_disable_allow_cost_center_in_entry_of_bs_account(self):
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
si = create_sales_invoice(debit_to="Debtors - _TC")
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
pe.reference_no = "112211-2"
pe.reference_date = nowdate()
pe.paid_to = "_Test Bank - _TC"
pe.paid_amount = si.grand_total
pe.insert()
pe.submit()
gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
debit_in_account_currency, credit_in_account_currency
from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
order by account asc""", pe.name, as_dict=1)
self.assertTrue(gl_entries)
for gle in gl_entries:
self.assertEqual(gle.cost_center, None)
def test_payment_entry_against_purchase_invoice_for_enable_allow_cost_center_in_entry_of_bs_account(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
pi = make_purchase_invoice_against_cost_center(cost_center=cost_center, credit_to="Creditors - _TC")
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
self.assertEqual(pe.cost_center, pi.cost_center)
pe.reference_no = "112222-1"
pe.reference_date = nowdate()
pe.paid_from = "_Test Bank - _TC"
pe.paid_amount = pi.grand_total
pe.insert()
pe.submit()
expected_values = {
"_Test Bank - _TC": {
"cost_center": cost_center
},
"Creditors - _TC": {
"cost_center": cost_center
}
}
gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
debit_in_account_currency, credit_in_account_currency
from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
order by account asc""", pe.name, as_dict=1)
self.assertTrue(gl_entries)
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
def test_payment_entry_against_purchase_invoice_for_disable_allow_cost_center_in_entry_of_bs_account(self):
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
pi = make_purchase_invoice(credit_to="Creditors - _TC")
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
pe.reference_no = "112222-2"
pe.reference_date = nowdate()
pe.paid_from = "_Test Bank - _TC"
pe.paid_amount = pi.grand_total
pe.insert()
pe.submit()
gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
debit_in_account_currency, credit_in_account_currency
from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
order by account asc""", pe.name, as_dict=1)
self.assertTrue(gl_entries)
for gle in gl_entries:
self.assertEqual(gle.cost_center, None)
def test_payment_entry_account_and_party_balance_for_enable_allow_cost_center_in_entry_of_bs_account(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
from erpnext.accounts.utils import get_balance_on
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
si = create_sales_invoice_against_cost_center(cost_center=cost_center, debit_to="Debtors - _TC")
account_balance = get_balance_on(account="_Test Bank - _TC", cost_center=si.cost_center)
party_balance = get_balance_on(party_type="Customer", party=si.customer, cost_center=si.cost_center)
party_account_balance = get_balance_on(si.debit_to, cost_center=si.cost_center)
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
pe.reference_no = "112211-1"
pe.reference_date = nowdate()
pe.paid_to = "_Test Bank - _TC"
pe.paid_amount = si.grand_total
pe.insert()
pe.submit()
expected_account_balance = account_balance + si.grand_total
expected_party_balance = party_balance - si.grand_total
expected_party_account_balance = party_account_balance - si.grand_total
account_balance = get_balance_on(account=pe.paid_to, cost_center=pe.cost_center)
party_balance = get_balance_on(party_type="Customer", party=pe.party, cost_center=pe.cost_center)
party_account_balance = get_balance_on(account=pe.paid_from, cost_center=pe.cost_center)
self.assertEqual(pe.cost_center, si.cost_center)
self.assertEqual(expected_account_balance, account_balance)
self.assertEqual(expected_party_balance, party_balance)
self.assertEqual(expected_party_account_balance, party_account_balance)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()

View File

@@ -379,6 +379,39 @@
"translatable": 0, "translatable": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"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,
"translatable": 0,
"unique": 0
},
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,

View File

@@ -389,6 +389,7 @@ class PurchaseInvoice(BuyingController):
if self.party_account_currency==self.company_currency else grand_total, if self.party_account_currency==self.company_currency else grand_total,
"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name, "against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
"against_voucher_type": self.doctype, "against_voucher_type": self.doctype,
"cost_center": self.cost_center
}, self.party_account_currency) }, self.party_account_currency)
) )
@@ -472,7 +473,8 @@ class PurchaseInvoice(BuyingController):
"account": self.stock_received_but_not_billed, "account": self.stock_received_but_not_billed,
"against": self.supplier, "against": self.supplier,
"debit": flt(item.item_tax_amount, item.precision("item_tax_amount")), "debit": flt(item.item_tax_amount, item.precision("item_tax_amount")),
"remarks": self.remarks or "Accounting Entry for Stock" "remarks": self.remarks or "Accounting Entry for Stock",
"cost_center": self.cost_center
}) })
) )
@@ -500,7 +502,8 @@ class PurchaseInvoice(BuyingController):
"remarks": self.get("remarks") or _("Accounting Entry for Asset"), "remarks": self.get("remarks") or _("Accounting Entry for Asset"),
"debit": base_asset_amount, "debit": base_asset_amount,
"debit_in_account_currency": (base_asset_amount "debit_in_account_currency": (base_asset_amount
if asset_rbnb_currency == self.company_currency else asset_amount) if asset_rbnb_currency == self.company_currency else asset_amount),
"cost_center": item.cost_center
})) }))
if item.item_tax_amount: if item.item_tax_amount:
@@ -526,7 +529,8 @@ class PurchaseInvoice(BuyingController):
"remarks": self.get("remarks") or _("Accounting Entry for Asset"), "remarks": self.get("remarks") or _("Accounting Entry for Asset"),
"debit": base_asset_amount, "debit": base_asset_amount,
"debit_in_account_currency": (base_asset_amount "debit_in_account_currency": (base_asset_amount
if cwip_account_currency == self.company_currency else asset_amount) if cwip_account_currency == self.company_currency else asset_amount),
"cost_center": self.cost_center
})) }))
if item.item_tax_amount and not cint(erpnext.is_perpetual_inventory_enabled(self.company)): if item.item_tax_amount and not cint(erpnext.is_perpetual_inventory_enabled(self.company)):
@@ -626,6 +630,7 @@ class PurchaseInvoice(BuyingController):
if self.party_account_currency==self.company_currency else self.paid_amount, if self.party_account_currency==self.company_currency else self.paid_amount,
"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name, "against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
"against_voucher_type": self.doctype, "against_voucher_type": self.doctype,
"cost_center": self.cost_center
}, self.party_account_currency) }, self.party_account_currency)
) )
@@ -635,7 +640,8 @@ class PurchaseInvoice(BuyingController):
"against": self.supplier, "against": self.supplier,
"credit": self.base_paid_amount, "credit": self.base_paid_amount,
"credit_in_account_currency": self.base_paid_amount \ "credit_in_account_currency": self.base_paid_amount \
if bank_account_currency==self.company_currency else self.paid_amount if bank_account_currency==self.company_currency else self.paid_amount,
"cost_center": self.cost_center
}, bank_account_currency) }, bank_account_currency)
) )
@@ -656,6 +662,7 @@ class PurchaseInvoice(BuyingController):
if self.party_account_currency==self.company_currency else self.write_off_amount, if self.party_account_currency==self.company_currency else self.write_off_amount,
"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name, "against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
"against_voucher_type": self.doctype, "against_voucher_type": self.doctype,
"cost_center": self.cost_center
}, self.party_account_currency) }, self.party_account_currency)
) )
gl_entries.append( gl_entries.append(
@@ -665,7 +672,7 @@ class PurchaseInvoice(BuyingController):
"credit": flt(self.base_write_off_amount), "credit": flt(self.base_write_off_amount),
"credit_in_account_currency": self.base_write_off_amount \ "credit_in_account_currency": self.base_write_off_amount \
if write_off_account_currency==self.company_currency else self.write_off_amount, if write_off_account_currency==self.company_currency else self.write_off_amount,
"cost_center": self.write_off_cost_center "cost_center": self.cost_center or self.write_off_cost_center
}) })
) )
@@ -680,7 +687,7 @@ class PurchaseInvoice(BuyingController):
"against": self.supplier, "against": self.supplier,
"debit_in_account_currency": self.rounding_adjustment, "debit_in_account_currency": self.rounding_adjustment,
"debit": self.base_rounding_adjustment, "debit": self.base_rounding_adjustment,
"cost_center": round_off_cost_center, "cost_center": self.cost_center or round_off_cost_center,
} }
)) ))

View File

@@ -790,6 +790,66 @@ class TestPurchaseInvoice(unittest.TestCase):
pi_doc = frappe.get_doc('Purchase Invoice', pi.name) pi_doc = frappe.get_doc('Purchase Invoice', pi.name)
self.assertEqual(pi_doc.outstanding_amount, 0) self.assertEqual(pi_doc.outstanding_amount, 0)
def test_purchase_invoice_for_enable_allow_cost_center_in_entry_of_bs_account(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
pi = make_purchase_invoice_against_cost_center(cost_center=cost_center, credit_to="Creditors - _TC")
self.assertEqual(pi.cost_center, cost_center)
expected_values = {
"Creditors - _TC": {
"cost_center": cost_center
},
"_Test Account Cost for Goods Sold - _TC": {
"cost_center": cost_center
}
}
gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
debit_in_account_currency, credit_in_account_currency
from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
order by account asc""", pi.name, as_dict=1)
self.assertTrue(gl_entries)
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
def test_purchase_invoice_for_disable_allow_cost_center_in_entry_of_bs_account(self):
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
cost_center = "_Test Cost Center - _TC"
pi = make_purchase_invoice(credit_to="Creditors - _TC")
expected_values = {
"Creditors - _TC": {
"cost_center": None
},
"_Test Account Cost for Goods Sold - _TC": {
"cost_center": cost_center
}
}
gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
debit_in_account_currency, credit_in_account_currency
from `tabGL Entry` where voucher_type='Purchase Invoice' and voucher_no=%s
order by account asc""", pi.name, as_dict=1)
self.assertTrue(gl_entries)
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
def unlink_payment_on_cancel_of_invoice(enable=1): def unlink_payment_on_cancel_of_invoice(enable=1):
accounts_settings = frappe.get_doc("Accounts Settings") accounts_settings = frappe.get_doc("Accounts Settings")
accounts_settings.unlink_payment_on_cancellation_of_invoice = enable accounts_settings.unlink_payment_on_cancellation_of_invoice = enable
@@ -839,4 +899,50 @@ def make_purchase_invoice(**args):
pi.submit() pi.submit()
return pi return pi
def make_purchase_invoice_against_cost_center(**args):
pi = frappe.new_doc("Purchase Invoice")
args = frappe._dict(args)
pi.posting_date = args.posting_date or today()
if args.posting_time:
pi.posting_time = args.posting_time
if args.update_stock:
pi.update_stock = 1
if args.is_paid:
pi.is_paid = 1
if args.cash_bank_account:
pi.cash_bank_account=args.cash_bank_account
pi.company = args.company or "_Test Company"
pi.cost_center = args.cost_center or "_Test Cost Center - _TC"
pi.supplier = args.supplier or "_Test Supplier"
pi.currency = args.currency or "INR"
pi.conversion_rate = args.conversion_rate or 1
pi.is_return = args.is_return
pi.is_return = args.is_return
pi.credit_to = args.return_against or "Creditors - _TC"
pi.is_subcontracted = args.is_subcontracted or "No"
pi.supplier_warehouse = "_Test Warehouse 1 - _TC"
pi.append("items", {
"item_code": args.item or args.item_code or "_Test Item",
"warehouse": args.warehouse or "_Test Warehouse - _TC",
"qty": args.qty or 5,
"received_qty": args.received_qty or 0,
"rejected_qty": args.rejected_qty or 0,
"rate": args.rate or 50,
"conversion_factor": 1.0,
"serial_no": args.serial_no,
"stock_uom": "_Test UOM",
"cost_center": args.cost_center or "_Test Cost Center - _TC",
"project": args.project,
"rejected_warehouse": args.rejected_warehouse or "",
"rejected_serial_no": args.rejected_serial_no or ""
})
if not args.do_not_save:
pi.insert()
if not args.do_not_submit:
pi.submit()
return pi
test_records = frappe.get_test_records('Purchase Invoice') test_records = frappe.get_test_records('Purchase Invoice')

View File

@@ -447,6 +447,39 @@
"translatable": 0, "translatable": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"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,
"translatable": 0,
"unique": 0
},
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,

View File

@@ -735,7 +735,8 @@ class SalesInvoice(SellingController):
"debit_in_account_currency": grand_total_in_company_currency \ "debit_in_account_currency": grand_total_in_company_currency \
if self.party_account_currency==self.company_currency else grand_total, if self.party_account_currency==self.company_currency else grand_total,
"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name, "against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
"against_voucher_type": self.doctype "against_voucher_type": self.doctype,
"cost_center": self.cost_center
}, self.party_account_currency) }, self.party_account_currency)
) )
@@ -796,13 +797,14 @@ class SalesInvoice(SellingController):
"against": "Expense account - " + cstr(self.loyalty_redemption_account) + " for the Loyalty Program", "against": "Expense account - " + cstr(self.loyalty_redemption_account) + " for the Loyalty Program",
"credit": self.loyalty_amount, "credit": self.loyalty_amount,
"against_voucher": self.return_against if cint(self.is_return) else self.name, "against_voucher": self.return_against if cint(self.is_return) else self.name,
"against_voucher_type": self.doctype "against_voucher_type": self.doctype,
"cost_center": self.cost_center
}) })
) )
gl_entries.append( gl_entries.append(
self.get_gl_dict({ self.get_gl_dict({
"account": self.loyalty_redemption_account, "account": self.loyalty_redemption_account,
"cost_center": self.loyalty_redemption_cost_center, "cost_center": self.cost_center or self.loyalty_redemption_cost_center,
"against": self.customer, "against": self.customer,
"debit": self.loyalty_amount, "debit": self.loyalty_amount,
"remark": "Loyalty Points redeemed by the customer" "remark": "Loyalty Points redeemed by the customer"
@@ -826,6 +828,7 @@ class SalesInvoice(SellingController):
else payment_mode.amount, else payment_mode.amount,
"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name, "against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
"against_voucher_type": self.doctype, "against_voucher_type": self.doctype,
"cost_center": self.cost_center
}, self.party_account_currency) }, self.party_account_currency)
) )
@@ -837,7 +840,8 @@ class SalesInvoice(SellingController):
"debit": payment_mode.base_amount, "debit": payment_mode.base_amount,
"debit_in_account_currency": payment_mode.base_amount \ "debit_in_account_currency": payment_mode.base_amount \
if payment_mode_account_currency==self.company_currency \ if payment_mode_account_currency==self.company_currency \
else payment_mode.amount else payment_mode.amount,
"cost_center": self.cost_center
}, payment_mode_account_currency) }, payment_mode_account_currency)
) )
@@ -854,7 +858,8 @@ class SalesInvoice(SellingController):
"debit_in_account_currency": flt(self.base_change_amount) \ "debit_in_account_currency": flt(self.base_change_amount) \
if self.party_account_currency==self.company_currency else flt(self.change_amount), if self.party_account_currency==self.company_currency else flt(self.change_amount),
"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name, "against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
"against_voucher_type": self.doctype "against_voucher_type": self.doctype,
"cost_center": self.cost_center
}, self.party_account_currency) }, self.party_account_currency)
) )
@@ -862,7 +867,8 @@ class SalesInvoice(SellingController):
self.get_gl_dict({ self.get_gl_dict({
"account": self.account_for_change_amount, "account": self.account_for_change_amount,
"against": self.customer, "against": self.customer,
"credit": self.base_change_amount "credit": self.base_change_amount,
"cost_center": self.cost_center
}) })
) )
else: else:
@@ -884,7 +890,8 @@ class SalesInvoice(SellingController):
"credit_in_account_currency": self.base_write_off_amount \ "credit_in_account_currency": self.base_write_off_amount \
if self.party_account_currency==self.company_currency else self.write_off_amount, if self.party_account_currency==self.company_currency else self.write_off_amount,
"against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name, "against_voucher": self.return_against if cint(self.is_return) and self.return_against else self.name,
"against_voucher_type": self.doctype "against_voucher_type": self.doctype,
"cost_center": self.cost_center
}, self.party_account_currency) }, self.party_account_currency)
) )
gl_entries.append( gl_entries.append(
@@ -894,7 +901,7 @@ class SalesInvoice(SellingController):
"debit": self.base_write_off_amount, "debit": self.base_write_off_amount,
"debit_in_account_currency": self.base_write_off_amount \ "debit_in_account_currency": self.base_write_off_amount \
if write_off_account_currency==self.company_currency else self.write_off_amount, if write_off_account_currency==self.company_currency else self.write_off_amount,
"cost_center": self.write_off_cost_center or default_cost_center "cost_center": self.cost_center or self.write_off_cost_center or default_cost_center
}, write_off_account_currency) }, write_off_account_currency)
) )
@@ -909,7 +916,7 @@ class SalesInvoice(SellingController):
"against": self.customer, "against": self.customer,
"credit_in_account_currency": self.base_rounding_adjustment, "credit_in_account_currency": self.base_rounding_adjustment,
"credit": self.base_rounding_adjustment, "credit": self.base_rounding_adjustment,
"cost_center": round_off_cost_center, "cost_center": self.cost_center or round_off_cost_center,
} }
)) ))

View File

@@ -1438,6 +1438,66 @@ class TestSalesInvoice(unittest.TestCase):
si_doc = frappe.get_doc('Sales Invoice', si.name) si_doc = frappe.get_doc('Sales Invoice', si.name)
self.assertEqual(si_doc.outstanding_amount, 0) self.assertEqual(si_doc.outstanding_amount, 0)
def test_sales_invoice_for_enable_allow_cost_center_in_entry_of_bs_account(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
si = create_sales_invoice_against_cost_center(cost_center=cost_center, debit_to="Debtors - _TC")
self.assertEqual(si.cost_center, cost_center)
expected_values = {
"Debtors - _TC": {
"cost_center": cost_center
},
"Sales - _TC": {
"cost_center": cost_center
}
}
gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
debit_in_account_currency, credit_in_account_currency
from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
order by account asc""", si.name, as_dict=1)
self.assertTrue(gl_entries)
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
def test_sales_invoice_for_disable_allow_cost_center_in_entry_of_bs_account(self):
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center - _TC"
si = create_sales_invoice(debit_to="Debtors - _TC")
expected_values = {
"Debtors - _TC": {
"cost_center": None
},
"Sales - _TC": {
"cost_center": cost_center
}
}
gl_entries = frappe.db.sql("""select account, cost_center, account_currency, debit, credit,
debit_in_account_currency, credit_in_account_currency
from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
order by account asc""", si.name, as_dict=1)
self.assertTrue(gl_entries)
for gle in gl_entries:
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
def create_sales_invoice(**args): def create_sales_invoice(**args):
si = frappe.new_doc("Sales Invoice") si = frappe.new_doc("Sales Invoice")
args = frappe._dict(args) args = frappe._dict(args)
@@ -1478,6 +1538,48 @@ def create_sales_invoice(**args):
return si return si
def create_sales_invoice_against_cost_center(**args):
si = frappe.new_doc("Sales Invoice")
args = frappe._dict(args)
if args.posting_date:
si.set_posting_time = 1
si.posting_date = args.posting_date or nowdate()
si.company = args.company or "_Test Company"
si.cost_center = args.cost_center or "_Test Cost Center - _TC"
si.customer = args.customer or "_Test Customer"
si.debit_to = args.debit_to or "Debtors - _TC"
si.update_stock = args.update_stock
si.is_pos = args.is_pos
si.is_return = args.is_return
si.return_against = args.return_against
si.currency=args.currency or "INR"
si.conversion_rate = args.conversion_rate or 1
si.append("items", {
"item_code": args.item or args.item_code or "_Test Item",
"gst_hsn_code": "999800",
"warehouse": args.warehouse or "_Test Warehouse - _TC",
"qty": args.qty or 1,
"rate": args.rate or 100,
"income_account": "Sales - _TC",
"expense_account": "Cost of Goods Sold - _TC",
"cost_center": args.cost_center or "_Test Cost Center - _TC",
"serial_no": args.serial_no
})
if not args.do_not_save:
si.insert()
if not args.do_not_submit:
si.submit()
else:
si.payment_schedule = []
else:
si.payment_schedule = []
return si
test_dependencies = ["Journal Entry", "Contact", "Address"] test_dependencies = ["Journal Entry", "Contact", "Address"]
test_records = frappe.get_test_records('Sales Invoice') test_records = frappe.get_test_records('Sales Invoice')

View File

@@ -17,6 +17,21 @@ frappe.query_reports["General Ledger"] = {
"fieldtype": "Link", "fieldtype": "Link",
"options": "Finance Book" "options": "Finance Book"
}, },
{
"fieldname":"cost_center",
"label": __("Cost Center"),
"fieldtype": "Link",
"options": "Cost Center",
"get_query": function() {
var company = frappe.query_report.get_filter_value('company');
return {
"doctype": "Cost Center",
"filters": {
"company": company,
}
}
}
},
{ {
"fieldname":"from_date", "fieldname":"from_date",
"label": __("From Date"), "label": __("From Date"),

View File

@@ -154,6 +154,11 @@ def get_conditions(filters):
conditions.append("""account in (select name from tabAccount conditions.append("""account in (select name from tabAccount
where lft>=%s and rgt<=%s and docstatus<2)""" % (lft, rgt)) where lft>=%s and rgt<=%s and docstatus<2)""" % (lft, rgt))
if filters.get("cost_center"):
lft, rgt = frappe.db.get_value("Cost Center", filters["cost_center"], ["lft", "rgt"])
conditions.append("""cost_center in (select name from `tabCost Center`
where lft>=%s and rgt<=%s and docstatus<2)""" % (lft, rgt))
if filters.get("voucher_no"): if filters.get("voucher_no"):
conditions.append("voucher_no=%(voucher_no)s") conditions.append("voucher_no=%(voucher_no)s")

View File

@@ -12,6 +12,21 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
"default": frappe.defaults.get_user_default("Company"), "default": frappe.defaults.get_user_default("Company"),
"reqd": 1 "reqd": 1
}, },
{
"fieldname":"cost_center",
"label": __("Cost Center"),
"fieldtype": "Link",
"options": "Cost Center",
"get_query": function() {
var company = frappe.query_report.get_filter_value('company');
return {
"doctype": "Cost Center",
"filters": {
"company": company,
}
}
}
},
{ {
"fieldname": "fiscal_year", "fieldname": "fiscal_year",
"label": __("Fiscal Year"), "label": __("Fiscal Year"),

View File

@@ -84,7 +84,7 @@ def validate_fiscal_year(date, fiscal_year, company, label="Date", doc=None):
throw(_("{0} '{1}' not in Fiscal Year {2}").format(label, formatdate(date), fiscal_year)) throw(_("{0} '{1}' not in Fiscal Year {2}").format(label, formatdate(date), fiscal_year))
@frappe.whitelist() @frappe.whitelist()
def get_balance_on(account=None, date=None, party_type=None, party=None, company=None, in_account_currency=True): def get_balance_on(account=None, date=None, party_type=None, party=None, company=None, in_account_currency=True, cost_center=None):
if not account and frappe.form_dict.get("account"): if not account and frappe.form_dict.get("account"):
account = frappe.form_dict.get("account") account = frappe.form_dict.get("account")
if not date and frappe.form_dict.get("date"): if not date and frappe.form_dict.get("date"):
@@ -93,6 +93,9 @@ def get_balance_on(account=None, date=None, party_type=None, party=None, company
party_type = frappe.form_dict.get("party_type") party_type = frappe.form_dict.get("party_type")
if not party and frappe.form_dict.get("party"): if not party and frappe.form_dict.get("party"):
party = frappe.form_dict.get("party") party = frappe.form_dict.get("party")
if not cost_center and frappe.form_dict.get("cost_center"):
cost_center = frappe.form_dict.get("cost_center")
cond = [] cond = []
if date: if date:
@@ -113,17 +116,36 @@ def get_balance_on(account=None, date=None, party_type=None, party=None, company
# hence, assuming balance as 0.0 # hence, assuming balance as 0.0
return 0.0 return 0.0
allow_cost_center_in_entry_of_bs_account = get_allow_cost_center_in_entry_of_bs_account()
if cost_center and allow_cost_center_in_entry_of_bs_account:
cc = frappe.get_doc("Cost Center", cost_center)
if cc.is_group:
cond.append(""" exists (
select 1 from `tabCost Center` cc where cc.name = gle.cost_center
and cc.lft >= %s and cc.rgt <= %s
)""" % (cc.lft, cc.rgt))
else:
cond.append("""gle.cost_center = "%s" """ % (frappe.db.escape(cost_center, percent=False), ))
if account: if account:
acc = frappe.get_doc("Account", account) acc = frappe.get_doc("Account", account)
if not frappe.flags.ignore_account_permission: if not frappe.flags.ignore_account_permission:
acc.check_permission("read") acc.check_permission("read")
# for pl accounts, get balance within a fiscal year
if acc.report_type == 'Profit and Loss': if not allow_cost_center_in_entry_of_bs_account and acc.report_type == 'Profit and Loss':
# for pl accounts, get balance within a fiscal year
cond.append("posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" \
% year_start_date)
elif allow_cost_center_in_entry_of_bs_account:
# for all accounts, get balance within a fiscal year if maintain cost center in balance account is checked
cond.append("posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" \ cond.append("posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" \
% year_start_date) % year_start_date)
# different filter for group and ledger - improved performance # different filter for group and ledger - improved performance
if acc.is_group: if acc.is_group:
cond.append("""exists ( cond.append("""exists (
@@ -830,3 +852,10 @@ def get_coa(doctype, parent, is_root, chart=None):
accounts = [d for d in accounts if d['parent_account']==parent] accounts = [d for d in accounts if d['parent_account']==parent]
return accounts return accounts
def get_allow_cost_center_in_entry_of_bs_account():
def generator():
return cint(frappe.db.get_value('Accounts Settings', None, 'allow_cost_center_in_entry_of_bs_account'))
return frappe.local_cache("get_allow_cost_center_in_entry_of_bs_account", (), generator, regenerate_if_none=True)

View File

@@ -343,7 +343,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
weight_per_unit: item.weight_per_unit, weight_per_unit: item.weight_per_unit,
weight_uom: item.weight_uom, weight_uom: item.weight_uom,
uom : item.uom, uom : item.uom,
pos_profile: me.frm.doc.doctype == 'Sales Invoice' ? me.frm.doc.pos_profile : '' pos_profile: me.frm.doc.doctype == 'Sales Invoice' ? me.frm.doc.pos_profile : '',
cost_center: item.cost_center
} }
}, },

View File

@@ -78,6 +78,21 @@ function get_filters(){
"fieldtype": "Link", "fieldtype": "Link",
"options": "Finance Book" "options": "Finance Book"
}, },
{
"fieldname":"cost_center",
"label": __("Cost Center"),
"fieldtype": "Link",
"options": "Cost Center",
"get_query": function() {
var company = frappe.query_report.get_filter_value('company');
return {
"doctype": "Cost Center",
"filters": {
"company": company,
}
};
}
},
{ {
"fieldname":"from_fiscal_year", "fieldname":"from_fiscal_year",
"label": __("Start Year"), "label": __("Start Year"),

View File

@@ -201,7 +201,18 @@ $.extend(erpnext.utils, {
} else { } else {
return options[0]; return options[0];
} }
} },
copy_parent_value_in_all_row: function(doc, dt, dn, table_fieldname, fieldname, parent_fieldname) {
var d = locals[dt][dn];
if(d[fieldname]){
var cl = doc[table_fieldname] || [];
for(var i = 0; i < cl.length; i++) {
cl[i][fieldname] = doc[parent_fieldname];
}
}
refresh_field(table_fieldname);
},
}); });
erpnext.utils.select_alternate_items = function(opts) { erpnext.utils.select_alternate_items = function(opts) {

View File

@@ -569,6 +569,74 @@ class TestDeliveryNote(unittest.TestCase):
dt = make_delivery_trip(dn.name) dt = make_delivery_trip(dn.name)
self.assertEqual(dn.name, dt.delivery_stops[0].delivery_note) self.assertEqual(dn.name, dt.delivery_stops[0].delivery_note)
def test_delivery_note_for_enable_allow_cost_center_in_entry_of_bs_account(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
set_perpetual_inventory(1, company)
set_valuation_method("_Test Item", "FIFO")
make_stock_entry(target="_Test Warehouse - _TC", qty=5, basic_rate=100)
stock_in_hand_account = get_inventory_account('_Test Company')
dn = create_delivery_note(cost_center=cost_center)
gl_entries = get_gl_entries("Delivery Note", dn.name)
self.assertTrue(gl_entries)
expected_values = {
"Cost of Goods Sold - _TC": {
"cost_center": cost_center
},
stock_in_hand_account: {
"cost_center": cost_center
}
}
for i, gle in enumerate(gl_entries):
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
set_perpetual_inventory(0, company)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
def test_delivery_note_for_disable_allow_cost_center_in_entry_of_bs_account(self):
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
cost_center = "_Test Cost Center - _TC"
company = frappe.db.get_value('Warehouse', '_Test Warehouse - _TC', 'company')
set_perpetual_inventory(1, company)
set_valuation_method("_Test Item", "FIFO")
make_stock_entry(target="_Test Warehouse - _TC", qty=5, basic_rate=100)
stock_in_hand_account = get_inventory_account('_Test Company')
dn = create_delivery_note()
gl_entries = get_gl_entries("Delivery Note", dn.name)
self.assertTrue(gl_entries)
expected_values = {
"Cost of Goods Sold - _TC": {
"cost_center": cost_center
},
stock_in_hand_account: {
"cost_center": None
}
}
for i, gle in enumerate(gl_entries):
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
set_perpetual_inventory(0, company)
def create_delivery_note(**args): def create_delivery_note(**args):
dn = frappe.new_doc("Delivery Note") dn = frappe.new_doc("Delivery Note")
args = frappe._dict(args) args = frappe._dict(args)
@@ -589,7 +657,7 @@ def create_delivery_note(**args):
"rate": args.rate or 100, "rate": args.rate or 100,
"conversion_factor": 1.0, "conversion_factor": 1.0,
"expense_account": "Cost of Goods Sold - _TC", "expense_account": "Cost of Goods Sold - _TC",
"cost_center": "_Test Cost Center - _TC", "cost_center": args.cost_center or "_Test Cost Center - _TC",
"serial_no": args.serial_no, "serial_no": args.serial_no,
"target_warehouse": args.target_warehouse "target_warehouse": args.target_warehouse
}) })

View File

@@ -333,11 +333,78 @@ class TestPurchaseReceipt(unittest.TestCase):
pr.cancel() pr.cancel()
serial_nos = frappe.get_all('Serial No', {'asset': asset}, 'name') or [] serial_nos = frappe.get_all('Serial No', {'asset': asset}, 'name') or []
self.assertEquals(len(serial_nos), 0) self.assertEquals(len(serial_nos), 0)
frappe.db.sql("delete from `tabLocation") #frappe.db.sql("delete from `tabLocation")
frappe.db.sql("delete from `tabAsset`") frappe.db.sql("delete from `tabAsset`")
def test_purchase_receipt_for_enable_allow_cost_center_in_entry_of_bs_account(self):
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 1
accounts_settings.save()
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
if not frappe.db.exists('Location', 'Test Location'):
frappe.get_doc({
'doctype': 'Location',
'location_name': 'Test Location'
}).insert()
pr = make_purchase_receipt(cost_center=cost_center)
set_perpetual_inventory(1, pr.company)
stock_in_hand_account = get_inventory_account(pr.company, pr.get("items")[0].warehouse)
gl_entries = get_gl_entries("Purchase Receipt", pr.name)
self.assertTrue(gl_entries)
expected_values = {
"Stock Received But Not Billed - _TC": {
"cost_center": cost_center
},
stock_in_hand_account: {
"cost_center": cost_center
}
}
for i, gle in enumerate(gl_entries):
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
set_perpetual_inventory(0, pr.company)
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
def test_purchase_receipt_for_disable_allow_cost_center_in_entry_of_bs_account(self):
accounts_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
accounts_settings.allow_cost_center_in_entry_of_bs_account = 0
accounts_settings.save()
if not frappe.db.exists('Location', 'Test Location'):
frappe.get_doc({
'doctype': 'Location',
'location_name': 'Test Location'
}).insert()
pr = make_purchase_receipt()
set_perpetual_inventory(1, pr.company)
stock_in_hand_account = get_inventory_account(pr.company, pr.get("items")[0].warehouse)
gl_entries = get_gl_entries("Purchase Receipt", pr.name)
self.assertTrue(gl_entries)
expected_values = {
"Stock Received But Not Billed - _TC": {
"cost_center": None
},
stock_in_hand_account: {
"cost_center": None
}
}
for i, gle in enumerate(gl_entries):
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
set_perpetual_inventory(0, pr.company)
def get_gl_entries(voucher_type, voucher_no): def get_gl_entries(voucher_type, voucher_no):
return frappe.db.sql("""select account, debit, credit return frappe.db.sql("""select account, debit, credit, cost_center
from `tabGL Entry` where voucher_type=%s and voucher_no=%s from `tabGL Entry` where voucher_type=%s and voucher_no=%s
order by account desc""", (voucher_type, voucher_no), as_dict=1) order by account desc""", (voucher_type, voucher_no), as_dict=1)