[fix] [minor] auto accounting for stock transactions
This commit is contained in:
parent
d85d63bb81
commit
bb77756069
@ -12,19 +12,6 @@ class DocType:
|
|||||||
def __init__(self, d, dl):
|
def __init__(self, d, dl):
|
||||||
self.doc, self.doclist = d, dl
|
self.doc, self.doclist = d, dl
|
||||||
|
|
||||||
def validate(self):
|
|
||||||
self.validate_auto_accounting_for_stock()
|
|
||||||
|
|
||||||
def validate_auto_accounting_for_stock(self):
|
|
||||||
if cint(self.doc.auto_accounting_for_stock) == 1:
|
|
||||||
previous_val = cint(webnotes.conn.get_value("Accounts Settings",
|
|
||||||
None, "auto_accounting_for_stock"))
|
|
||||||
if cint(self.doc.auto_accounting_for_stock) != previous_val:
|
|
||||||
from accounts.utils import validate_stock_and_account_balance, \
|
|
||||||
create_stock_in_hand_jv
|
|
||||||
validate_stock_and_account_balance()
|
|
||||||
create_stock_in_hand_jv(reverse=cint(self.doc.auto_accounting_for_stock) < previous_val)
|
|
||||||
|
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
for key in ["auto_accounting_for_stock"]:
|
for key in ["auto_accounting_for_stock"]:
|
||||||
webnotes.conn.set_default(key, self.doc.fields.get(key, ''))
|
webnotes.conn.set_default(key, self.doc.fields.get(key, ''))
|
||||||
|
@ -32,6 +32,18 @@ class TestJournalVoucher(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertTrue(not webnotes.conn.sql("""select name from `tabJournal Voucher Detail`
|
self.assertTrue(not webnotes.conn.sql("""select name from `tabJournal Voucher Detail`
|
||||||
where against_jv=%s""", jv_invoice.doc.name))
|
where against_jv=%s""", jv_invoice.doc.name))
|
||||||
|
|
||||||
|
def test_jv_against_stock_account(self):
|
||||||
|
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
|
||||||
|
|
||||||
|
jv = webnotes.bean(copy=test_records[0])
|
||||||
|
jv.doclist[1].account = "_Test Account Stock in Hand - _TC"
|
||||||
|
jv.insert()
|
||||||
|
|
||||||
|
from accounts.general_ledger import StockAccountInvalidTransaction
|
||||||
|
self.assertRaises(StockAccountInvalidTransaction, jv.submit)
|
||||||
|
|
||||||
|
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
|
||||||
|
|
||||||
def test_monthly_budget_crossed_ignore(self):
|
def test_monthly_budget_crossed_ignore(self):
|
||||||
webnotes.conn.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
|
webnotes.conn.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
|
||||||
|
@ -90,7 +90,6 @@ class DocType(SellingController):
|
|||||||
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype,
|
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype,
|
||||||
self.doc.company, self.doc.grand_total, self)
|
self.doc.company, self.doc.grand_total, self)
|
||||||
|
|
||||||
self.set_buying_amount()
|
|
||||||
self.check_prev_docstatus()
|
self.check_prev_docstatus()
|
||||||
|
|
||||||
self.update_status_updater_args()
|
self.update_status_updater_args()
|
||||||
|
@ -330,13 +330,12 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertFalse(gle)
|
self.assertFalse(gle)
|
||||||
|
|
||||||
def atest_pos_gl_entry_with_aii(self):
|
def test_pos_gl_entry_with_aii(self):
|
||||||
webnotes.conn.sql("delete from `tabStock Ledger Entry`")
|
webnotes.conn.sql("delete from `tabStock Ledger Entry`")
|
||||||
|
webnotes.conn.sql("delete from `tabGL Entry`")
|
||||||
|
webnotes.conn.sql("delete from `tabBin`")
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
|
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
|
||||||
|
|
||||||
old_default_company = webnotes.conn.get_default("company")
|
|
||||||
webnotes.conn.set_default("company", "_Test Company")
|
|
||||||
|
|
||||||
self._insert_purchase_receipt()
|
self._insert_purchase_receipt()
|
||||||
self._insert_pos_settings()
|
self._insert_pos_settings()
|
||||||
|
|
||||||
@ -360,20 +359,18 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
["_Test Item", "_Test Warehouse - _TC", -1.0])
|
["_Test Item", "_Test Warehouse - _TC", -1.0])
|
||||||
|
|
||||||
# check gl entries
|
# check gl entries
|
||||||
stock_in_hand_account = webnotes.conn.get_value("Company", "_Test Company",
|
|
||||||
"stock_in_hand_account")
|
|
||||||
|
|
||||||
gl_entries = webnotes.conn.sql("""select account, debit, credit
|
gl_entries = webnotes.conn.sql("""select account, debit, credit
|
||||||
from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
|
from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
|
||||||
order by account asc, debit asc""", si.doc.name, as_dict=1)
|
order by account asc, debit asc""", si.doc.name, as_dict=1)
|
||||||
self.assertTrue(gl_entries)
|
self.assertTrue(gl_entries)
|
||||||
|
|
||||||
expected_gl_entries = sorted([
|
expected_gl_entries = sorted([
|
||||||
[si.doc.debit_to, 630.0, 0.0],
|
[si.doc.debit_to, 630.0, 0.0],
|
||||||
[pos[1]["income_account"], 0.0, 500.0],
|
[pos[1]["income_account"], 0.0, 500.0],
|
||||||
[pos[2]["account_head"], 0.0, 80.0],
|
[pos[2]["account_head"], 0.0, 80.0],
|
||||||
[pos[3]["account_head"], 0.0, 50.0],
|
[pos[3]["account_head"], 0.0, 50.0],
|
||||||
[stock_in_hand_account, 0.0, 75.0],
|
["_Test Account Stock In Hand - _TC", 0.0, 75.0],
|
||||||
[pos[1]["expense_account"], 75.0, 0.0],
|
[pos[1]["expense_account"], 75.0, 0.0],
|
||||||
[si.doc.debit_to, 0.0, 600.0],
|
[si.doc.debit_to, 0.0, 600.0],
|
||||||
["_Test Account Bank Account - _TC", 600.0, 0.0]
|
["_Test Account Bank Account - _TC", 600.0, 0.0]
|
||||||
@ -383,6 +380,8 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
self.assertEquals(expected_gl_entries[i][1], gle.debit)
|
self.assertEquals(expected_gl_entries[i][1], gle.debit)
|
||||||
self.assertEquals(expected_gl_entries[i][2], gle.credit)
|
self.assertEquals(expected_gl_entries[i][2], gle.credit)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# cancel
|
# cancel
|
||||||
si.cancel()
|
si.cancel()
|
||||||
gle = webnotes.conn.sql("""select * from `tabGL Entry`
|
gle = webnotes.conn.sql("""select * from `tabGL Entry`
|
||||||
@ -390,12 +389,11 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertFalse(gle)
|
self.assertFalse(gle)
|
||||||
|
|
||||||
self.assertFalse(get_stock_and_account_difference([si.doclist[1].warehouse]))
|
self.assertFalse(get_stock_and_account_difference(["_Test Account Stock In Hand - _TC"]))
|
||||||
|
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
|
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
|
||||||
webnotes.conn.set_default("company", old_default_company)
|
|
||||||
|
|
||||||
def atest_sales_invoice_gl_entry_with_aii_no_item_code(self):
|
def test_sales_invoice_gl_entry_with_aii_no_item_code(self):
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
|
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
|
||||||
|
|
||||||
si_copy = webnotes.copy_doclist(test_records[1])
|
si_copy = webnotes.copy_doclist(test_records[1])
|
||||||
@ -422,7 +420,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
|
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
|
webnotes.defaults.set_global_default("auto_accounting_for_stock", 0)
|
||||||
|
|
||||||
def atest_sales_invoice_gl_entry_with_aii_non_stock_item(self):
|
def test_sales_invoice_gl_entry_with_aii_non_stock_item(self):
|
||||||
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
|
webnotes.defaults.set_global_default("auto_accounting_for_stock", 1)
|
||||||
|
|
||||||
si_copy = webnotes.copy_doclist(test_records[1])
|
si_copy = webnotes.copy_doclist(test_records[1])
|
||||||
@ -641,7 +639,7 @@ class TestSalesInvoice(unittest.TestCase):
|
|||||||
return new_si
|
return new_si
|
||||||
|
|
||||||
# if yearly, test 3 repetitions, else test 13 repetitions
|
# if yearly, test 3 repetitions, else test 13 repetitions
|
||||||
count = no_of_months == 12 and 3 or 13
|
count = 3 if no_of_months == 12 else 13
|
||||||
for i in xrange(count):
|
for i in xrange(count):
|
||||||
base_si = _test(i)
|
base_si = _test(i)
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-06-04 11:02:19",
|
"creation": "2013-06-04 11:02:19",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-07-25 16:32:10",
|
"modified": "2013-08-29 16:58:56",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -416,17 +416,6 @@
|
|||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"doctype": "DocField",
|
|
||||||
"fieldname": "buying_amount",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"hidden": 1,
|
|
||||||
"label": "Buying Amount",
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"print_hide": 1,
|
|
||||||
"read_only": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
|
@ -5,8 +5,12 @@ from __future__ import unicode_literals
|
|||||||
import webnotes
|
import webnotes
|
||||||
from webnotes.utils import flt, cstr, now
|
from webnotes.utils import flt, cstr, now
|
||||||
from webnotes.model.doc import Document
|
from webnotes.model.doc import Document
|
||||||
|
from webnotes import msgprint, _
|
||||||
from accounts.utils import validate_expense_against_budget
|
from accounts.utils import validate_expense_against_budget
|
||||||
|
|
||||||
|
|
||||||
|
class StockAccountInvalidTransaction(webnotes.ValidationError): pass
|
||||||
|
|
||||||
def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True,
|
def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True,
|
||||||
update_outstanding='Yes'):
|
update_outstanding='Yes'):
|
||||||
if gl_map:
|
if gl_map:
|
||||||
@ -47,8 +51,8 @@ def merge_similar_entries(gl_map):
|
|||||||
merged_gl_map = filter(lambda x: flt(x.debit)!=0 or flt(x.credit)!=0, merged_gl_map)
|
merged_gl_map = filter(lambda x: flt(x.debit)!=0 or flt(x.credit)!=0, merged_gl_map)
|
||||||
return merged_gl_map
|
return merged_gl_map
|
||||||
|
|
||||||
def check_if_in_list(gle, gl_mqp):
|
def check_if_in_list(gle, gl_map):
|
||||||
for e in gl_mqp:
|
for e in gl_map:
|
||||||
if e.account == gle.account and \
|
if e.account == gle.account and \
|
||||||
cstr(e.get('against_voucher'))==cstr(gle.get('against_voucher')) \
|
cstr(e.get('against_voucher'))==cstr(gle.get('against_voucher')) \
|
||||||
and cstr(e.get('against_voucher_type')) == \
|
and cstr(e.get('against_voucher_type')) == \
|
||||||
@ -57,11 +61,14 @@ def check_if_in_list(gle, gl_mqp):
|
|||||||
return e
|
return e
|
||||||
|
|
||||||
def save_entries(gl_map, adv_adj, update_outstanding):
|
def save_entries(gl_map, adv_adj, update_outstanding):
|
||||||
|
validate_account_for_auto_accounting_for_stock(gl_map)
|
||||||
|
|
||||||
total_debit = total_credit = 0.0
|
total_debit = total_credit = 0.0
|
||||||
for entry in gl_map:
|
for entry in gl_map:
|
||||||
make_entry(entry, adv_adj, update_outstanding)
|
make_entry(entry, adv_adj, update_outstanding)
|
||||||
# check against budget
|
# check against budget
|
||||||
validate_expense_against_budget(entry)
|
validate_expense_against_budget(entry)
|
||||||
|
|
||||||
|
|
||||||
# update total debit / credit
|
# update total debit / credit
|
||||||
total_debit += flt(entry.debit)
|
total_debit += flt(entry.debit)
|
||||||
@ -79,8 +86,20 @@ def make_entry(args, adv_adj, update_outstanding):
|
|||||||
|
|
||||||
def validate_total_debit_credit(total_debit, total_credit):
|
def validate_total_debit_credit(total_debit, total_credit):
|
||||||
if abs(total_debit - total_credit) > 0.005:
|
if abs(total_debit - total_credit) > 0.005:
|
||||||
webnotes.throw(webnotes._("Debit and Credit not equal for this voucher: Diff (Debit) is ") +
|
webnotes.throw(_("Debit and Credit not equal for this voucher: Diff (Debit) is ") +
|
||||||
cstr(total_debit - total_credit))
|
cstr(total_debit - total_credit))
|
||||||
|
|
||||||
|
def validate_account_for_auto_accounting_for_stock(gl_map):
|
||||||
|
if gl_map[0].voucher_type=="Journal Voucher":
|
||||||
|
aii_accounts = [d[0] for d in webnotes.conn.sql("""select account from tabWarehouse
|
||||||
|
where ifnull(account, '')!=''""")]
|
||||||
|
|
||||||
|
for entry in gl_map:
|
||||||
|
if entry.account in aii_accounts:
|
||||||
|
webnotes.throw(_("Account") + ": " + entry.account +
|
||||||
|
_(" can only be debited/credited through Stock transactions"),
|
||||||
|
StockAccountInvalidTransaction)
|
||||||
|
|
||||||
|
|
||||||
def delete_gl_entries(gl_entries=None, voucher_type=None, voucher_no=None,
|
def delete_gl_entries(gl_entries=None, voucher_type=None, voucher_no=None,
|
||||||
adv_adj=False, update_outstanding="Yes"):
|
adv_adj=False, update_outstanding="Yes"):
|
||||||
|
@ -246,79 +246,6 @@ def get_company_default(company, fieldname):
|
|||||||
_("' in Company: ") + company), raise_exception=True)
|
_("' in Company: ") + company), raise_exception=True)
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def create_stock_in_hand_jv(reverse=False):
|
|
||||||
from webnotes.utils import nowdate
|
|
||||||
today = nowdate()
|
|
||||||
fiscal_year = get_fiscal_year(today)[0]
|
|
||||||
jv_list = []
|
|
||||||
|
|
||||||
for company in webnotes.conn.sql_list("select name from `tabCompany`"):
|
|
||||||
stock_rbnb_value = get_stock_rbnb_value(company)
|
|
||||||
stock_rbnb_value = reverse and -1*stock_rbnb_value or stock_rbnb_value
|
|
||||||
if stock_rbnb_value:
|
|
||||||
jv = webnotes.bean([
|
|
||||||
{
|
|
||||||
"doctype": "Journal Voucher",
|
|
||||||
"naming_series": "JV-AUTO-",
|
|
||||||
"company": company,
|
|
||||||
"posting_date": today,
|
|
||||||
"fiscal_year": fiscal_year,
|
|
||||||
"voucher_type": "Journal Entry",
|
|
||||||
"user_remark": (_("Perpetual Accounting") + ": " +
|
|
||||||
(_("Disabled") if reverse else _("Enabled")) + ". " +
|
|
||||||
_("Journal Entry for inventory that is received but not yet invoiced"))
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "Journal Voucher Detail",
|
|
||||||
"parentfield": "entries",
|
|
||||||
"account": get_company_default(company, "stock_received_but_not_billed"),
|
|
||||||
(stock_rbnb_value > 0 and "credit" or "debit"): abs(stock_rbnb_value)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"doctype": "Journal Voucher Detail",
|
|
||||||
"parentfield": "entries",
|
|
||||||
"account": get_company_default(company, "stock_adjustment_account"),
|
|
||||||
(stock_rbnb_value > 0 and "debit" or "credit"): abs(stock_rbnb_value),
|
|
||||||
"cost_center": get_company_default(company, "stock_adjustment_cost_center")
|
|
||||||
},
|
|
||||||
])
|
|
||||||
jv.insert()
|
|
||||||
|
|
||||||
jv_list.append(jv.doc.name)
|
|
||||||
|
|
||||||
if jv_list:
|
|
||||||
msgprint(_("Following Journal Vouchers have been created automatically") + \
|
|
||||||
":\n%s" % ("\n".join([("<a href=\"#Form/Journal Voucher/%s\">%s</a>" % (jv, jv)) for jv in jv_list]),))
|
|
||||||
|
|
||||||
msgprint(_("""These adjustment vouchers book the difference between \
|
|
||||||
the total value of received items and the total value of invoiced items, \
|
|
||||||
as a required step to use Perpetual Accounting.
|
|
||||||
This is an approximation to get you started.
|
|
||||||
You will need to submit these vouchers after checking if the values are correct.
|
|
||||||
For more details, read: \
|
|
||||||
<a href="http://erpnext.com/auto-inventory-accounting" target="_blank">\
|
|
||||||
Perpetual Accounting</a>"""))
|
|
||||||
|
|
||||||
webnotes.msgprint("""Please refresh the system to get effect of Perpetual Accounting""")
|
|
||||||
|
|
||||||
|
|
||||||
def get_stock_rbnb_value(company):
|
|
||||||
total_received_amount = webnotes.conn.sql("""select sum(valuation_rate*qty*conversion_factor)
|
|
||||||
from `tabPurchase Receipt Item` pr_item where docstatus=1
|
|
||||||
and exists(select name from `tabItem` where name = pr_item.item_code
|
|
||||||
and is_stock_item='Yes')
|
|
||||||
and exists(select name from `tabPurchase Receipt`
|
|
||||||
where name = pr_item.parent and company = %s)""", company)
|
|
||||||
|
|
||||||
total_billed_amount = webnotes.conn.sql("""select sum(valuation_rate*qty*conversion_factor)
|
|
||||||
from `tabPurchase Invoice Item` pi_item where docstatus=1
|
|
||||||
and exists(select name from `tabItem` where name = pi_item.item_code
|
|
||||||
and is_stock_item='Yes')
|
|
||||||
and exists(select name from `tabPurchase Invoice`
|
|
||||||
where name = pi_item.parent and company = %s)""", company)
|
|
||||||
return flt(total_received_amount[0][0]) - flt(total_billed_amount[0][0])
|
|
||||||
|
|
||||||
|
|
||||||
def fix_total_debit_credit():
|
def fix_total_debit_credit():
|
||||||
vouchers = webnotes.conn.sql("""select voucher_type, voucher_no,
|
vouchers = webnotes.conn.sql("""select voucher_type, voucher_no,
|
||||||
@ -335,14 +262,6 @@ def fix_total_debit_credit():
|
|||||||
where voucher_type = %s and voucher_no = %s and %s > 0 limit 1""" %
|
where voucher_type = %s and voucher_no = %s and %s > 0 limit 1""" %
|
||||||
(dr_or_cr, dr_or_cr, '%s', '%s', '%s', dr_or_cr),
|
(dr_or_cr, dr_or_cr, '%s', '%s', '%s', dr_or_cr),
|
||||||
(d.diff, d.voucher_type, d.voucher_no))
|
(d.diff, d.voucher_type, d.voucher_no))
|
||||||
|
|
||||||
def validate_stock_and_account_balance():
|
|
||||||
difference = get_stock_and_account_difference()
|
|
||||||
if difference:
|
|
||||||
msgprint(_("Account balance must be synced with stock balance, \
|
|
||||||
to enable perpetual accounting." +
|
|
||||||
_(" Following accounts are not synced with stock balance") + ": \n" +
|
|
||||||
"\n".join(difference.keys())), raise_exception=1)
|
|
||||||
|
|
||||||
def get_stock_and_account_difference(account_list=None, posting_date=None):
|
def get_stock_and_account_difference(account_list=None, posting_date=None):
|
||||||
from stock.utils import get_stock_balance_on
|
from stock.utils import get_stock_balance_on
|
||||||
|
@ -83,29 +83,6 @@ class SellingController(StockController):
|
|||||||
if self.meta.get_field("in_words_export"):
|
if self.meta.get_field("in_words_export"):
|
||||||
self.doc.in_words_export = money_in_words(disable_rounded_total and
|
self.doc.in_words_export = money_in_words(disable_rounded_total and
|
||||||
self.doc.grand_total_export or self.doc.rounded_total_export, self.doc.currency)
|
self.doc.grand_total_export or self.doc.rounded_total_export, self.doc.currency)
|
||||||
|
|
||||||
def set_buying_amount(self, stock_ledger_entries = None):
|
|
||||||
from stock.utils import get_buying_amount
|
|
||||||
if not stock_ledger_entries:
|
|
||||||
stock_ledger_entries = self.get_stock_ledger_entries()
|
|
||||||
|
|
||||||
item_sales_bom = {}
|
|
||||||
for d in self.doclist.get({"parentfield": "packing_details"}):
|
|
||||||
new_d = webnotes._dict(d.fields.copy())
|
|
||||||
new_d.total_qty = -1 * d.qty
|
|
||||||
item_sales_bom.setdefault(d.parent_item, []).append(new_d)
|
|
||||||
|
|
||||||
if stock_ledger_entries:
|
|
||||||
stock_items = self.get_stock_items()
|
|
||||||
for item in self.doclist.get({"parentfield": self.fname}):
|
|
||||||
if item.item_code in stock_items or \
|
|
||||||
(item_sales_bom and item_sales_bom.get(item.item_code)):
|
|
||||||
buying_amount = get_buying_amount(item.item_code, self.doc.doctype, self.doc.name, item.name,
|
|
||||||
stock_ledger_entries.get((item.item_code, item.warehouse), []),
|
|
||||||
item_sales_bom)
|
|
||||||
item.buying_amount = buying_amount >= 0.01 and buying_amount or 0
|
|
||||||
webnotes.conn.set_value(item.doctype, item.name, "buying_amount",
|
|
||||||
item.buying_amount)
|
|
||||||
|
|
||||||
def calculate_taxes_and_totals(self):
|
def calculate_taxes_and_totals(self):
|
||||||
self.other_fname = "other_charges"
|
self.other_fname = "other_charges"
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
|
|
||||||
# License: GNU General Public License v3. See license.txt
|
|
||||||
|
|
||||||
import webnotes
|
|
||||||
from webnotes.utils import now_datetime
|
|
||||||
|
|
||||||
def execute():
|
|
||||||
webnotes.reload_doc("stock", "doctype", "delivery_note_item")
|
|
||||||
webnotes.reload_doc("accounts", "doctype", "sales_invoice_item")
|
|
||||||
|
|
||||||
webnotes.conn.auto_commit_on_many_writes = True
|
|
||||||
for company in webnotes.conn.sql("select name from `tabCompany`"):
|
|
||||||
stock_ledger_entries = webnotes.conn.sql("""select item_code, voucher_type, voucher_no,
|
|
||||||
voucher_detail_no, posting_date, posting_time, stock_value,
|
|
||||||
warehouse, actual_qty as qty from `tabStock Ledger Entry`
|
|
||||||
where ifnull(`is_cancelled`, "No") = "No" and company = %s
|
|
||||||
order by item_code desc, warehouse desc,
|
|
||||||
posting_date desc, posting_time desc, name desc""", company[0], as_dict=True)
|
|
||||||
|
|
||||||
dn_list = webnotes.conn.sql("""select name from `tabDelivery Note`
|
|
||||||
where docstatus < 2 and company = %s""", company[0])
|
|
||||||
|
|
||||||
for dn in dn_list:
|
|
||||||
dn = webnotes.get_obj("Delivery Note", dn[0], with_children = 1)
|
|
||||||
dn.set_buying_amount(stock_ledger_entries)
|
|
||||||
|
|
||||||
si_list = webnotes.conn.sql("""select name from `tabSales Invoice`
|
|
||||||
where docstatus < 2 and company = %s""", company[0])
|
|
||||||
for si in si_list:
|
|
||||||
si = webnotes.get_obj("Sales Invoice", si[0], with_children = 1)
|
|
||||||
si.set_buying_amount(stock_ledger_entries)
|
|
||||||
|
|
||||||
webnotes.conn.auto_commit_on_many_writes = False
|
|
@ -186,7 +186,6 @@ class DocType(SellingController):
|
|||||||
|
|
||||||
self.credit_limit()
|
self.credit_limit()
|
||||||
|
|
||||||
self.set_buying_amount()
|
|
||||||
self.make_gl_entries()
|
self.make_gl_entries()
|
||||||
|
|
||||||
# set DN status
|
# set DN status
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-04-22 13:15:44",
|
"creation": "2013-04-22 13:15:44",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-08-07 14:45:30",
|
"modified": "2013-08-29 16:58:16",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -420,17 +420,6 @@
|
|||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"doctype": "DocField",
|
|
||||||
"fieldname": "buying_amount",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"hidden": 1,
|
|
||||||
"label": "Buying Amount",
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"print_hide": 1,
|
|
||||||
"read_only": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_on_submit": 1,
|
"allow_on_submit": 1,
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
|
@ -7,10 +7,7 @@ from webnotes.utils import cint, cstr, flt
|
|||||||
from webnotes.model.doc import addchild
|
from webnotes.model.doc import addchild
|
||||||
from webnotes.model.bean import getlist
|
from webnotes.model.bean import getlist
|
||||||
from webnotes.model.code import get_obj
|
from webnotes.model.code import get_obj
|
||||||
from webnotes import msgprint
|
from webnotes import msgprint, _
|
||||||
|
|
||||||
sql = webnotes.conn.sql
|
|
||||||
|
|
||||||
|
|
||||||
class DocType:
|
class DocType:
|
||||||
def __init__(self, doc, doclist=[]):
|
def __init__(self, doc, doclist=[]):
|
||||||
@ -18,47 +15,66 @@ class DocType:
|
|||||||
self.doclist = doclist
|
self.doclist = doclist
|
||||||
self.prwise_cost = {}
|
self.prwise_cost = {}
|
||||||
|
|
||||||
|
|
||||||
def check_mandatory(self):
|
def check_mandatory(self):
|
||||||
""" Check mandatory fields """
|
|
||||||
if not self.doc.from_pr_date or not self.doc.to_pr_date:
|
if not self.doc.from_pr_date or not self.doc.to_pr_date:
|
||||||
msgprint("Please enter From and To PR Date", raise_exception=1)
|
webnotes.throw(_("Please enter From and To PR Date"))
|
||||||
|
|
||||||
if not self.doc.currency:
|
if not self.doc.currency:
|
||||||
msgprint("Please enter Currency.", raise_exception=1)
|
webnotes.throw(_("Please enter Currency"))
|
||||||
|
|
||||||
|
def update_landed_cost(self):
|
||||||
|
"""
|
||||||
|
Add extra cost and recalculate all values in pr,
|
||||||
|
Recalculate valuation rate in all sle after pr posting date
|
||||||
|
"""
|
||||||
|
self.get_selected_pr()
|
||||||
|
self.validate_selected_pr()
|
||||||
|
self.add_charges_in_pr()
|
||||||
|
self.cal_charges_and_item_tax_amt()
|
||||||
|
self.update_sle()
|
||||||
|
msgprint("Landed Cost updated successfully")
|
||||||
|
|
||||||
|
def get_selected_pr(self):
|
||||||
|
""" Get selected purchase receipt no """
|
||||||
|
self.selected_pr = [d.purchase_receipt for d in \
|
||||||
|
self.doclist.get({"parentfield": "lc_pr_details"}) if d.select_pr]
|
||||||
|
if not self.selected_pr:
|
||||||
|
webnotes.throw(_("Please select atleast one PR to proceed."))
|
||||||
|
|
||||||
def get_purchase_receipts(self):
|
def get_purchase_receipts(self):
|
||||||
""" Get purchase receipts for given period """
|
""" Get purchase receipts for given period """
|
||||||
|
|
||||||
self.doclist = self.doc.clear_table(self.doclist,'lc_pr_details',1)
|
self.doclist = self.doc.clear_table(self.doclist,'lc_pr_details')
|
||||||
self.check_mandatory()
|
self.check_mandatory()
|
||||||
|
|
||||||
pr = sql("select name from `tabPurchase Receipt` where docstatus = 1 and posting_date >= '%s' and posting_date <= '%s' and currency = '%s' order by name " % (self.doc.from_pr_date, self.doc.to_pr_date, self.doc.currency), as_dict = 1)
|
pr = webnotes.conn.sql("""select name from `tabPurchase Receipt` where docstatus = 1
|
||||||
if len(pr)>200:
|
and posting_date>=%s and posting_date<=%s and currency=%s order by name """,
|
||||||
msgprint("Please enter date of shorter duration as there are too many purchase receipt, hence it cannot be loaded.", raise_exception=1)
|
(self.doc.from_pr_date, self.doc.to_pr_date, self.doc.currency), as_dict = 1)
|
||||||
|
if len(pr) > 200:
|
||||||
|
webnotes.throw(_("Please enter date of shorter duration as there are too many \
|
||||||
|
purchase receipt, hence it cannot be loaded."))
|
||||||
|
|
||||||
for i in pr:
|
for i in pr:
|
||||||
ch = addchild(self.doc, 'lc_pr_details', 'Landed Cost Purchase Receipt',
|
ch = addchild(self.doc, 'lc_pr_details', 'Landed Cost Purchase Receipt',
|
||||||
self.doclist)
|
self.doclist)
|
||||||
ch.purchase_receipt = i and i['name'] or ''
|
ch.purchase_receipt = i.name
|
||||||
ch.save()
|
|
||||||
|
|
||||||
def get_selected_pr(self):
|
|
||||||
""" Get selected purchase receipt no """
|
|
||||||
self.selected_pr = [d.purchase_receipt for d in getlist(self.doclist, 'lc_pr_details') if d.select_pr]
|
|
||||||
if not self.selected_pr:
|
|
||||||
msgprint("Please select atleast one PR to proceed.", raise_exception=1)
|
|
||||||
|
|
||||||
def validate_selected_pr(self):
|
def validate_selected_pr(self):
|
||||||
"""Validate selected PR as submitted"""
|
"""Validate selected PR as submitted"""
|
||||||
invalid_pr = sql("SELECT name FROM `tabPurchase Receipt` WHERE docstatus != 1 and name in (%s)" % ("'" + "', '".join(self.selected_pr) + "'"))
|
invalid_pr = webnotes.conn.sql("""SELECT name FROM `tabPurchase Receipt`
|
||||||
|
WHERE docstatus!=1 and name in (%s)""" %
|
||||||
|
', '.join(['%s']*len(self.selected_pr)), tuple(self.selected_pr))
|
||||||
if invalid_pr:
|
if invalid_pr:
|
||||||
msgprint("Selected purchase receipts must be submitted. Following PR are not submitted: %s" % invalid_pr, raise_exception=1)
|
webnotes.throw(_("Selected purchase receipts must be submitted. \
|
||||||
|
Following PR are not submitted") + ": " + invalid_pr)
|
||||||
|
|
||||||
|
|
||||||
def get_total_amt(self):
|
def get_total_amt(self):
|
||||||
""" Get sum of net total of all selected PR"""
|
""" Get sum of net total of all selected PR"""
|
||||||
return sql("SELECT SUM(net_total) FROM `tabPurchase Receipt` WHERE name in (%s)" % ("'" + "', '".join(self.selected_pr) + "'"))[0][0]
|
return webnotes.conn.sql("""SELECT SUM(net_total) FROM `tabPurchase Receipt`
|
||||||
|
WHERE name in (%s)""" % ', '.join(['%s']*len(self.selected_pr)),
|
||||||
|
tuple(self.selected_pr))[0][0]
|
||||||
|
|
||||||
|
|
||||||
def add_charges_in_pr(self):
|
def add_charges_in_pr(self):
|
||||||
@ -74,7 +90,9 @@ class DocType:
|
|||||||
self.prwise_cost[pr] = self.prwise_cost.get(pr, 0) + amt
|
self.prwise_cost[pr] = self.prwise_cost.get(pr, 0) + amt
|
||||||
cumulative_grand_total += amt
|
cumulative_grand_total += amt
|
||||||
|
|
||||||
pr_oc_row = sql("select name from `tabPurchase Taxes and Charges` where parent = %s and category = 'Valuation' and add_deduct_tax = 'Add' and charge_type = 'Actual' and account_head = %s",(pr, lc.account_head))
|
pr_oc_row = webnotes.conn.sql("""select name from `tabPurchase Taxes and Charges`
|
||||||
|
where parent = %s and category = 'Valuation' and add_deduct_tax = 'Add'
|
||||||
|
and charge_type = 'Actual' and account_head = %s""",(pr, lc.account_head))
|
||||||
if not pr_oc_row: # add if not exists
|
if not pr_oc_row: # add if not exists
|
||||||
ch = addchild(pr_obj.doc, 'purchase_tax_details', 'Purchase Taxes and Charges')
|
ch = addchild(pr_obj.doc, 'purchase_tax_details', 'Purchase Taxes and Charges')
|
||||||
ch.category = 'Valuation'
|
ch.category = 'Valuation'
|
||||||
@ -89,7 +107,9 @@ class DocType:
|
|||||||
ch.idx = 500 # add at the end
|
ch.idx = 500 # add at the end
|
||||||
ch.save(1)
|
ch.save(1)
|
||||||
else: # overwrite if exists
|
else: # overwrite if exists
|
||||||
sql("update `tabPurchase Taxes and Charges` set rate = %s, tax_amount = %s where name = %s and parent = %s ", (amt, amt, pr_oc_row[0][0], pr))
|
webnotes.conn.sql("""update `tabPurchase Taxes and Charges`
|
||||||
|
set rate = %s, tax_amount = %s where name = %s and parent = %s""",
|
||||||
|
(amt, amt, pr_oc_row[0][0], pr))
|
||||||
|
|
||||||
|
|
||||||
def reset_other_charges(self, pr_obj):
|
def reset_other_charges(self, pr_obj):
|
||||||
@ -201,9 +221,9 @@ class DocType:
|
|||||||
d.save()
|
d.save()
|
||||||
if d.serial_no:
|
if d.serial_no:
|
||||||
self.update_serial_no(d.serial_no, d.valuation_rate)
|
self.update_serial_no(d.serial_no, d.valuation_rate)
|
||||||
sql("update `tabStock Ledger Entry` set incoming_rate = '%s' where voucher_detail_no = '%s'"%(flt(d.valuation_rate), d.name))
|
webnotes.conn.sql("update `tabStock Ledger Entry` set incoming_rate = '%s' where voucher_detail_no = '%s'"%(flt(d.valuation_rate), d.name))
|
||||||
|
|
||||||
res = sql("""select item_code, warehouse, posting_date, posting_time
|
res = webnotes.conn.sql("""select item_code, warehouse, posting_date, posting_time
|
||||||
from `tabStock Ledger Entry` where voucher_detail_no = %s LIMIT 1""",
|
from `tabStock Ledger Entry` where voucher_detail_no = %s LIMIT 1""",
|
||||||
d.name, as_dict=1)
|
d.name, as_dict=1)
|
||||||
|
|
||||||
@ -211,22 +231,9 @@ class DocType:
|
|||||||
if res:
|
if res:
|
||||||
update_entries_after(res[0])
|
update_entries_after(res[0])
|
||||||
|
|
||||||
|
|
||||||
def update_serial_no(self, sr_no, rate):
|
def update_serial_no(self, sr_no, rate):
|
||||||
""" update valuation rate in serial no"""
|
""" update valuation rate in serial no"""
|
||||||
sr_no = map(lambda x: x.strip(), cstr(sr_no).split('\n'))
|
sr_no = map(lambda x: x.strip(), cstr(sr_no).split('\n'))
|
||||||
|
|
||||||
webnotes.conn.sql("""update `tabSerial No` set purchase_rate = %s where name in (%s)""" %
|
webnotes.conn.sql("""update `tabSerial No` set purchase_rate = %s where name in (%s)""" %
|
||||||
('%s', ', '.join(['%s']*len(sr_no))), tuple([rate] + sr_no))
|
('%s', ', '.join(['%s']*len(sr_no))), tuple([rate] + sr_no))
|
||||||
|
|
||||||
def update_landed_cost(self):
|
|
||||||
"""
|
|
||||||
Add extra cost and recalculate all values in pr,
|
|
||||||
Recalculate valuation rate in all sle after pr posting date
|
|
||||||
"""
|
|
||||||
self.get_selected_pr()
|
|
||||||
self.validate_selected_pr()
|
|
||||||
self.add_charges_in_pr()
|
|
||||||
self.cal_charges_and_item_tax_amt()
|
|
||||||
self.update_sle()
|
|
||||||
msgprint("Landed Cost updated successfully")
|
|
@ -39,9 +39,9 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
|||||||
};
|
};
|
||||||
|
|
||||||
if(cint(wn.defaults.get_default("auto_accounting_for_stock"))) {
|
if(cint(wn.defaults.get_default("auto_accounting_for_stock"))) {
|
||||||
this.frm.add_fetch("company", "stock_adjustment_account", "expense_adjustment_account");
|
this.frm.add_fetch("company", "stock_adjustment_account", "expense_account");
|
||||||
|
this.frm.fields_dict.mtn_details.grid.get_field('expense_account').get_query =
|
||||||
this.frm.fields_dict["expense_adjustment_account"].get_query = function() {
|
function() {
|
||||||
return {
|
return {
|
||||||
filters: {
|
filters: {
|
||||||
"company": me.frm.doc.company,
|
"company": me.frm.doc.company,
|
||||||
@ -88,7 +88,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
|||||||
set_default_account: function() {
|
set_default_account: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
|
|
||||||
if (cint(wn.defaults.get_default("auto_inventory_accounting")) && !this.frm.doc.expense_adjustment_account) {
|
if(cint(wn.defaults.get_default("auto_accounting_for_stock")) {
|
||||||
var account_for = "stock_adjustment_account";
|
var account_for = "stock_adjustment_account";
|
||||||
if (this.frm.doc.purpose == "Sales Return")
|
if (this.frm.doc.purpose == "Sales Return")
|
||||||
account_for = "stock_in_hand_account";
|
account_for = "stock_in_hand_account";
|
||||||
@ -102,12 +102,22 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
|||||||
"company": this.frm.doc.company
|
"company": this.frm.doc.company
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if (!r.exc) me.frm.set_value("expense_adjustment_account", r.message);
|
if (!r.exc) {
|
||||||
|
for(d in getchildren('Stock Entry Detail',doc.name,'mtn_details')) {
|
||||||
|
if(!d.expense_account) d.expense_account = r.message;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
entries_add: function(doc, cdt, cdn) {
|
||||||
|
var row = wn.model.get_doc(cdt, cdn);
|
||||||
|
this.frm.script_manager.copy_from_first_row("mtn_details", row,
|
||||||
|
["expense_account", "cost_center"]);
|
||||||
|
},
|
||||||
|
|
||||||
clean_up: function() {
|
clean_up: function() {
|
||||||
// Clear Production Order record from locals, because it is updated via Stock Entry
|
// Clear Production Order record from locals, because it is updated via Stock Entry
|
||||||
if(this.frm.doc.production_order &&
|
if(this.frm.doc.production_order &&
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-03-29 18:22:12",
|
"creation": "2013-03-29 18:22:12",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-08-28 19:15:55",
|
"modified": "2013-08-28 19:25:38",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -149,7 +149,7 @@
|
|||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "expense_account",
|
"fieldname": "expense_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Expense/Adjustment Account",
|
"label": "Difference Account",
|
||||||
"options": "Account",
|
"options": "Account",
|
||||||
"print_hide": 1
|
"print_hide": 1
|
||||||
},
|
},
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2013-03-28 10:35:31",
|
"creation": "2013-03-28 10:35:31",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-08-07 18:16:18",
|
"modified": "2013-08-29 16:46:33",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -102,11 +102,11 @@
|
|||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:sys_defaults.auto_inventory_accounting",
|
"depends_on": "eval:sys_defaults.auto_accounting_for_stock",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "expense_account",
|
"fieldname": "expense_account",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Expense Account",
|
"label": "Difference Account",
|
||||||
"options": "Account"
|
"options": "Account"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -22,7 +22,6 @@ cur_frm.set_query("account", function() {
|
|||||||
filters: {
|
filters: {
|
||||||
"company": cur_frm.doc.company,
|
"company": cur_frm.doc.company,
|
||||||
"debit_or_credit": "Debit",
|
"debit_or_credit": "Debit",
|
||||||
"is_pl_account": "No",
|
|
||||||
'group_or_ledger': "Ledger"
|
'group_or_ledger': "Ledger"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import webnotes
|
import webnotes
|
||||||
|
|
||||||
from webnotes.utils import flt, validate_email_add
|
from webnotes.utils import cint, flt, validate_email_add
|
||||||
from webnotes.model.code import get_obj
|
from webnotes.model.code import get_obj
|
||||||
from webnotes import msgprint
|
from webnotes import msgprint
|
||||||
|
|
||||||
@ -23,6 +23,21 @@ class DocType:
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
if self.doc.email_id and not validate_email_add(self.doc.email_id):
|
if self.doc.email_id and not validate_email_add(self.doc.email_id):
|
||||||
msgprint("Please enter valid Email Id", raise_exception=1)
|
msgprint("Please enter valid Email Id", raise_exception=1)
|
||||||
|
|
||||||
|
self.account_mandatory()
|
||||||
|
|
||||||
|
def account_mandatory(self):
|
||||||
|
if cint(webnotes.defaults.get_global_default("auto_accounting_for_stock")):
|
||||||
|
sle_exists = webnotes.conn.get_value("Stock Ledger Entry", {"warehouse": self.doc.name})
|
||||||
|
if not self.doc.account and (self.doc.__islocal or not sle_exists):
|
||||||
|
webnotes.throw(_("Asset/Expense Account mandatory"))
|
||||||
|
|
||||||
|
if not self.doc.__islocal and sle_exists:
|
||||||
|
old_account = webnotes.conn.get_value("Warehouse", self.doc.name, "account")
|
||||||
|
if old_account != self.doc.account:
|
||||||
|
webnotes.throw(_("Account can not be changed/assigned/removed as \
|
||||||
|
stock transactions exist for this warehouse"))
|
||||||
|
|
||||||
|
|
||||||
def merge_warehouses(self):
|
def merge_warehouses(self):
|
||||||
webnotes.conn.auto_commit_on_many_writes = 1
|
webnotes.conn.auto_commit_on_many_writes = 1
|
||||||
|
@ -82,7 +82,7 @@ def update_entries_after(args, verbose=1):
|
|||||||
|
|
||||||
valuation_method = get_valuation_method(args["item_code"])
|
valuation_method = get_valuation_method(args["item_code"])
|
||||||
stock_value_difference = 0.0
|
stock_value_difference = 0.0
|
||||||
|
|
||||||
for sle in entries_to_fix:
|
for sle in entries_to_fix:
|
||||||
if sle.serial_no or not cint(webnotes.conn.get_default("allow_negative_stock")):
|
if sle.serial_no or not cint(webnotes.conn.get_default("allow_negative_stock")):
|
||||||
# validate negative stock for serialized items, fifo valuation
|
# validate negative stock for serialized items, fifo valuation
|
||||||
@ -90,7 +90,7 @@ def update_entries_after(args, verbose=1):
|
|||||||
if not validate_negative_stock(qty_after_transaction, sle):
|
if not validate_negative_stock(qty_after_transaction, sle):
|
||||||
qty_after_transaction += flt(sle.actual_qty)
|
qty_after_transaction += flt(sle.actual_qty)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if sle.serial_no:
|
if sle.serial_no:
|
||||||
valuation_rate = get_serialized_values(qty_after_transaction, sle, valuation_rate)
|
valuation_rate = get_serialized_values(qty_after_transaction, sle, valuation_rate)
|
||||||
elif valuation_method == "Moving Average":
|
elif valuation_method == "Moving Average":
|
||||||
@ -172,6 +172,7 @@ def get_stock_ledger_entries(args, conditions=None, order="desc", limit=None, fo
|
|||||||
return webnotes.conn.sql("""select * from `tabStock Ledger Entry`
|
return webnotes.conn.sql("""select * from `tabStock Ledger Entry`
|
||||||
where item_code = %%(item_code)s
|
where item_code = %%(item_code)s
|
||||||
and warehouse = %%(warehouse)s
|
and warehouse = %%(warehouse)s
|
||||||
|
and ifnull(is_cancelled, 'No')='No'
|
||||||
%(conditions)s
|
%(conditions)s
|
||||||
order by timestamp(posting_date, posting_time) %(order)s, name %(order)s
|
order by timestamp(posting_date, posting_time) %(order)s, name %(order)s
|
||||||
%(limit)s %(for_update)s""" % {
|
%(limit)s %(for_update)s""" % {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user