Merge branch '1310' of github.com:webnotes/erpnext

Conflicts:
	accounts/doctype/account/account.py
	controllers/accounts_controller.py
	patches/patch_list.py
	selling/doctype/sales_common/sales_common.py
	stock/doctype/purchase_receipt/purchase_receipt.py
This commit is contained in:
Anand Doshi
2013-11-15 19:12:09 +05:30
26 changed files with 590 additions and 143 deletions

View File

@@ -30,6 +30,7 @@ class DocType:
self.validate_duplicate_account()
self.validate_root_details()
self.validate_mandatory()
self.validate_warehouse_account()
self.validate_frozen_accounts_modifier()
if not self.doc.parent_account:
@@ -165,24 +166,24 @@ class DocType:
in webnotes.user.get_roles():
return 1
def check_credit_limit(self, account, company, tot_outstanding):
def check_credit_limit(self, total_outstanding):
# Get credit limit
credit_limit_from = 'Customer'
cr_limit = webnotes.conn.sql("""select t1.credit_limit from tabCustomer t1, `tabAccount` t2
where t2.name=%s and t1.name = t2.master_name""", account)
where t2.name=%s and t1.name = t2.master_name""", self.doc.name)
credit_limit = cr_limit and flt(cr_limit[0][0]) or 0
if not credit_limit:
credit_limit = webnotes.conn.get_value('Company', company, 'credit_limit')
credit_limit_from = 'global settings in the Company'
credit_limit = webnotes.conn.get_value('Company', self.doc.company, 'credit_limit')
credit_limit_from = 'Company'
# If outstanding greater than credit limit and not authorized person raise exception
if credit_limit > 0 and flt(tot_outstanding) > credit_limit \
if credit_limit > 0 and flt(total_outstanding) > credit_limit \
and not self.get_authorized_user():
msgprint("""Total Outstanding amount (%s) for <b>%s</b> can not be \
greater than credit limit (%s). To change your credit limit settings, \
please update the <b>%s</b>""" % (fmt_money(tot_outstanding),
account, fmt_money(credit_limit), credit_limit_from), raise_exception=1)
please update in the <b>%s</b> master""" % (fmt_money(total_outstanding),
self.doc.name, fmt_money(credit_limit), credit_limit_from), raise_exception=1)
def validate_trash(self):
"""checks gl entries and if child exists"""

View File

@@ -16,7 +16,6 @@ class DocType:
self.check_mandatory()
self.pl_must_have_cost_center()
self.validate_posting_date()
self.check_credit_limit()
self.check_pl_account()
self.validate_cost_center()
@@ -55,21 +54,6 @@ class DocType:
from accounts.utils import validate_fiscal_year
validate_fiscal_year(self.doc.posting_date, self.doc.fiscal_year, "Posting Date")
def check_credit_limit(self):
master_type, master_name = webnotes.conn.get_value("Account",
self.doc.account, ["master_type", "master_name"])
tot_outstanding = 0 #needed when there is no GL Entry in the system for that acc head
if (self.doc.voucher_type=='Journal Voucher' or self.doc.voucher_type=='Sales Invoice') \
and (master_type =='Customer' and master_name):
dbcr = webnotes.conn.sql("""select sum(debit), sum(credit) from `tabGL Entry`
where account = %s""", self.doc.account)
if dbcr:
tot_outstanding = flt(dbcr[0][0]) - flt(dbcr[0][1]) + \
flt(self.doc.debit) - flt(self.doc.credit)
get_obj('Account',self.doc.account).check_credit_limit(self.doc.account,
self.doc.company, tot_outstanding)
def check_pl_account(self):
if self.doc.is_opening=='Yes' and \
webnotes.conn.get_value("Account", self.doc.account, "is_pl_account") == "Yes":

View File

@@ -44,6 +44,7 @@ class DocType(AccountsController):
self.check_credit_days()
self.check_account_against_entries()
self.make_gl_entries()
self.check_credit_limit()
def on_cancel(self):
from accounts.utils import remove_against_link_from_jv
@@ -259,6 +260,13 @@ class DocType(AccountsController):
)
if gl_map:
make_gl_entries(gl_map, cancel=cancel, adv_adj=adv_adj)
def check_credit_limit(self):
for d in self.doclist.get({"parentfield": "entries"}):
master_type, master_name = webnotes.conn.get_value("Account", d.account,
["master_type", "master_name"])
if master_type == "Customer" and master_name:
super(DocType, self).check_credit_limit(d.account)
def get_balance(self):
if not getlist(self.doclist,'entries'):

View File

