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

This commit is contained in:
Rushabh Mehta 2013-03-12 14:29:00 +05:30
commit d6cc122a75
17 changed files with 83 additions and 81 deletions

View File

@ -540,8 +540,7 @@ class DocType(SellingController):
if not w: if not w:
ps = webnotes.conn.sql("select name, warehouse from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % self.doc.company) ps = webnotes.conn.sql("select name, warehouse from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % self.doc.company)
if not ps: if not ps:
msgprint("To make POS entry, please create POS Setting from Accounts --> POS Setting page and refresh the system.") msgprint("To make POS entry, please create POS Setting from Accounts --> POS Setting page and refresh the system.", raise_exception=True)
raise Exception
elif not ps[0][1]: elif not ps[0][1]:
msgprint("Please enter warehouse in POS Setting") msgprint("Please enter warehouse in POS Setting")
else: else:

View File

@ -21,7 +21,7 @@
wn.provide("erpnext.buying"); wn.provide("erpnext.buying");
erpnext.buying.BuyingController = erpnext.utils.Controller.extend({ erpnext.buying.BuyingController = wn.ui.form.Controller.extend({
setup: function() { setup: function() {
var me = this; var me = this;
@ -68,15 +68,15 @@ erpnext.buying.BuyingController = erpnext.utils.Controller.extend({
callback: function(r) { callback: function(r) {
if(!r.exc) { if(!r.exc) {
me.price_list_currency(); me.price_list_currency();
if (callback_fn) callback_fn(me.frm.doc, me.frm.doc.doctype, if (typeof callback_fn === "function")
me.frm.doc.name); callback_fn(me.frm.doc, me.frm.doc.doctype, me.frm.doc.name);
} }
} }
}); });
} else { } else {
me.price_list_currency(); me.price_list_currency();
if (callback_fn) callback_fn(me.frm.doc, me.frm.doc.doctype, if (typeof callback_fn === "function")
me.frm.doc.name); callback_fn(me.frm.doc, me.frm.doc.doctype, me.frm.doc.name);
} }
} }
}, },

View File

