[fix] [minor] auto accounting for stock transactions
diff --git a/accounts/doctype/accounts_settings/accounts_settings.py b/accounts/doctype/accounts_settings/accounts_settings.py
index 5f0d276..b18f14d 100644
--- a/accounts/doctype/accounts_settings/accounts_settings.py
+++ b/accounts/doctype/accounts_settings/accounts_settings.py
@@ -12,19 +12,6 @@
def __init__(self, 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):
for key in ["auto_accounting_for_stock"]:
webnotes.conn.set_default(key, self.doc.fields.get(key, ''))
diff --git a/accounts/doctype/journal_voucher/test_journal_voucher.py b/accounts/doctype/journal_voucher/test_journal_voucher.py
index 6c24c91..6ade931 100644
--- a/accounts/doctype/journal_voucher/test_journal_voucher.py
+++ b/accounts/doctype/journal_voucher/test_journal_voucher.py
@@ -32,6 +32,18 @@
self.assertTrue(not webnotes.conn.sql("""select name from `tabJournal Voucher Detail`
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):
webnotes.conn.set_value("Company", "_Test Company", "monthly_bgt_flag", "Ignore")
diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py
index b31eda5..fe2ed63 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/accounts/doctype/sales_invoice/sales_invoice.py
@@ -90,7 +90,6 @@
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype,
self.doc.company, self.doc.grand_total, self)
- self.set_buying_amount()
self.check_prev_docstatus()
self.update_status_updater_args()
diff --git a/accounts/doctype/sales_invoice/test_sales_invoice.py b/accounts/doctype/sales_invoice/test_sales_invoice.py
index 4f82efc..c2b9c8f 100644
--- a/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -330,13 +330,12 @@
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 `tabGL Entry`")
+ webnotes.conn.sql("delete from `tabBin`")
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_pos_settings()
@@ -360,20 +359,18 @@
["_Test Item", "_Test Warehouse - _TC", -1.0])
# 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
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],
[pos[1]["income_account"], 0.0, 500.0],
[pos[2]["account_head"], 0.0, 80.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],
[si.doc.debit_to, 0.0, 600.0],
["_Test Account Bank Account - _TC", 600.0, 0.0]
@@ -383,6 +380,8 @@
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`
@@ -390,12 +389,11 @@
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.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)
si_copy = webnotes.copy_doclist(test_records[1])
@@ -422,7 +420,7 @@
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)
si_copy = webnotes.copy_doclist(test_records[1])
@@ -641,7 +639,7 @@
return new_si
# 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):
base_si = _test(i)
diff --git a/accounts/doctype/sales_invoice_item/sales_invoice_item.txt b/accounts/doctype/sales_invoice_item/sales_invoice_item.txt
index 057f166..07cdc54 100644
--- a/accounts/doctype/sales_invoice_item/sales_invoice_item.txt
+++ b/accounts/doctype/sales_invoice_item/sales_invoice_item.txt
@@ -2,7 +2,7 @@
{
"creation": "2013-06-04 11:02:19",
"docstatus": 0,
- "modified": "2013-07-25 16:32:10",
+ "modified": "2013-08-29 16:58:56",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -417,17 +417,6 @@
"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,
"doctype": "DocField",
"fieldname": "page_break",
diff --git a/accounts/general_ledger.py b/accounts/general_ledger.py
index 876a581..acb1694 100644
--- a/accounts/general_ledger.py
+++ b/accounts/general_ledger.py
@@ -5,8 +5,12 @@
import webnotes
from webnotes.utils import flt, cstr, now
from webnotes.model.doc import Document
+from webnotes import msgprint, _
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,
update_outstanding='Yes'):
if gl_map:
@@ -47,8 +51,8 @@
merged_gl_map = filter(lambda x: flt(x.debit)!=0 or flt(x.credit)!=0, merged_gl_map)
return merged_gl_map
-def check_if_in_list(gle, gl_mqp):
- for e in gl_mqp:
+def check_if_in_list(gle, gl_map):
+ for e in gl_map:
if e.account == gle.account and \
cstr(e.get('against_voucher'))==cstr(gle.get('against_voucher')) \
and cstr(e.get('against_voucher_type')) == \
@@ -57,11 +61,14 @@
return e
def save_entries(gl_map, adv_adj, update_outstanding):
+ validate_account_for_auto_accounting_for_stock(gl_map)
+
total_debit = total_credit = 0.0
for entry in gl_map:
make_entry(entry, adv_adj, update_outstanding)
# check against budget
validate_expense_against_budget(entry)
+
# update total debit / credit
total_debit += flt(entry.debit)
@@ -79,8 +86,20 @@
def validate_total_debit_credit(total_debit, total_credit):
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))
+
+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,
adv_adj=False, update_outstanding="Yes"):
diff --git a/accounts/utils.py b/accounts/utils.py
index e88804a..2e28254 100644
--- a/accounts/utils.py
+++ b/accounts/utils.py
@@ -246,79 +246,6 @@
_("' in Company: ") + company), raise_exception=True)
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():
vouchers = webnotes.conn.sql("""select voucher_type, voucher_no,
@@ -335,14 +262,6 @@
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),
(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):
from stock.utils import get_stock_balance_on
diff --git a/controllers/selling_controller.py b/controllers/selling_controller.py
index 2cec4ea..4fa97fc 100644
--- a/controllers/selling_controller.py
+++ b/controllers/selling_controller.py
@@ -83,29 +83,6 @@
if self.meta.get_field("in_words_export"):
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)
-
- 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):
self.other_fname = "other_charges"
diff --git a/patches/march_2013/p03_update_buying_amount.py b/patches/march_2013/p03_update_buying_amount.py
deleted file mode 100644
index ddb52e0..0000000
--- a/patches/march_2013/p03_update_buying_amount.py
+++ /dev/null
@@ -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
\ No newline at end of file
diff --git a/stock/doctype/delivery_note/delivery_note.py b/stock/doctype/delivery_note/delivery_note.py
index b07ba5a..b0b2e5d 100644
--- a/stock/doctype/delivery_note/delivery_note.py
+++ b/stock/doctype/delivery_note/delivery_note.py
@@ -186,7 +186,6 @@
self.credit_limit()
- self.set_buying_amount()
self.make_gl_entries()
# set DN status
diff --git a/stock/doctype/delivery_note_item/delivery_note_item.txt b/stock/doctype/delivery_note_item/delivery_note_item.txt
index 83b8f75..b74c33a 100644
--- a/stock/doctype/delivery_note_item/delivery_note_item.txt
+++ b/stock/doctype/delivery_note_item/delivery_note_item.txt
@@ -2,7 +2,7 @@
{
"creation": "2013-04-22 13:15:44",
"docstatus": 0,
- "modified": "2013-08-07 14:45:30",
+ "modified": "2013-08-29 16:58:16",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -421,17 +421,6 @@
"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,
"doctype": "DocField",
"fieldname": "page_break",
diff --git a/stock/doctype/landed_cost_wizard/landed_cost_wizard.py b/stock/doctype/landed_cost_wizard/landed_cost_wizard.py
index 0cdad4d..f46c0c2 100644
--- a/stock/doctype/landed_cost_wizard/landed_cost_wizard.py
+++ b/stock/doctype/landed_cost_wizard/landed_cost_wizard.py
@@ -7,10 +7,7 @@
from webnotes.model.doc import addchild
from webnotes.model.bean import getlist
from webnotes.model.code import get_obj
-from webnotes import msgprint
-
-sql = webnotes.conn.sql
-
+from webnotes import msgprint, _
class DocType:
def __init__(self, doc, doclist=[]):
@@ -18,47 +15,66 @@
self.doclist = doclist
self.prwise_cost = {}
+
def check_mandatory(self):
- """ Check mandatory fields """
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:
- 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):
""" 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()
- 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)
- if len(pr)>200:
- msgprint("Please enter date of shorter duration as there are too many purchase receipt, hence it cannot be loaded.", raise_exception=1)
+ pr = webnotes.conn.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)
+ 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:
ch = addchild(self.doc, 'lc_pr_details', 'Landed Cost Purchase Receipt',
self.doclist)
- ch.purchase_receipt = i and i['name'] or ''
- 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)
+ ch.purchase_receipt = i.name
def validate_selected_pr(self):
"""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:
- 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):
""" 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):
@@ -74,7 +90,9 @@
self.prwise_cost[pr] = self.prwise_cost.get(pr, 0) + 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
ch = addchild(pr_obj.doc, 'purchase_tax_details', 'Purchase Taxes and Charges')
ch.category = 'Valuation'
@@ -89,7 +107,9 @@
ch.idx = 500 # add at the end
ch.save(1)
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):
@@ -201,9 +221,9 @@
d.save()
if d.serial_no:
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""",
d.name, as_dict=1)
@@ -211,22 +231,9 @@
if res:
update_entries_after(res[0])
-
def update_serial_no(self, sr_no, rate):
""" update valuation rate in serial no"""
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)""" %
- ('%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")
+ ('%s', ', '.join(['%s']*len(sr_no))), tuple([rate] + sr_no))
\ No newline at end of file
diff --git a/stock/doctype/stock_entry/stock_entry.js b/stock/doctype/stock_entry/stock_entry.js
index d8983d5..87f9a9c 100644
--- a/stock/doctype/stock_entry/stock_entry.js
+++ b/stock/doctype/stock_entry/stock_entry.js
@@ -39,9 +39,9 @@
};
if(cint(wn.defaults.get_default("auto_accounting_for_stock"))) {
- this.frm.add_fetch("company", "stock_adjustment_account", "expense_adjustment_account");
-
- this.frm.fields_dict["expense_adjustment_account"].get_query = function() {
+ this.frm.add_fetch("company", "stock_adjustment_account", "expense_account");
+ this.frm.fields_dict.mtn_details.grid.get_field('expense_account').get_query =
+ function() {
return {
filters: {
"company": me.frm.doc.company,
@@ -88,7 +88,7 @@
set_default_account: function() {
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";
if (this.frm.doc.purpose == "Sales Return")
account_for = "stock_in_hand_account";
@@ -102,12 +102,22 @@
"company": this.frm.doc.company
},
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() {
// Clear Production Order record from locals, because it is updated via Stock Entry
if(this.frm.doc.production_order &&
diff --git a/stock/doctype/stock_entry_detail/stock_entry_detail.txt b/stock/doctype/stock_entry_detail/stock_entry_detail.txt
index 051eb7c..b400cdd 100644
--- a/stock/doctype/stock_entry_detail/stock_entry_detail.txt
+++ b/stock/doctype/stock_entry_detail/stock_entry_detail.txt
@@ -2,7 +2,7 @@
{
"creation": "2013-03-29 18:22:12",
"docstatus": 0,
- "modified": "2013-08-28 19:15:55",
+ "modified": "2013-08-28 19:25:38",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -149,7 +149,7 @@
"doctype": "DocField",
"fieldname": "expense_account",
"fieldtype": "Link",
- "label": "Expense/Adjustment Account",
+ "label": "Difference Account",
"options": "Account",
"print_hide": 1
},
diff --git a/stock/doctype/stock_reconciliation/stock_reconciliation.txt b/stock/doctype/stock_reconciliation/stock_reconciliation.txt
index 2891ad2..e5b1b74 100644
--- a/stock/doctype/stock_reconciliation/stock_reconciliation.txt
+++ b/stock/doctype/stock_reconciliation/stock_reconciliation.txt
@@ -2,7 +2,7 @@
{
"creation": "2013-03-28 10:35:31",
"docstatus": 0,
- "modified": "2013-08-07 18:16:18",
+ "modified": "2013-08-29 16:46:33",
"modified_by": "Administrator",
"owner": "Administrator"
},
@@ -102,11 +102,11 @@
"reqd": 1
},
{
- "depends_on": "eval:sys_defaults.auto_inventory_accounting",
+ "depends_on": "eval:sys_defaults.auto_accounting_for_stock",
"doctype": "DocField",
"fieldname": "expense_account",
"fieldtype": "Link",
- "label": "Expense Account",
+ "label": "Difference Account",
"options": "Account"
},
{
diff --git a/stock/doctype/warehouse/warehouse.js b/stock/doctype/warehouse/warehouse.js
index 3451863..34745f5 100644
--- a/stock/doctype/warehouse/warehouse.js
+++ b/stock/doctype/warehouse/warehouse.js
@@ -22,7 +22,6 @@
filters: {
"company": cur_frm.doc.company,
"debit_or_credit": "Debit",
- "is_pl_account": "No",
'group_or_ledger': "Ledger"
}
}
diff --git a/stock/doctype/warehouse/warehouse.py b/stock/doctype/warehouse/warehouse.py
index bed314c..6a532ff 100644
--- a/stock/doctype/warehouse/warehouse.py
+++ b/stock/doctype/warehouse/warehouse.py
@@ -4,7 +4,7 @@
from __future__ import unicode_literals
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 import msgprint
@@ -23,6 +23,21 @@
def validate(self):
if self.doc.email_id and not validate_email_add(self.doc.email_id):
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):
webnotes.conn.auto_commit_on_many_writes = 1
diff --git a/stock/stock_ledger.py b/stock/stock_ledger.py
index a4e8d26..a3af5ad 100644
--- a/stock/stock_ledger.py
+++ b/stock/stock_ledger.py
@@ -82,7 +82,7 @@
valuation_method = get_valuation_method(args["item_code"])
stock_value_difference = 0.0
-
+
for sle in entries_to_fix:
if sle.serial_no or not cint(webnotes.conn.get_default("allow_negative_stock")):
# validate negative stock for serialized items, fifo valuation
@@ -90,7 +90,7 @@
if not validate_negative_stock(qty_after_transaction, sle):
qty_after_transaction += flt(sle.actual_qty)
continue
-
+
if sle.serial_no:
valuation_rate = get_serialized_values(qty_after_transaction, sle, valuation_rate)
elif valuation_method == "Moving Average":
@@ -172,6 +172,7 @@
return webnotes.conn.sql("""select * from `tabStock Ledger Entry`
where item_code = %%(item_code)s
and warehouse = %%(warehouse)s
+ and ifnull(is_cancelled, 'No')='No'
%(conditions)s
order by timestamp(posting_date, posting_time) %(order)s, name %(order)s
%(limit)s %(for_update)s""" % {