@@ -91,6 +91,7 @@ class DocType(SellingController):
# this sequence because outstanding may get -ve
self.make_gl_entries()
self.check_credit_limit(self.doc.debit_to)
if not cint(self.doc.is_pos) == 1:
self.update_against_document_in_jv()
@@ -506,32 +507,39 @@ class DocType(SellingController):
self.make_sl_entries(sl_entries)
def make_gl_entries(self):
from accounts.general_ledger import make_gl_entries, merge_similar_entries
def make_gl_entries(self, update_gl_entries_after=True):
gl_entries = self.get_gl_entries()
if gl_entries:
from accounts.general_ledger import make_gl_entries
update_outstanding = cint(self.doc.is_pos) and self.doc.write_off_account \
and 'No' or 'Yes'
make_gl_entries(gl_entries, cancel=(self.doc.docstatus == 2),
update_outstanding=update_outstanding, merge_entries=False)
if update_gl_entries_after and cint(self.doc.update_stock) \
and cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")):
self.update_gl_entries_after()
def get_gl_entries(self, warehouse_account=None):
from accounts.general_ledger import merge_similar_entries
gl_entries = []
self.make_customer_gl_entry(gl_entries)
self.make_tax_gl_entries(gl_entries)
self.make_item_gl_entries(gl_entries)
# merge gl entries before adding pos entries
gl_entries = merge_similar_entries(gl_entries)
self.make_pos_gl_entries(gl_entries)
update_outstanding = cint(self.doc.is_pos) and self.doc.write_off_account and 'No' or 'Yes'
return gl_entries
if gl_entries:
make_gl_entries(gl_entries, cancel=(self.doc.docstatus == 2),
update_outstanding=update_outstanding, merge_entries=False)
if cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")) \
and cint(self.doc.update_stock):
self.update_gl_entries_after()
def make_customer_gl_entry(self, gl_entries):
if self.doc.grand_total:
gl_entries.append(
@@ -575,7 +583,7 @@ class DocType(SellingController):
# expense account gl entries
if cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")) \
and cint(self.doc.update_stock):
gl_entries += self.get_gl_entries_for_stock()
gl_entries += super(DocType, self).get_gl_entries()
def make_pos_gl_entries(self, gl_entries):
if cint(self.doc.is_pos) and self.doc.cash_bank_account and self.doc.paid_amount:

View File

@@ -3,7 +3,7 @@
import webnotes
import unittest, json
from webnotes.utils import flt, cint
from webnotes.utils import flt
from webnotes.model.bean import DocstatusTransitionError, TimestampMismatchError
from accounts.utils import get_stock_and_account_difference
from stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
@@ -364,6 +364,7 @@ class TestSalesInvoice(unittest.TestCase):
from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
order by account asc, debit asc""", si.doc.name, as_dict=1)
self.assertTrue(gl_entries)
# print gl_entries
stock_in_hand = webnotes.conn.get_value("Account", {"master_name": "_Test Warehouse - _TC"})
@@ -382,9 +383,6 @@ class TestSalesInvoice(unittest.TestCase):
self.assertEquals(expected_gl_entries[i][1], gle.debit)
self.assertEquals(expected_gl_entries[i][2], gle.credit)
# cancel
si.cancel()
gle = webnotes.conn.sql("""select * from `tabGL Entry`
where voucher_type='Sales Invoice' and voucher_no=%s""", si.doc.name)
@@ -395,6 +393,62 @@ class TestSalesInvoice(unittest.TestCase):
set_perpetual_inventory(0)
def test_si_gl_entry_with_aii_and_update_stock_with_warehouse_but_no_account(self):
self.clear_stock_account_balance()
set_perpetual_inventory()
webnotes.delete_doc("Account", "_Test Warehouse No Account - _TC")
# insert purchase receipt
from stock.doctype.purchase_receipt.test_purchase_receipt import test_records \
as pr_test_records
pr = webnotes.bean(copy=pr_test_records[0])
pr.doc.naming_series = "_T-Purchase Receipt-"
pr.doclist[1].warehouse = "_Test Warehouse No Account - _TC"
pr.run_method("calculate_taxes_and_totals")
pr.insert()
pr.submit()
si_doclist = webnotes.copy_doclist(test_records[1])
si_doclist[0]["update_stock"] = 1
si_doclist[0]["posting_time"] = "12:05"
si_doclist[1]["warehouse"] = "_Test Warehouse No Account - _TC"
si = webnotes.bean(copy=si_doclist)
si.insert()
si.submit()
# check stock ledger entries
sle = webnotes.conn.sql("""select * from `tabStock Ledger Entry`
where voucher_type = 'Sales Invoice' and voucher_no = %s""",
si.doc.name, as_dict=1)[0]
self.assertTrue(sle)
self.assertEquals([sle.item_code, sle.warehouse, sle.actual_qty],
["_Test Item", "_Test Warehouse No Account - _TC", -1.0])
# check gl entries
gl_entries = webnotes.conn.sql("""select account, debit, credit
from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
order by account asc, debit asc""", si.doc.name, as_dict=1)
self.assertTrue(gl_entries)
expected_gl_entries = sorted([
[si.doc.debit_to, 630.0, 0.0],
[si_doclist[1]["income_account"], 0.0, 500.0],
[si_doclist[2]["account_head"], 0.0, 80.0],
[si_doclist[3]["account_head"], 0.0, 50.0],
])
for i, gle in enumerate(gl_entries):
self.assertEquals(expected_gl_entries[i][0], gle.account)
self.assertEquals(expected_gl_entries[i][1], gle.debit)
self.assertEquals(expected_gl_entries[i][2], gle.credit)
si.cancel()
gle = webnotes.conn.sql("""select * from `tabGL Entry`
where voucher_type='Sales Invoice' and voucher_no=%s""", si.doc.name)
self.assertFalse(gle)
set_perpetual_inventory(0)
def test_sales_invoice_gl_entry_with_aii_no_item_code(self):
self.clear_stock_account_balance()
set_perpetual_inventory()
@@ -599,7 +653,7 @@ class TestSalesInvoice(unittest.TestCase):
self._test_recurring_invoice(si7, True)
def _test_recurring_invoice(self, base_si, first_and_last_day):
from webnotes.utils import add_months, get_last_day, getdate
from webnotes.utils import add_months, get_last_day
from accounts.doctype.sales_invoice.sales_invoice import manage_recurring_invoices
no_of_months = ({"Monthly": 1, "Quarterly": 3, "Yearly": 12})[base_si.doc.recurring_type]