@ -132,6 +132,10 @@ class DocType(BuyingController):
for d in getlist(self.doclist, 'po_details'): for d in getlist(self.doclist, 'po_details'):
#1. Check if is_stock_item == 'Yes' #1. Check if is_stock_item == 'Yes'
if webnotes.conn.get_value("Item", d.item_code, "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) ind_qty, po_qty = 0, flt(d.qty) * flt(d.conversion_factor)
if is_stopped: if is_stopped:
po_qty = flt(d.qty) > flt(d.received_qty) and \ po_qty = flt(d.qty) > flt(d.received_qty) and \

View File

@ -17,7 +17,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import webnotes 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.model.doc import make_autoname
from webnotes import msgprint, _ from webnotes import msgprint, _
@ -104,7 +104,7 @@ class DocType:
fname, fid = file_args.split(",") fname, fid = file_args.split(",")
if self.doc.image == fname: if self.doc.image == fname:
new_file_args = fname + "," + fid 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: if new_file_args not in file_list:
file_list += [new_file_args] file_list += [new_file_args]
profile_wrapper.doc.file_list = "\n".join(file_list) profile_wrapper.doc.file_list = "\n".join(file_list)

View File

@ -18,7 +18,7 @@
wn.require("public/app/js/utils.js"); wn.require("public/app/js/utils.js");
wn.provide("erpnext.hr"); wn.provide("erpnext.hr");
erpnext.hr.AttendanceControlPanel = erpnext.utils.Controller.extend({ erpnext.hr.AttendanceControlPanel = wn.ui.form.Controller.extend({
onload: function() { onload: function() {
this.frm.set_value("att_fr_date", get_today()); this.frm.set_value("att_fr_date", get_today());
this.frm.set_value("att_to_date", get_today()); this.frm.set_value("att_to_date", get_today());

View File

@ -6,4 +6,4 @@ def execute():
webnotes.reload_doc('website', 'doctype', 'blog_post') webnotes.reload_doc('website', 'doctype', 'blog_post')
webnotes.conn.sql('''update tabBlogger set posts=(select count(*) webnotes.conn.sql('''update tabBlogger set posts=(select count(*)
from `tabBlog Post` where ifnull(blogger,"")=tabBlogger.name)''') 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)""")

View File

@ -18,7 +18,7 @@ wn.provide("erpnext.projects");
cur_frm.add_fetch("project", "company", "company"); cur_frm.add_fetch("project", "company", "company");
erpnext.projects.Task = erpnext.utils.Controller.extend({ erpnext.projects.Task = wn.ui.form.Controller.extend({
setup: function() { setup: function() {
this.frm.fields_dict.project.get_query = function() { this.frm.fields_dict.project.get_query = function() {
return "select name from `tabProject` \ return "select name from `tabProject` \
@ -29,7 +29,8 @@ erpnext.projects.Task = erpnext.utils.Controller.extend({
project: function() { project: function() {
if(this.frm.doc.project) { 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);
} }
}, },

View File

@ -16,7 +16,7 @@
wn.provide("erpnext.stock"); wn.provide("erpnext.stock");
erpnext.stock.StockController = erpnext.utils.Controller.extend({ erpnext.stock.StockController = wn.ui.form.Controller.extend({
show_stock_ledger: function() { show_stock_ledger: function() {
var me = this; var me = this;
this.frm.add_custom_button("Show Stock Ledger", function() { this.frm.add_custom_button("Show Stock Ledger", function() {

View File

@ -24,34 +24,3 @@ erpnext.get_currency = function(company) {
else else
return wn.boot.sysdefaults.currency; 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();
}
});

View File

@ -156,9 +156,13 @@ class DocType(SellingController):
f = [d.item_code, d.description] f = [d.item_code, d.description]
#check item is stock item #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 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: if e in check_list:
msgprint("Item %s has been entered twice." % d.item_code) msgprint("Item %s has been entered twice." % d.item_code)
else: else:
@ -333,10 +337,6 @@ class DocType(SellingController):
def update_stock_ledger(self, update_stock, is_stopped = 0): def update_stock_ledger(self, update_stock, is_stopped = 0):
for d in self.get_item_list(is_stopped): for d in self.get_item_list(is_stopped):
if webnotes.conn.get_value("Item", d['item_code'], "is_stock_item") == "Yes": 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 = { args = {
"item_code": d['item_code'], "item_code": d['item_code'],
"reserved_qty": flt(update_stock) * flt(d['reserved_qty']), "reserved_qty": flt(update_stock) * flt(d['reserved_qty']),

View File

@ -65,7 +65,7 @@ class TestSalesOrder(unittest.TestCase):
# submit dn # submit dn
dn = self.create_dn_against_so(so) 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 # stop so
so.load_from_db() so.load_from_db()
@ -75,7 +75,7 @@ class TestSalesOrder(unittest.TestCase):
# unstop so # unstop so
so.load_from_db() so.load_from_db()
so.obj.unstop_sales_order() 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 # cancel dn
dn.cancel() dn.cancel()
@ -151,9 +151,9 @@ class TestSalesOrder(unittest.TestCase):
dn = self.create_dn_against_so(so) dn = self.create_dn_against_so(so)
self.check_reserved_qty(sbom_test_records[0][1]["item_code"], 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"], 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 # stop so
so.load_from_db() so.load_from_db()
@ -168,9 +168,9 @@ class TestSalesOrder(unittest.TestCase):
so.load_from_db() so.load_from_db()
so.obj.unstop_sales_order() so.obj.unstop_sales_order()
self.check_reserved_qty(sbom_test_records[0][1]["item_code"], 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"], 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 # cancel dn
dn.cancel() dn.cancel()
@ -234,8 +234,8 @@ test_records = [
"price_list_name": "_Test Price List", "price_list_name": "_Test Price List",
"territory": "_Test Territory", "territory": "_Test Territory",
"transaction_date": "2013-02-21", "transaction_date": "2013-02-21",
"grand_total": 500.0, "grand_total": 1000.0,
"grand_total_export": 500.0, "grand_total_export": 1000.0,
}, },
{ {
"description": "CPU", "description": "CPU",
@ -244,9 +244,9 @@ test_records = [
"item_name": "CPU", "item_name": "CPU",
"parentfield": "sales_order_details", "parentfield": "sales_order_details",
"qty": 10.0, "qty": 10.0,
"basic_rate": 50.0, "basic_rate": 100.0,
"export_rate": 50.0, "export_rate": 100.0,
"amount": 500.0, "amount": 1000.0,
"reserved_warehouse": "_Test Warehouse", "reserved_warehouse": "_Test Warehouse",
} }
], ],

View File

@ -338,9 +338,9 @@ class DocType(SellingController):
self.values = [] self.values = []
for d in self.get_item_list(): for d in self.get_item_list():
if webnotes.conn.get_value("Item", d['item_code'], "is_stock_item") == "Yes": if webnotes.conn.get_value("Item", d['item_code'], "is_stock_item") == "Yes":
if not d['warehouse']: # this happens when item is changed from non-stock to stock item
msgprint("Please enter Warehouse for item %s as it is stock item" if not d["warehouse"]:
% d['item_code'], raise_exception=1) continue
if d['reserved_qty'] < 0 : if d['reserved_qty'] < 0 :
# Reduce reserved qty from reserved warehouse mentioned in so # Reduce reserved qty from reserved warehouse mentioned in so
@ -407,6 +407,15 @@ class DocType(SellingController):
webnotes.conn.set_value("Delivery Note Item", item.name, "buying_amount", webnotes.conn.set_value("Delivery Note Item", item.name, "buying_amount",
item.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): def make_gl_entries(self):
if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")): if not cint(webnotes.defaults.get_global_default("auto_inventory_accounting")):
return return

View File

@ -20,15 +20,12 @@ import webnotes
from webnotes.utils import cstr, flt from webnotes.utils import 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 import msgprint from webnotes import msgprint, _
sql = webnotes.conn.sql sql = webnotes.conn.sql
class DocType: from webnotes.model.controller import DocListController
def __init__(self, doc, doclist=[]): class DocType(DocListController):
self.doc = doc
self.doclist = doclist
def get_tax_rate(self, tax_type): def get_tax_rate(self, tax_type):
rate = sql("select tax_rate from tabAccount where name = %s", tax_type) rate = sql("select tax_rate from tabAccount where name = %s", tax_type)
ret = { ret = {
@ -197,6 +194,8 @@ class DocType:
if self.doc.name: if self.doc.name:
self.old_page_name = webnotes.conn.get_value('Item', self.doc.name, 'page_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): def check_non_asset_warehouse(self):
if self.doc.is_asset_item == "Yes": if self.doc.is_asset_item == "Yes":
existing_qty = sql("select t1.warehouse, t1.actual_qty from tabBin t1, tabWarehouse t2 where t1.item_code=%s and (t2.warehouse_type!='Fixed Asset' or t2.warehouse_type is null) and t1.warehouse=t2.name and t1.actual_qty > 0", self.doc.name) existing_qty = sql("select t1.warehouse, t1.actual_qty from tabBin t1, tabWarehouse t2 where t1.item_code=%s and (t2.warehouse_type!='Fixed Asset' or t2.warehouse_type is null) and t1.warehouse=t2.name and t1.actual_qty > 0", self.doc.name)
@ -216,6 +215,15 @@ class DocType:
} }
return ret 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): 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) sle = sql("select name from `tabStock Ledger Entry` where item_code = %s and ifnull(is_cancelled, 'No') = 'No'", self.doc.name)
return sle and 'exists' or 'not exists' return sle and 'exists' or 'not exists'

View File

@ -146,6 +146,9 @@ class DocType(BuyingController):
self.values = [] self.values = []
for d in getlist(self.doclist, 'purchase_receipt_details'): for d in getlist(self.doclist, 'purchase_receipt_details'):
if webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == "Yes": if webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == "Yes":
if not d.warehouse:
continue
ord_qty = 0 ord_qty = 0
pr_qty = flt(d.qty) * flt(d.conversion_factor) pr_qty = flt(d.qty) * flt(d.conversion_factor)

View File

@ -19,7 +19,6 @@ wn.provide("erpnext.stock");
erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
onload_post_render: function() { onload_post_render: function() {
this._super();
if(this.frm.doc.__islocal && (this.frm.doc.production_order || this.frm.doc.bom_no) 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) { && !getchildren('Stock Entry Detail', this.frm.doc.name, 'mtn_details').length) {
// if production order / bom is mentioned, get items // if production order / bom is mentioned, get items
@ -28,7 +27,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
}, },
refresh: function() { refresh: function() {
this._super(); erpnext.hide_naming_series();
this.toggle_related_fields(this.frm.doc); this.toggle_related_fields(this.frm.doc);
this.toggle_enable_bom(); this.toggle_enable_bom();
if (this.frm.doc.docstatus==1) { if (this.frm.doc.docstatus==1) {

View File

@ -29,9 +29,9 @@ import json
sql = webnotes.conn.sql 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=[]): def __init__(self, doc, doclist=[]):
self.doc = doc self.doc = doc
self.doclist = doclist self.doclist = doclist
@ -44,12 +44,14 @@ class DocType(TransactionBase):
pro_obj = self.doc.production_order and \ pro_obj = self.doc.production_order and \
get_obj('Production Order', self.doc.production_order) or None get_obj('Production Order', self.doc.production_order) or None
self.validate_item()
self.validate_warehouse(pro_obj) self.validate_warehouse(pro_obj)
self.validate_production_order(pro_obj) self.validate_production_order(pro_obj)
self.get_stock_and_rate() self.get_stock_and_rate()
self.validate_incoming_rate() self.validate_incoming_rate()
self.validate_bom() self.validate_bom()
self.validate_finished_goods() self.validate_finished_goods()
self.validate_return_reference_doc() self.validate_return_reference_doc()
self.validate_with_material_request() self.validate_with_material_request()
@ -78,6 +80,12 @@ class DocType(TransactionBase):
sl_obj.scrub_serial_nos(self) sl_obj.scrub_serial_nos(self)
sl_obj.validate_serial_no(self, 'mtn_details') 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): def validate_warehouse(self, pro_obj):
"""perform various (sometimes conditional) validations on warehouse""" """perform various (sometimes conditional) validations on warehouse"""

View File

@ -181,11 +181,13 @@ def get_buying_amount(item_code, warehouse, qty, voucher_type, voucher_no, vouch
def _get_buying_amount(voucher_type, voucher_no, item_row, item_code, warehouse, qty, def _get_buying_amount(voucher_type, voucher_no, item_row, item_code, warehouse, qty,
stock_ledger_entries): stock_ledger_entries):
for i, sle in enumerate(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 \ if (sle.voucher_detail_no == item_row) or \
(sle.item_code == item_code and sle.warehouse == warehouse and \ (sle.item_code == item_code and sle.warehouse == warehouse and \
abs(flt(sle.qty)) == qty): 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 return buying_amount