Merge branch 'master' of github.com:webnotes/erpnext
diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py
index 906de23..de3ee95 100644
--- a/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/accounts/doctype/sales_invoice/sales_invoice.py
@@ -540,8 +540,7 @@
if not w:
ps = webnotes.conn.sql("select name, warehouse from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % self.doc.company)
if not ps:
- msgprint("To make POS entry, please create POS Setting from Accounts --> POS Setting page and refresh the system.")
- raise Exception
+ msgprint("To make POS entry, please create POS Setting from Accounts --> POS Setting page and refresh the system.", raise_exception=True)
elif not ps[0][1]:
msgprint("Please enter warehouse in POS Setting")
else:
diff --git a/buying/doctype/purchase_common/purchase_common.js b/buying/doctype/purchase_common/purchase_common.js
index 05b7bcb..dacee80 100644
--- a/buying/doctype/purchase_common/purchase_common.js
+++ b/buying/doctype/purchase_common/purchase_common.js
@@ -21,7 +21,7 @@
wn.provide("erpnext.buying");
-erpnext.buying.BuyingController = erpnext.utils.Controller.extend({
+erpnext.buying.BuyingController = wn.ui.form.Controller.extend({
setup: function() {
var me = this;
@@ -68,15 +68,15 @@
callback: function(r) {
if(!r.exc) {
me.price_list_currency();
- if (callback_fn) callback_fn(me.frm.doc, me.frm.doc.doctype,
- me.frm.doc.name);
+ if (typeof callback_fn === "function")
+ callback_fn(me.frm.doc, me.frm.doc.doctype, me.frm.doc.name);
}
}
});
} else {
me.price_list_currency();
- if (callback_fn) callback_fn(me.frm.doc, me.frm.doc.doctype,
- me.frm.doc.name);
+ if (typeof callback_fn === "function")
+ callback_fn(me.frm.doc, me.frm.doc.doctype, me.frm.doc.name);
}
}
},
diff --git a/buying/doctype/purchase_order/purchase_order.py b/buying/doctype/purchase_order/purchase_order.py
index 438442c..218d4bf 100644
--- a/buying/doctype/purchase_order/purchase_order.py
+++ b/buying/doctype/purchase_order/purchase_order.py
@@ -132,6 +132,10 @@
for d in getlist(self.doclist, 'po_details'):
#1. Check if is_stock_item == 'Yes'
if webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == "Yes":
+ # this happens when item is changed from non-stock to stock item
+ if not d.warehouse:
+ continue
+
ind_qty, po_qty = 0, flt(d.qty) * flt(d.conversion_factor)
if is_stopped:
po_qty = flt(d.qty) > flt(d.received_qty) and \
diff --git a/hr/doctype/employee/employee.py b/hr/doctype/employee/employee.py
index 2bd7998..d98c8a7 100644
--- a/hr/doctype/employee/employee.py
+++ b/hr/doctype/employee/employee.py
@@ -17,7 +17,7 @@
from __future__ import unicode_literals
import webnotes
-from webnotes.utils import getdate, validate_email_add
+from webnotes.utils import getdate, validate_email_add, cstr
from webnotes.model.doc import make_autoname
from webnotes import msgprint, _
@@ -104,7 +104,7 @@
fname, fid = file_args.split(",")
if self.doc.image == fname:
new_file_args = fname + "," + fid
- file_list = profile_wrapper.doc.file_list.split("\n")
+ file_list = cstr(profile_wrapper.doc.file_list).split("\n")
if new_file_args not in file_list:
file_list += [new_file_args]
profile_wrapper.doc.file_list = "\n".join(file_list)
diff --git a/hr/doctype/upload_attendance/upload_attendance.js b/hr/doctype/upload_attendance/upload_attendance.js
index 008e1cd..0c1d7b2 100644
--- a/hr/doctype/upload_attendance/upload_attendance.js
+++ b/hr/doctype/upload_attendance/upload_attendance.js
@@ -18,7 +18,7 @@
wn.require("public/app/js/utils.js");
wn.provide("erpnext.hr");
-erpnext.hr.AttendanceControlPanel = erpnext.utils.Controller.extend({
+erpnext.hr.AttendanceControlPanel = wn.ui.form.Controller.extend({
onload: function() {
this.frm.set_value("att_fr_date", get_today());
this.frm.set_value("att_to_date", get_today());
diff --git a/patches/march_2013/p03_rename_blog_to_blog_post.py b/patches/march_2013/p03_rename_blog_to_blog_post.py
index 7520f9c..69902f34 100644
--- a/patches/march_2013/p03_rename_blog_to_blog_post.py
+++ b/patches/march_2013/p03_rename_blog_to_blog_post.py
@@ -6,4 +6,4 @@
webnotes.reload_doc('website', 'doctype', 'blog_post')
webnotes.conn.sql('''update tabBlogger set posts=(select count(*)
from `tabBlog Post` where ifnull(blogger,"")=tabBlogger.name)''')
- webnotes.conn.sql("""update `tabBlog Post` set published_on=creation""")
+ webnotes.conn.sql("""update `tabBlog Post` set published_on=date(creation)""")
diff --git a/projects/doctype/task/task.js b/projects/doctype/task/task.js
index 472ca6b..8493920 100644
--- a/projects/doctype/task/task.js
+++ b/projects/doctype/task/task.js
@@ -18,7 +18,7 @@
cur_frm.add_fetch("project", "company", "company");
-erpnext.projects.Task = erpnext.utils.Controller.extend({
+erpnext.projects.Task = wn.ui.form.Controller.extend({
setup: function() {
this.frm.fields_dict.project.get_query = function() {
return "select name from `tabProject` \
@@ -29,7 +29,8 @@
project: function() {
if(this.frm.doc.project) {
- get_server_fields('get_project_details', '','', doc, cdt, cdn, 1);
+ get_server_fields('get_project_details', '','', this.frm.doc, this.frm.doc.doctype,
+ this.frm.doc.name, 1);
}
},
diff --git a/public/js/controllers/stock_controller.js b/public/js/controllers/stock_controller.js
index d3511e1..15d34e0 100644
--- a/public/js/controllers/stock_controller.js
+++ b/public/js/controllers/stock_controller.js
@@ -16,7 +16,7 @@
wn.provide("erpnext.stock");
-erpnext.stock.StockController = erpnext.utils.Controller.extend({
+erpnext.stock.StockController = wn.ui.form.Controller.extend({
show_stock_ledger: function() {
var me = this;
this.frm.add_custom_button("Show Stock Ledger", function() {
diff --git a/public/js/utils.js b/public/js/utils.js
index 0f78705..4df9555 100644
--- a/public/js/utils.js
+++ b/public/js/utils.js
@@ -23,35 +23,4 @@
return wn.model.get(":Company", company).default_currency || wn.boot.sysdefaults.currency;
else
return wn.boot.sysdefaults.currency;
-}
-
-// TODO
-erpnext.utils.Controller = Class.extend({
- init: function(opts) {
- $.extend(this, opts);
- this.setup && this.setup();
- },
-
- onload_post_render: function() {
- if(this.frm.doc.__islocal) {
- this.setup_defaults();
- }
- },
-
- setup_defaults: function() {
- var me = this;
-
- var defaults = {
- posting_date: wn.datetime.get_today(),
- posting_time: wn.datetime.now_time()
- }
-
- $.each(defaults, function(k, v) {
- if(!me.frm.doc[k]) me.frm.set_value(k, v);
- });
- },
-
- refresh: function() {
- erpnext.hide_naming_series();
- }
-});
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/selling/doctype/sales_order/sales_order.py b/selling/doctype/sales_order/sales_order.py
index 8205afb..5009c4e 100644
--- a/selling/doctype/sales_order/sales_order.py
+++ b/selling/doctype/sales_order/sales_order.py
@@ -156,9 +156,13 @@
f = [d.item_code, d.description]
#check item is stock item
- st_itm = sql("select is_stock_item from `tabItem` where name = '%s'"%d.item_code)
+ st_itm = sql("select is_stock_item from `tabItem` where name = %s", d.item_code)
if st_itm and st_itm[0][0] == 'Yes':
+ if not d.reserved_warehouse:
+ msgprint("""Please enter Reserved Warehouse for item %s
+ as it is stock Item""" % d.item_code, raise_exception=1)
+
if e in check_list:
msgprint("Item %s has been entered twice." % d.item_code)
else:
@@ -333,10 +337,6 @@
def update_stock_ledger(self, update_stock, is_stopped = 0):
for d in self.get_item_list(is_stopped):
if webnotes.conn.get_value("Item", d['item_code'], "is_stock_item") == "Yes":
- if not d['reserved_warehouse']:
- msgprint("""Please enter Reserved Warehouse for item %s
- as it is stock Item""" % d['item_code'], raise_exception=1)
-
args = {
"item_code": d['item_code'],
"reserved_qty": flt(update_stock) * flt(d['reserved_qty']),
diff --git a/selling/doctype/sales_order/test_sales_order.py b/selling/doctype/sales_order/test_sales_order.py
index 5d820fe..40a10b4 100644
--- a/selling/doctype/sales_order/test_sales_order.py
+++ b/selling/doctype/sales_order/test_sales_order.py
@@ -65,7 +65,7 @@
# submit dn
dn = self.create_dn_against_so(so)
- self.check_reserved_qty(so.doclist[1].item_code, so.doclist[1].reserved_warehouse, 6.0)
+ self.check_reserved_qty(so.doclist[1].item_code, so.doclist[1].reserved_warehouse, 5.0)
# stop so
so.load_from_db()
@@ -75,7 +75,7 @@
# unstop so
so.load_from_db()
so.obj.unstop_sales_order()
- self.check_reserved_qty(so.doclist[1].item_code, so.doclist[1].reserved_warehouse, 6.0)
+ self.check_reserved_qty(so.doclist[1].item_code, so.doclist[1].reserved_warehouse, 5.0)
# cancel dn
dn.cancel()
@@ -151,9 +151,9 @@
dn = self.create_dn_against_so(so)
self.check_reserved_qty(sbom_test_records[0][1]["item_code"],
- so.doclist[1].reserved_warehouse, 30.0)
+ so.doclist[1].reserved_warehouse, 25.0)
self.check_reserved_qty(sbom_test_records[0][2]["item_code"],
- so.doclist[1].reserved_warehouse, 12.0)
+ so.doclist[1].reserved_warehouse, 10.0)
# stop so
so.load_from_db()
@@ -168,9 +168,9 @@
so.load_from_db()
so.obj.unstop_sales_order()
self.check_reserved_qty(sbom_test_records[0][1]["item_code"],
- so.doclist[1].reserved_warehouse, 30.0)
+ so.doclist[1].reserved_warehouse, 25.0)
self.check_reserved_qty(sbom_test_records[0][2]["item_code"],
- so.doclist[1].reserved_warehouse, 12.0)
+ so.doclist[1].reserved_warehouse, 10.0)
# cancel dn
dn.cancel()
@@ -234,8 +234,8 @@
"price_list_name": "_Test Price List",
"territory": "_Test Territory",
"transaction_date": "2013-02-21",
- "grand_total": 500.0,
- "grand_total_export": 500.0,
+ "grand_total": 1000.0,
+ "grand_total_export": 1000.0,
},
{
"description": "CPU",
@@ -244,9 +244,9 @@
"item_name": "CPU",
"parentfield": "sales_order_details",
"qty": 10.0,
- "basic_rate": 50.0,
- "export_rate": 50.0,
- "amount": 500.0,
+ "basic_rate": 100.0,
+ "export_rate": 100.0,
+ "amount": 1000.0,
"reserved_warehouse": "_Test Warehouse",
}
],
diff --git a/stock/doctype/delivery_note/delivery_note.py b/stock/doctype/delivery_note/delivery_note.py
index 3d799c4..229ec40 100644
--- a/stock/doctype/delivery_note/delivery_note.py
+++ b/stock/doctype/delivery_note/delivery_note.py
@@ -156,7 +156,7 @@
if not self.doc.billing_status: self.doc.billing_status = 'Not Billed'
if not self.doc.installation_status: self.doc.installation_status = 'Not Installed'
-
+
def validate_mandatory(self):
if self.doc.amended_from and not self.doc.amendment_date:
msgprint("Please Enter Amendment Date")
@@ -338,10 +338,10 @@
self.values = []
for d in self.get_item_list():
if webnotes.conn.get_value("Item", d['item_code'], "is_stock_item") == "Yes":
- if not d['warehouse']:
- msgprint("Please enter Warehouse for item %s as it is stock item"
- % d['item_code'], raise_exception=1)
-
+ # this happens when item is changed from non-stock to stock item
+ if not d["warehouse"]:
+ continue
+
if d['reserved_qty'] < 0 :
# Reduce reserved qty from reserved warehouse mentioned in so
args = {
@@ -407,6 +407,15 @@
webnotes.conn.set_value("Delivery Note Item", item.name, "buying_amount",
item.buying_amount)
+ self.validate_warehouse()
+
+ def validate_warehouse(self):
+ for d in self.get_item_list():
+ if webnotes.conn.get_value("Item", d['item_code'], "is_stock_item") == "Yes":
+ if not d['warehouse']:
+ msgprint("Please enter Warehouse for item %s as it is stock item"
+ % d['item_code'], raise_exception=1)
+
def make_gl_entries(self):
if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
return
@@ -440,4 +449,4 @@
def get_total_buying_amount(self):
total_buying_amount = sum([item.buying_amount for item in
self.doclist.get({"parentfield": "delivery_note_details"})])
- return total_buying_amount
\ No newline at end of file
+ return total_buying_amount
diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py
index 334af298..74bf3f3 100644
--- a/stock/doctype/item/item.py
+++ b/stock/doctype/item/item.py
@@ -20,15 +20,12 @@
from webnotes.utils import cstr, flt
from webnotes.model.doc import addchild
from webnotes.model.bean import getlist
-from webnotes import msgprint
+from webnotes import msgprint, _
sql = webnotes.conn.sql
-class DocType:
- def __init__(self, doc, doclist=[]):
- self.doc = doc
- self.doclist = doclist
-
+from webnotes.model.controller import DocListController
+class DocType(DocListController):
def get_tax_rate(self, tax_type):
rate = sql("select tax_rate from tabAccount where name = %s", tax_type)
ret = {
@@ -196,6 +193,8 @@
if self.doc.name:
self.old_page_name = webnotes.conn.get_value('Item', self.doc.name, 'page_name')
+
+ self.validate_is_stock_item()
def check_non_asset_warehouse(self):
if self.doc.is_asset_item == "Yes":
@@ -215,6 +214,15 @@
'description' : file and file[0]['description'] or ''
}
return ret
+
+ def validate_is_stock_item(self):
+ if not self.doc.fields.get("__islocal"):
+ if webnotes.conn.get_value("Item", self.doc.name, "is_stock_item")=="Yes" and \
+ ((not self.doc.is_stock_item) or self.doc.is_stock_item == "No"):
+ if self.check_if_sle_exists() == "exists":
+ webnotes.msgprint(self.meta.get_label("is_stock_item") + ": "
+ + _("""Cannot change to Yes. Reason: Stock Ledger Entries exist for""")
+ + """ "%s" """ % self.doc.name, raise_exception=True)
def check_if_sle_exists(self):
sle = sql("select name from `tabStock Ledger Entry` where item_code = %s and ifnull(is_cancelled, 'No') = 'No'", self.doc.name)
diff --git a/stock/doctype/purchase_receipt/purchase_receipt.py b/stock/doctype/purchase_receipt/purchase_receipt.py
index 12da0a6..cce1493 100644
--- a/stock/doctype/purchase_receipt/purchase_receipt.py
+++ b/stock/doctype/purchase_receipt/purchase_receipt.py
@@ -125,7 +125,7 @@
self.update_raw_materials_supplied("pr_raw_material_details")
self.update_valuation_rate("purchase_receipt_details")
-
+
def on_update(self):
if self.doc.rejected_warehouse:
for d in getlist(self.doclist,'purchase_receipt_details'):
@@ -146,6 +146,9 @@
self.values = []
for d in getlist(self.doclist, 'purchase_receipt_details'):
if webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == "Yes":
+ if not d.warehouse:
+ continue
+
ord_qty = 0
pr_qty = flt(d.qty) * flt(d.conversion_factor)
diff --git a/stock/doctype/stock_entry/stock_entry.js b/stock/doctype/stock_entry/stock_entry.js
index 55a86a3..ba1f648 100644
--- a/stock/doctype/stock_entry/stock_entry.js
+++ b/stock/doctype/stock_entry/stock_entry.js
@@ -19,7 +19,6 @@
erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
onload_post_render: function() {
- this._super();
if(this.frm.doc.__islocal && (this.frm.doc.production_order || this.frm.doc.bom_no)
&& !getchildren('Stock Entry Detail', this.frm.doc.name, 'mtn_details').length) {
// if production order / bom is mentioned, get items
@@ -28,7 +27,7 @@
},
refresh: function() {
- this._super();
+ erpnext.hide_naming_series();
this.toggle_related_fields(this.frm.doc);
this.toggle_enable_bom();
if (this.frm.doc.docstatus==1) {
diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py
index 278c283..74b71d9 100644
--- a/stock/doctype/stock_entry/stock_entry.py
+++ b/stock/doctype/stock_entry/stock_entry.py
@@ -29,9 +29,9 @@
sql = webnotes.conn.sql
-from utilities.transaction_base import TransactionBase
+from controllers.accounts_controller import AccountsController
-class DocType(TransactionBase):
+class DocType(AccountsController):
def __init__(self, doc, doclist=[]):
self.doc = doc
self.doclist = doclist
@@ -44,12 +44,14 @@
pro_obj = self.doc.production_order and \
get_obj('Production Order', self.doc.production_order) or None
+ self.validate_item()
self.validate_warehouse(pro_obj)
self.validate_production_order(pro_obj)
self.get_stock_and_rate()
self.validate_incoming_rate()
self.validate_bom()
self.validate_finished_goods()
+
self.validate_return_reference_doc()
self.validate_with_material_request()
@@ -78,6 +80,12 @@
sl_obj.scrub_serial_nos(self)
sl_obj.validate_serial_no(self, 'mtn_details')
+ def validate_item(self):
+ for item in self.doclist.get({"parentfield": "mtn_details"}):
+ if item.item_code not in self.stock_items:
+ msgprint(_("""Only Stock Items are allowed for Stock Entry"""),
+ raise_exception=True)
+
def validate_warehouse(self, pro_obj):
"""perform various (sometimes conditional) validations on warehouse"""
diff --git a/stock/utils.py b/stock/utils.py
index bc6054f..20d08ea 100644
--- a/stock/utils.py
+++ b/stock/utils.py
@@ -181,11 +181,13 @@
def _get_buying_amount(voucher_type, voucher_no, item_row, item_code, warehouse, qty,
stock_ledger_entries):
for i, sle in enumerate(stock_ledger_entries):
- if sle.voucher_type == voucher_type and sle.voucher_no == voucher_no:
+ if sle.voucher_type == voucher_type and sle.voucher_no == voucher_no and \
+ len(stock_ledger_entries) > i+1:
if (sle.voucher_detail_no == item_row) or \
(sle.item_code == item_code and sle.warehouse == warehouse and \
abs(flt(sle.qty)) == qty):
- buying_amount = flt(stock_ledger_entries[i+1].stock_value) - flt(sle.stock_value)
+ buying_amount = flt(stock_ledger_entries[i+1].stock_value) - \
+ flt(sle.stock_value)
return buying_amount