mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-29 09:54:47 +00:00
moved directory structure
This commit is contained in:
1
stock/doctype/item/__init__.py
Normal file
1
stock/doctype/item/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
144
stock/doctype/item/item.js
Normal file
144
stock/doctype/item/item.js
Normal file
@@ -0,0 +1,144 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
cur_frm.cscript.refresh = function(doc) {
|
||||
// make sensitive fields(has_serial_no, is_stock_item, valuation_method)
|
||||
// read only if any stock ledger entry exists
|
||||
|
||||
if (!doc.__islocal) {
|
||||
set_field_permlevel("item_code", 1);
|
||||
}
|
||||
|
||||
if ((!doc.__islocal) && (doc.is_stock_item == 'Yes')) {
|
||||
var callback = function(r, rt) {
|
||||
if (r.message == 'exists') permlevel = 1;
|
||||
else permlevel = 0;
|
||||
|
||||
set_field_permlevel('has_serial_no', permlevel);
|
||||
set_field_permlevel('is_stock_item', permlevel);
|
||||
set_field_permlevel('valuation_method', permlevel);
|
||||
}
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'check_if_sle_exists','',callback);
|
||||
}
|
||||
|
||||
cur_frm.cscript.hide_website_fields(doc);
|
||||
}
|
||||
|
||||
cur_frm.cscript.hide_website_fields = function(doc) {
|
||||
var website_fields_list = ['page_name', 'website_image', 'web_short_description',
|
||||
'web_long_description'];
|
||||
if (doc && cint(doc.show_in_website)) {
|
||||
unhide_field(website_fields_list);
|
||||
} else {
|
||||
hide_field(website_fields_list);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.show_in_website = function(doc, dt, dn) {
|
||||
cur_frm.cscript.hide_website_fields(doc);
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['default_bom'].get_query = function(doc) {
|
||||
//var d = locals[this.doctype][this.docname];
|
||||
return 'SELECT DISTINCT `tabBOM`.`name` FROM `tabBOM` WHERE `tabBOM`.`item` = "' + doc.item_code + '" AND `tabBOM`.`is_active` = "No" and `tabBOM`.docstatus != 2 AND `tabBOM`.%(key)s LIKE "%s" ORDER BY `tabBOM`.`name` LIMIT 50'
|
||||
}
|
||||
|
||||
|
||||
// Expense Account
|
||||
// ---------------------------------
|
||||
cur_frm.fields_dict['purchase_account'].get_query = function(doc){
|
||||
return 'SELECT DISTINCT `tabAccount`.`name` FROM `tabAccount` WHERE `tabAccount`.`debit_or_credit`="Debit" AND `tabAccount`.`group_or_ledger`="Ledger" AND `tabAccount`.`docstatus`!=2 AND `tabAccount`.%(key)s LIKE "%s" ORDER BY `tabAccount`.`name` LIMIT 50'
|
||||
}
|
||||
|
||||
// Income Account
|
||||
// --------------------------------
|
||||
cur_frm.fields_dict['default_income_account'].get_query = function(doc) {
|
||||
return 'SELECT DISTINCT `tabAccount`.`name` FROM `tabAccount` WHERE `tabAccount`.`debit_or_credit`="Credit" AND `tabAccount`.`group_or_ledger`="Ledger" AND `tabAccount`.`docstatus`!=2 AND `tabAccount`.`account_type` ="Income Account" AND `tabAccount`.%(key)s LIKE "%s" ORDER BY `tabAccount`.`name` LIMIT 50'
|
||||
}
|
||||
|
||||
|
||||
// Purchase Cost Center
|
||||
// -----------------------------
|
||||
cur_frm.fields_dict['cost_center'].get_query = function(doc) {
|
||||
return 'SELECT `tabCost Center`.`name` FROM `tabCost Center` WHERE `tabCost Center`.%(key)s LIKE "%s" AND `tabCost Center`.`group_or_ledger` = "Ledger" AND `tabCost Center`.`docstatus`!= 2 ORDER BY `tabCost Center`.`name` ASC LIMIT 50'
|
||||
}
|
||||
|
||||
|
||||
// Sales Cost Center
|
||||
// -----------------------------
|
||||
cur_frm.fields_dict['default_sales_cost_center'].get_query = function(doc) {
|
||||
return 'SELECT `tabCost Center`.`name` FROM `tabCost Center` WHERE `tabCost Center`.%(key)s LIKE "%s" AND `tabCost Center`.`group_or_ledger` = "Ledger" AND `tabCost Center`.`docstatus`!= 2 ORDER BY `tabCost Center`.`name` ASC LIMIT 50'
|
||||
}
|
||||
|
||||
|
||||
cur_frm.fields_dict['item_tax'].grid.get_field("tax_type").get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT `tabAccount`.`name` FROM `tabAccount` WHERE `tabAccount`.`account_type` in ("Tax", "Chargeable") and `tabAccount`.`docstatus` != 2 and `tabAccount`.%(key)s LIKE "%s" ORDER BY `tabAccount`.`name` DESC LIMIT 50'
|
||||
}
|
||||
|
||||
cur_frm.cscript.tax_type = function(doc, cdt, cdn){
|
||||
var d = locals[cdt][cdn];
|
||||
get_server_fields('get_tax_rate',d.tax_type,'item_tax',doc, cdt, cdn, 1);
|
||||
}
|
||||
|
||||
|
||||
//get query select item group
|
||||
cur_frm.fields_dict['item_group'].get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT `tabItem Group`.`name`,`tabItem Group`.`parent_item_group` FROM `tabItem Group` WHERE `tabItem Group`.`is_group` = "No" AND `tabItem Group`.`docstatus`!= 2 AND `tabItem Group`.%(key)s LIKE "%s" ORDER BY `tabItem Group`.`name` ASC LIMIT 50'
|
||||
}
|
||||
|
||||
// for description from attachment
|
||||
// takes the first attachment and creates
|
||||
// a table with both image and attachment in HTML
|
||||
// in the "alternate_description" field
|
||||
cur_frm.cscript.add_image = function(doc, dt, dn) {
|
||||
if(!doc.file_list) {
|
||||
msgprint('Please attach a file first!');
|
||||
}
|
||||
|
||||
var f = doc.file_list.split('\n')[0];
|
||||
var fname = f.split(',')[0];
|
||||
var fid = f.split(',')[1];
|
||||
if(!in_list(['jpg','jpeg','gif','png'], fname.split('.')[1].toLowerCase())) {
|
||||
msgprint('File must be of extension jpg, jpeg, gif or png'); return;
|
||||
}
|
||||
|
||||
doc.description_html = repl('<table style="width: 100%; table-layout: fixed;">'+
|
||||
'<tr><td style="width:110px"><img src="%(imgurl)s" width="100px"></td>'+
|
||||
'<td>%(desc)s</td></tr>'+
|
||||
'</table>', {imgurl: wn.urllib.get_file_url(fid), desc:doc.description});
|
||||
|
||||
refresh_field('description_html');
|
||||
}
|
||||
//===================== Quotation to validation - either customer or lead mandatory ====================
|
||||
cur_frm.cscript.weight_to_validate = function(doc,cdt,cdn){
|
||||
|
||||
if((doc.nett_weight || doc.gross_weight) && !doc.weight_uom)
|
||||
{
|
||||
alert('Weight is mentioned,\nPlease mention "Weight UOM" too');
|
||||
validated=0;
|
||||
}
|
||||
}
|
||||
//===================validation function =================================
|
||||
|
||||
cur_frm.cscript.validate = function(doc,cdt,cdn){
|
||||
cur_frm.cscript.weight_to_validate(doc,cdt,cdn);
|
||||
}
|
||||
|
||||
//===========Fill Default Currency in "Item Prices====================
|
||||
cur_frm.fields_dict['ref_rate_details'].grid.onrowadd = function(doc, cdt, cdn){
|
||||
locals[cdt][cdn].ref_currency = sys_defaults.currency;
|
||||
refresh_field('ref_currency',cdn,'ref_rate_details');
|
||||
}
|
||||
240
stock/doctype/item/item.py
Normal file
240
stock/doctype/item/item.py
Normal file
@@ -0,0 +1,240 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class DocType:
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
|
||||
def get_tax_rate(self, tax_type):
|
||||
rate = sql("select tax_rate from tabAccount where name = %s", tax_type)
|
||||
ret = {
|
||||
'tax_rate' : rate and flt(rate[0][0]) or 0
|
||||
}
|
||||
return ret
|
||||
|
||||
def on_update(self):
|
||||
self.update_page_name()
|
||||
|
||||
bin = sql("select stock_uom from `tabBin` where item_code = '%s' " % self.doc.item_code)
|
||||
if bin and cstr(bin[0][0]) != cstr(self.doc.stock_uom):
|
||||
msgprint("Please Update Stock UOM with the help of Stock UOM Replace Utility.")
|
||||
raise Exception
|
||||
check_list = []
|
||||
for d in getlist(self.doclist,'uom_conversion_details'):
|
||||
if not self.doc.stock_uom:
|
||||
msgprint("Please enter Stock UOM first.")
|
||||
raise Exception
|
||||
|
||||
if cstr(d.uom) in check_list:
|
||||
msgprint("UOM %s has been entered more than once in Conversion Factor Details." % cstr(d.uom))
|
||||
raise Exception
|
||||
else:
|
||||
check_list.append(cstr(d.uom))
|
||||
|
||||
if cstr(d.uom) == cstr(self.doc.stock_uom):
|
||||
if flt(d.conversion_factor) != 1:
|
||||
msgprint("Conversion Factor of UOM : %s should be equal to 1. As UOM : %s is Stock UOM of Item: %s." % ( cstr(d.uom), cstr(d.uom), cstr(self.doc.name)))
|
||||
raise Exception
|
||||
# else set uom_exist as true
|
||||
uom_exist='true'
|
||||
elif cstr(d.uom) != cstr(self.doc.stock_uom) and flt(d.conversion_factor) == 1:
|
||||
msgprint("Conversion Factor of UOM : %s should not be equal to 1. As UOM : %s is not Stock UOM of Item: %s." % ( cstr(d.uom), cstr(d.uom), cstr(self.doc.name)))
|
||||
raise Exception
|
||||
|
||||
if not cstr(self.doc.stock_uom) in check_list :
|
||||
child = addchild( self.doc, 'uom_conversion_details', 'UOM Conversion Detail', 1, self.doclist)
|
||||
child.uom = self.doc.stock_uom
|
||||
child.conversion_factor = 1
|
||||
child.save()
|
||||
|
||||
self.clear_web_cache()
|
||||
|
||||
# On delete 1. Delete BIN (if none of the corrosponding transactions present, it gets deleted. if present, rolled back due to exception)
|
||||
def on_trash(self):
|
||||
sql("delete from tabBin where item_code='%s'"%(self.doc.item_code))
|
||||
|
||||
self.delete_web_cache(self.doc.page_name)
|
||||
|
||||
# Check whether Ref Rate is not entered twice for same Price List and Currency
|
||||
def check_ref_rate_detail(self):
|
||||
check_list=[]
|
||||
for d in getlist(self.doclist,'ref_rate_details'):
|
||||
if [cstr(d.price_list_name),cstr(d.ref_currency)] in check_list:
|
||||
msgprint("Ref Rate is entered twice for Price List : '%s' and Currency : '%s'." % (d.price_list_name,d.ref_currency))
|
||||
raise Exception
|
||||
else:
|
||||
check_list.append([cstr(d.price_list_name),cstr(d.ref_currency)])
|
||||
|
||||
# Append all the customer codes and insert into "customer_code" field of item table
|
||||
def fill_customer_code(self):
|
||||
cust_code=[]
|
||||
for d in getlist(self.doclist,'item_customer_details'):
|
||||
cust_code.append(d.ref_code)
|
||||
self.doc.customer_code=','.join(cust_code)
|
||||
|
||||
# Check whether Tax Rate is not entered twice for same Tax Type
|
||||
def check_item_tax(self):
|
||||
check_list=[]
|
||||
for d in getlist(self.doclist,'item_tax'):
|
||||
account_type = sql("select account_type from tabAccount where name = %s",d.tax_type)
|
||||
account_type = account_type and account_type[0][0] or ''
|
||||
if account_type not in ['Tax', 'Chargeable']:
|
||||
msgprint("'%s' is not Tax / Chargeable Account"%(d.tax_type))
|
||||
raise Exception, "Tax Account validation"
|
||||
else:
|
||||
if d.tax_type in check_list:
|
||||
msgprint("Rate is entered twice for Tax : '%s'." % (d.tax_type))
|
||||
raise Exception
|
||||
else:
|
||||
check_list.append(d.tax_type)
|
||||
|
||||
def check_for_active_boms(self, check):
|
||||
if check in ['Is Active', 'Is Purchase Item']:
|
||||
bom_mat = sql("select distinct t1.parent from `tabBOM Item` t1, `tabBOM` t2 where t1.item_code ='%s' and (t1.bom_no = '' or t1.bom_no is NULL) and t2.name = t1.parent and t2.is_active = 'Yes' and t2.docstatus = 1 and t1.docstatus =1 " % self.doc.name )
|
||||
if bom_mat and bom_mat[0][0]:
|
||||
msgprint("%s should be 'Yes'. As Item %s is present in one or many Active BOMs." % (cstr(check), cstr(self.doc.name)))
|
||||
raise Exception
|
||||
if check == 'Is Active' or ( check == 'Is Manufactured Item' and self.doc.is_sub_contracted_item != 'Yes') or (check == 'Is Sub Contracted Item' and self.doc.is_manufactured_item != 'Yes') :
|
||||
bom = sql("select name from `tabBOM` where item = '%s' and is_active ='Yes'" % cstr(self.doc.name))
|
||||
if bom and bom[0][0]:
|
||||
msgprint("%s should be 'Yes'. As Item %s is present in one or many Active BOMs." % (cstr(check), cstr(self.doc.name)))
|
||||
raise Exception
|
||||
|
||||
def validate_barcode(self):
|
||||
if self.doc.barcode:
|
||||
duplicate = sql("select name from tabItem where barcode = %s and name != %s", (self.doc.barcode, self.doc.name))
|
||||
if duplicate:
|
||||
msgprint("Barcode: %s already used in item: %s" % (self.doc.barcode, cstr(duplicate[0][0])), raise_exception = 1)
|
||||
|
||||
def validate(self):
|
||||
fl = {'is_manufactured_item' :'Is Manufactured Item',
|
||||
'is_sub_contracted_item':'Is Sub Contracted Item',
|
||||
'is_purchase_item' :'Is Purchase Item',
|
||||
'is_pro_applicable' :'Is Pro Applicable'}
|
||||
for d in fl:
|
||||
if cstr(self.doc.fields[d]) != 'Yes':
|
||||
self.check_for_active_boms(check = fl[d])
|
||||
self.check_ref_rate_detail()
|
||||
self.fill_customer_code()
|
||||
self.check_item_tax()
|
||||
self.validate_barcode()
|
||||
if not self.doc.min_order_qty:
|
||||
self.doc.min_order_qty = 0
|
||||
self.check_non_asset_warehouse()
|
||||
|
||||
if self.doc.is_pro_applicable and self.doc.is_pro_applicable == 'Yes' and self.doc.is_manufactured_item and self.doc.is_manufactured_item != 'Yes':
|
||||
msgprint("If making Production Order is allowed then, it should also allow to make Bill of Materials. Refer Manufacturing section.")
|
||||
raise Exception
|
||||
|
||||
if self.doc.is_pro_applicable == 'Yes' and self.doc.is_stock_item == 'No':
|
||||
msgprint("As Production Order can be made for this Item, then Is Stock Item Should be 'Yes' as we maintain it's stock. Refer Manufacturing and Inventory section.", raise_exception=1)
|
||||
|
||||
if self.doc.is_stock_item == "Yes" and not self.doc.default_warehouse:
|
||||
msgprint("As we maintain stock of this item, its better to maintain default warehouse. To add default warehouse please go to 'Inventory' section. It will be fetched automatically while making Sales Order, Delivery Note, etc.. ", 1)
|
||||
|
||||
if self.doc.has_serial_no == 'Yes' and self.doc.is_stock_item == 'No':
|
||||
msgprint("'Has Serial No' can not be 'Yes' for non-stock item", raise_exception=1)
|
||||
|
||||
if self.doc.name:
|
||||
self.old_page_name = webnotes.conn.get_value('Item', self.doc.name, 'page_name')
|
||||
|
||||
def check_non_asset_warehouse(self):
|
||||
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)
|
||||
for e in existing_qty:
|
||||
msgprint("%s Units exist in Warehouse %s, which is not an Asset Warehouse." % (e[1],e[0]))
|
||||
if existing_qty:
|
||||
msgprint("Please transfer the above quantities to an asset warehouse before changing this item to an asset item.")
|
||||
self.doc.is_asset_item = 'No'
|
||||
raise Exception
|
||||
|
||||
def get_file_details(self, arg = ''):
|
||||
file = sql("select file_group, description from tabFile where name = %s", eval(arg)['file_name'], as_dict = 1)
|
||||
|
||||
ret = {
|
||||
'file_group' : file and file[0]['file_group'] or '',
|
||||
'description' : file and file[0]['description'] or ''
|
||||
|
||||
}
|
||||
return ret
|
||||
|
||||
def check_if_sle_exists(self):
|
||||
"""
|
||||
checks if any stock ledger entry exists for this item
|
||||
"""
|
||||
|
||||
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'
|
||||
|
||||
def on_rename(self,newdn,olddn):
|
||||
sql("update tabItem set item_code = %s where name = %s", (newdn, olddn))
|
||||
|
||||
def delete_web_cache(self, page_name):
|
||||
import website.web_cache
|
||||
website.web_cache.delete_cache(page_name)
|
||||
|
||||
def clear_web_cache(self):
|
||||
if hasattr(self, 'old_page_name') and self.old_page_name and \
|
||||
self.doc.page_name != self.old_page_name:
|
||||
self.delete_web_cache(self.doc.page_name)
|
||||
|
||||
if self.doc.show_in_website:
|
||||
import website.web_cache
|
||||
website.web_cache.create_cache(self.doc.page_name, self.doc.doctype, self.doc.name)
|
||||
website.web_cache.clear_cache(self.doc.page_name, self.doc.doctype, self.doc.name)
|
||||
else:
|
||||
self.delete_web_cache(self.doc.page_name)
|
||||
|
||||
def update_page_name(self):
|
||||
import website.utils
|
||||
|
||||
# if same name, do not repeat twice
|
||||
if self.doc.name == self.doc.item_name or not self.doc.item_name:
|
||||
page_name = self.doc.name
|
||||
else:
|
||||
page_name = self.doc.name + " " + self.doc.item_name
|
||||
|
||||
self.doc.page_name = website.utils.page_name(page_name)
|
||||
|
||||
webnotes.conn.set_value('Item', self.doc.name, 'page_name', self.doc.page_name)
|
||||
|
||||
# no need to check for uniqueness, as name is unique
|
||||
|
||||
def prepare_template_args(self):
|
||||
import markdown2
|
||||
self.doc.web_description_html = markdown2.markdown(self.doc.description or '',
|
||||
extras=["wiki-tables"])
|
||||
1014
stock/doctype/item/item.txt
Normal file
1014
stock/doctype/item/item.txt
Normal file
File diff suppressed because it is too large
Load Diff
28
stock/doctype/item/item_list.js
Normal file
28
stock/doctype/item/item_list.js
Normal file
@@ -0,0 +1,28 @@
|
||||
// render
|
||||
wn.doclistviews['Item'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d)
|
||||
this.fields = this.fields.concat([
|
||||
"`tabItem`.item_name",
|
||||
"`tabItem`.description",
|
||||
]);
|
||||
this.stats = this.stats.concat(['default_warehouse', 'brand']);
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
data.description = repl("%(item_name)s | %(description)s", data);
|
||||
if(data.description && data.description.length > 50) {
|
||||
data.description = '<span title="'+data.description+'">' +
|
||||
data.description.substr(0,50) + '...</span>';
|
||||
}
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content: 'check'},
|
||||
{width: '5%', content:'avatar'},
|
||||
{width: '20%', content:'name'},
|
||||
{width: '60%', content:'description+tags', css: {'color': '#222'}},
|
||||
{width: '12%', content:'modified', css: {'text-align': 'right', 'color':'#777'}}
|
||||
]
|
||||
});
|
||||
79
stock/doctype/item/test_item.py
Normal file
79
stock/doctype/item/test_item.py
Normal file
@@ -0,0 +1,79 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import unittest
|
||||
import webnotes
|
||||
import copy
|
||||
|
||||
from webnotes.model.doclist import DocList
|
||||
from webnotes.model.doc import Document
|
||||
from webnotes.model.code import get_obj
|
||||
from webnotes.utils import flt
|
||||
|
||||
sql = webnotes.conn.sql
|
||||
|
||||
|
||||
class TestItem(unittest.TestCase):
|
||||
def setUp(self):
|
||||
webnotes.conn.begin()
|
||||
|
||||
def tearDown(self):
|
||||
webnotes.conn.rollback()
|
||||
|
||||
def testInsert(self):
|
||||
d = DocList()
|
||||
|
||||
count_before = flt(sql("select count(*) from tab"+_doctype)[0][0])
|
||||
if docok:
|
||||
for i in docok:
|
||||
d.doc = i
|
||||
d.children = None
|
||||
d.doc.fields['__islocal']=1
|
||||
d.save(1)
|
||||
count_after = flt(sql("select count(*) from tab"+_doctype)[0][0])
|
||||
self.assertTrue(count_before+len(docok)==count_after)
|
||||
|
||||
def testFailAssert(self):
|
||||
if docnotok:
|
||||
with self.assertRaises(Exception) as context:
|
||||
d = DocList()
|
||||
d.doc = docnotok[0]
|
||||
d.children = None
|
||||
d.doc.fields['__islocal']=1
|
||||
d.save(1)
|
||||
|
||||
# Test Data
|
||||
|
||||
tabOK = [
|
||||
{'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Ink', 'default_warehouse': None, 'item_name': 'Gel Ink', 'item_group': 'Ink', 'item_code': 'GELINK', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'},
|
||||
{'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Refill', 'default_warehouse': None, 'item_name': 'Gel Refill', 'item_group': 'Refill', 'item_code': 'GELREF', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'},
|
||||
{'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Pen', 'default_warehouse': None, 'item_name': 'Gel Pen', 'item_group': 'Pen', 'item_code': 'GELPEN', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'}
|
||||
]
|
||||
|
||||
tabNotOK = [
|
||||
{'is_purchase_item': None, 'is_pro_applicable': None, 'is_manufactured_item': None, 'description': 'F Ink', 'default_warehouse': None, 'item_name': 'F Ink', 'item_group': 'F Ink', 'item_code': None, 'is_sub_contracted_item': None, 'is_stock_item': 'No', 'stock_uom': 'Nos', 'docstatus': '0'}
|
||||
]
|
||||
|
||||
_doctype = 'Item'
|
||||
|
||||
for i in tabOK: i['doctype']=_doctype
|
||||
for i in tabNotOK: i['doctype']=_doctype
|
||||
|
||||
docok = [Document(fielddata=r) for r in tabOK]
|
||||
docnotok = [Document(fielddata=r) for r in tabNotOK]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user