Merge branch 'wsgi' of https://github.com/webnotes/erpnext into i18n

Conflicts:
	accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js
	accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js
	public/js/complete_setup.js
	selling/doctype/opportunity/opportunity.js
	selling/doctype/quotation/quotation.js
This commit is contained in:
Bárbara Perretti 2013-10-16 15:09:18 -03:00
commit 4b41e5f7f7
250 changed files with 5061 additions and 2506 deletions

View File

@ -7,7 +7,6 @@ import webnotes
from webnotes.utils import flt, fmt_money, cstr, cint
from webnotes import msgprint, _
sql = webnotes.conn.sql
get_value = webnotes.conn.get_value
class DocType:
@ -25,17 +24,6 @@ class DocType:
self.doc.master_name, "address")
}
def validate(self):
self.validate_master_name()
self.validate_parent()
self.validate_duplicate_account()
self.validate_root_details()
self.validate_mandatory()
self.validate_warehouse_account()
if not self.doc.parent_account:
self.doc.parent_account = ''
def validate(self):
self.validate_master_name()
self.validate_parent()
@ -56,7 +44,7 @@ class DocType:
def validate_parent(self):
"""Fetch Parent Details and validation for account not to be created under ledger"""
if self.doc.parent_account:
par = sql("""select name, group_or_ledger, is_pl_account, debit_or_credit
par = webnotes.conn.sql("""select name, group_or_ledger, is_pl_account, debit_or_credit
from tabAccount where name =%s""", self.doc.parent_account)
if not par:
msgprint("Parent account does not exists", raise_exception=1)
@ -84,7 +72,7 @@ class DocType:
def validate_duplicate_account(self):
if self.doc.fields.get('__islocal') or not self.doc.name:
company_abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr")
if sql("""select name from tabAccount where name=%s""",
if webnotes.conn.sql("""select name from tabAccount where name=%s""",
(self.doc.account_name + " - " + company_abbr)):
msgprint("Account Name: %s already exists, please rename"
% self.doc.account_name, raise_exception=1)
@ -133,7 +121,7 @@ class DocType:
return webnotes.conn.get_value("GL Entry", {"account": self.doc.name})
def check_if_child_exists(self):
return sql("""select name from `tabAccount` where parent_account = %s
return webnotes.conn.sql("""select name from `tabAccount` where parent_account = %s
and docstatus != 2""", self.doc.name)
def validate_mandatory(self):
@ -181,7 +169,7 @@ class DocType:
# Get credit limit
credit_limit_from = 'Customer'
cr_limit = sql("""select t1.credit_limit from tabCustomer t1, `tabAccount` t2
cr_limit = webnotes.conn.sql("""select t1.credit_limit from tabCustomer t1, `tabAccount` t2
where t2.name=%s and t1.name = t2.master_name""", account)
credit_limit = cr_limit and flt(cr_limit[0][0]) or 0
if not credit_limit:
@ -221,7 +209,7 @@ class DocType:
# rename account name
new_account_name = " - ".join(parts[:-1])
sql("update `tabAccount` set account_name = %s where name = %s", (new_account_name, old))
webnotes.conn.sql("update `tabAccount` set account_name = %s where name = %s", (new_account_name, old))
if merge:
new_name = " - ".join(parts)

View File

@ -10,7 +10,6 @@ from webnotes.model.doc import addchild
from webnotes.model.bean import getlist, copy_doclist
from webnotes import msgprint
sql = webnotes.conn.sql
@ -23,7 +22,7 @@ class DocType:
msgprint("Bank Account, From Date and To Date are Mandatory")
return
dl = sql("select t1.name, t1.cheque_no, t1.cheque_date, t2.debit, t2.credit, t1.posting_date, t2.against_account from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 where t2.parent = t1.name and t2.account = %s and (clearance_date is null or clearance_date = '0000-00-00' or clearance_date = '') and t1.posting_date >= %s and t1.posting_date <= %s and t1.docstatus=1", (self.doc.bank_account, self.doc.from_date, self.doc.to_date))
dl = webnotes.conn.sql("select t1.name, t1.cheque_no, t1.cheque_date, t2.debit, t2.credit, t1.posting_date, t2.against_account from `tabJournal Voucher` t1, `tabJournal Voucher Detail` t2 where t2.parent = t1.name and t2.account = %s and (clearance_date is null or clearance_date = '0000-00-00' or clearance_date = '') and t1.posting_date >= %s and t1.posting_date <= %s and t1.docstatus=1", (self.doc.bank_account, self.doc.from_date, self.doc.to_date))
self.doclist = self.doc.clear_table(self.doclist, 'entries')
self.doc.total_amount = 0.0
@ -47,7 +46,7 @@ class DocType:
msgprint("Clearance Date can not be before Cheque Date (Row #%s)" %
d.idx, raise_exception=1)
sql("""update `tabJournal Voucher`
webnotes.conn.sql("""update `tabJournal Voucher`
set clearance_date = %s, modified = %s where name=%s""",
(d.clearance_date, nowdate(), d.voucher_id))
vouchers.append(d.voucher_id)

View File

@ -107,7 +107,7 @@ class DocType:
_(" does not belong to the company") + ": " + self.doc.company)
def check_negative_balance(account, adv_adj=False):
if not adv_adj:
if not adv_adj and account:
account_details = webnotes.conn.get_value("Account", account,
["allow_negative_balance", "debit_or_credit"], as_dict=True)
if not account_details["allow_negative_balance"]:
@ -161,16 +161,6 @@ def update_outstanding_amt(account, against_voucher_type, against_voucher, on_ca
webnotes.conn.sql("update `tab%s` set outstanding_amount=%s where name='%s'" %
(against_voucher_type, bal, against_voucher))
def validate_freezed_account(account, adv_adj=False):
"""Account has been freezed for other users except account manager"""
freezed_account = webnotes.conn.get_value("Account", account, "freeze_account")
if freezed_account == 'Yes' and not adv_adj \
and 'Accounts Manager' not in webnotes.user.get_roles():
webnotes.throw(_("Account") + ": " + account + _(" has been freezed. \
Only Accounts Manager can do transaction against this account"))
def validate_frozen_account(account, adv_adj):
frozen_account = webnotes.conn.get_value("Account", account, "freeze_account")
if frozen_account == 'Yes' and not adv_adj:
@ -183,4 +173,4 @@ def validate_frozen_account(account, adv_adj):
elif frozen_accounts_modifier not in webnotes.user.get_roles():
webnotes.throw(account + _(" is a frozen account. ") +
_("To create / edit transactions against this account, you need role") + ": " +
frozen_accounts_modifier)
frozen_accounts_modifier)

View File

@ -59,6 +59,50 @@ erpnext.accounts.JournalVoucher = wn.ui.form.Controller.extend({
};
});
},
against_voucher: function(doc, cdt, cdn) {
var d = wn.model.get_doc(cdt, cdn);
if (d.against_voucher && !flt(d.debit)) {
this.get_outstanding({
'doctype': 'Purchase Invoice',
'docname': d.against_voucher
}, d)
}
},
against_invoice: function(doc, cdt, cdn) {
var d = wn.model.get_doc(cdt, cdn);
if (d.against_invoice && !flt(d.credit)) {
this.get_outstanding({
'doctype': 'Sales Invoice',
'docname': d.against_invoice
}, d)
}
},
against_jv: function(doc, cdt, cdn) {
var d = wn.model.get_doc(cdt, cdn);
if (d.against_jv && !flt(d.credit) && !flt(d.debit)) {
this.get_outstanding({
'doctype': 'Journal Voucher',
'docname': d.against_jv,
'account': d.account
}, d)
}
},
get_outstanding: function(args, child) {
var me = this;
return this.frm.call({
child: child,
method: "get_outstanding",
args: { args: args},
callback: function(r) {
cur_frm.cscript.update_totals(me.frm.doc);
}
});
}
});
cur_frm.script_manager.make(erpnext.accounts.JournalVoucher);
@ -88,24 +132,6 @@ cur_frm.cscript.is_opening = function(doc, cdt, cdn) {
if (doc.is_opening == 'Yes') unhide_field('aging_date');
}
cur_frm.cscript.against_voucher = function(doc,cdt,cdn) {
var d = locals[cdt][cdn];
if (d.against_voucher && !flt(d.debit)) {
args = {'doctype': 'Purchase Invoice', 'docname': d.against_voucher }
return get_server_fields('get_outstanding',docstring(args),'entries',doc,cdt,cdn,1,function(r,rt) { cur_frm.cscript.update_totals(doc); });
}
}
cur_frm.cscript.against_invoice = function(doc,cdt,cdn) {
var d = locals[cdt][cdn];
if (d.against_invoice && !flt(d.credit)) {
args = {'doctype': 'Sales Invoice', 'docname': d.against_invoice }
return get_server_fields('get_outstanding',docstring(args),'entries',doc,cdt,cdn,1,function(r,rt) { cur_frm.cscript.update_totals(doc); });
}
}
// Update Totals
cur_frm.cscript.update_totals = function(doc) {
var td=0.0; var tc =0.0;
var el = getchildren('Journal Voucher Detail', doc.name, 'entries');

View File

@ -260,15 +260,6 @@ class DocType(AccountsController):
if gl_map:
make_gl_entries(gl_map, cancel=cancel, adv_adj=adv_adj)
def get_outstanding(self, args):
args = eval(args)
o_s = webnotes.conn.sql("""select outstanding_amount from `tab%s` where name = %s""" %
(args['doctype'], '%s'), args['docname'])
if args['doctype'] == 'Purchase Invoice':
return {'debit': o_s and flt(o_s[0][0]) or 0}
if args['doctype'] == 'Sales Invoice':
return {'credit': o_s and flt(o_s[0][0]) or 0}
def get_balance(self):
if not getlist(self.doclist,'entries'):
msgprint("Please enter atleast 1 entry in 'GL Entries' table")
@ -434,4 +425,31 @@ def get_against_jv(doctype, txt, searchfield, start, page_len, filters):
where jv_detail.parent = jv.name and jv_detail.account = %s and jv.docstatus = 1
and jv.%s like %s order by jv.name desc limit %s, %s""" %
("%s", searchfield, "%s", "%s", "%s"),
(filters["account"], "%%%s%%" % txt, start, page_len))
(filters["account"], "%%%s%%" % txt, start, page_len))
@webnotes.whitelist()
def get_outstanding(args):
args = eval(args)
if args.get("doctype") == "Journal Voucher" and args.get("account"):
against_jv_amount = webnotes.conn.sql("""
select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0))
from `tabJournal Voucher Detail` where parent=%s and account=%s
and ifnull(against_invoice, '')='' and ifnull(against_voucher, '')=''
and ifnull(against_jv, '')=''""", (args['docname'], args['account']))
against_jv_amount = flt(against_jv_amount[0][0]) if against_jv_amount else 0
if against_jv_amount > 0:
return {"credit": against_jv_amount}
else:
return {"debit": -1* against_jv_amount}
elif args.get("doctype") == "Sales Invoice":
return {
"credit": flt(webnotes.conn.get_value("Sales Invoice", args["docname"],
"outstanding_amount"))
}
elif args.get("doctype") == "Purchase Invoice":
return {
"debit": flt(webnotes.conn.get_value("Purchase Invoice", args["docname"],
"outstanding_amount"))
}

View File

@ -11,7 +11,6 @@ from webnotes import session, msgprint
import webnotes.defaults
sql = webnotes.conn.sql
from accounts.utils import get_balance_on, get_fiscal_year
@ -44,7 +43,7 @@ class DocType:
ret['company'] = get_companies()
#--- to get fiscal year and start_date of that fiscal year -----
res = sql("select name, year_start_date from `tabFiscal Year`")
res = webnotes.conn.sql("select name, year_start_date from `tabFiscal Year`")
ret['fiscal_year'] = [r[0] for r in res]
ret['start_dates'] = {}
for r in res:
@ -52,7 +51,7 @@ class DocType:
#--- from month and to month (for MIS - Comparison Report) -------
month_list = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
fiscal_start_month = sql("select MONTH(year_start_date) from `tabFiscal Year` where name = %s",(webnotes.defaults.get_global_default("fiscal_year")))
fiscal_start_month = webnotes.conn.sql("select MONTH(year_start_date) from `tabFiscal Year` where name = %s",(webnotes.defaults.get_global_default("fiscal_year")))
fiscal_start_month = fiscal_start_month and fiscal_start_month[0][0] or 1
mon = ['']
for i in range(fiscal_start_month,13): mon.append(month_list[i-1])
@ -107,7 +106,7 @@ class DocType:
def dates(self,fiscal_year,from_date,to_date):
import datetime
ret = ''
start_date = cstr(sql("select year_start_date from `tabFiscal Year` where name = %s",fiscal_year)[0][0])
start_date = cstr(webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name = %s",fiscal_year)[0][0])
st_mon = cint(from_date.split('-')[1])
ed_mon = cint(to_date.split('-')[1])
st_day = cint(from_date.split('-')[2])
@ -152,7 +151,7 @@ class DocType:
def get_totals(self, args):
args = eval(args)
#msgprint(args)
totals = sql("SELECT %s FROM %s WHERE %s %s %s %s" %(cstr(args['query_val']), cstr(args['tables']), cstr(args['company']), cstr(args['cond']), cstr(args['add_cond']), cstr(args['fil_cond'])), as_dict = 1)[0]
totals = webnotes.conn.sql("SELECT %s FROM %s WHERE %s %s %s %s" %(cstr(args['query_val']), cstr(args['tables']), cstr(args['company']), cstr(args['cond']), cstr(args['add_cond']), cstr(args['fil_cond'])), as_dict = 1)[0]
#msgprint(totals)
tot_keys = totals.keys()
# return in flt because JSON doesn't accept Decimal
@ -185,7 +184,7 @@ class DocType:
# Get Children
# ------------
def get_children(self, parent_account, level, pl, company, fy):
cl = sql("select distinct account_name, name, debit_or_credit, lft, rgt from `tabAccount` where ifnull(parent_account, '') = %s and ifnull(is_pl_account, 'No')=%s and company=%s and docstatus != 2 order by name asc", (parent_account, pl, company))
cl = webnotes.conn.sql("select distinct account_name, name, debit_or_credit, lft, rgt from `tabAccount` where ifnull(parent_account, '') = %s and ifnull(is_pl_account, 'No')=%s and company=%s and docstatus != 2 order by name asc", (parent_account, pl, company))
level0_diff = [0 for p in self.period_list]
if pl=='Yes' and level==0: # switch for income & expenses
cl = [c for c in cl]
@ -238,7 +237,7 @@ class DocType:
def define_periods(self, year, period):
# get year start date
ysd = sql("select year_start_date from `tabFiscal Year` where name=%s", year)
ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name=%s", year)
ysd = ysd and ysd[0][0] or ''
self.ysd = ysd

View File

@ -69,7 +69,6 @@ class DocType(AccountsController):
def get_pl_balances(self):
"""Get balance for pl accounts"""
return webnotes.conn.sql("""
select t1.account, sum(ifnull(t1.debit,0))-sum(ifnull(t1.credit,0)) as balance
from `tabGL Entry` t1, `tabAccount` t2
@ -101,4 +100,4 @@ class DocType(AccountsController):
}))
from accounts.general_ledger import make_gl_entries
make_gl_entries(gl_entries)
make_gl_entries(gl_entries)

View File

@ -8,6 +8,9 @@ import webnotes
class TestPeriodClosingVoucher(unittest.TestCase):
def test_closing_entry(self):
# clear GL Entries
webnotes.conn.sql("""delete from `tabGL Entry`""")
from accounts.doctype.journal_voucher.test_journal_voucher import test_records as jv_records
jv = webnotes.bean(copy=jv_records[2])
jv.insert()

View File

@ -2,7 +2,7 @@
{
"creation": "2013-05-24 12:15:51",
"docstatus": 0,
"modified": "2013-08-28 19:13:42",
"modified": "2013-10-15 11:12:02",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -80,16 +80,6 @@
"read_only": 0,
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "conversion_rate",
"fieldtype": "Float",
"label": "Conversion Rate",
"oldfieldname": "conversion_rate",
"oldfieldtype": "Currency",
"read_only": 0,
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "selling_price_list",

View File

@ -8,6 +8,7 @@ cur_frm.cscript.other_fname = "purchase_tax_details";
wn.provide("erpnext.accounts");
wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js');
wn.require('app/buying/doctype/purchase_common/purchase_common.js');
wn.require('app/accounts/doctype/sales_invoice/pos.js');
erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
onload: function() {

View File

@ -12,7 +12,6 @@ from setup.utils import get_company_currency
import webnotes.defaults
sql = webnotes.conn.sql
from controllers.buying_controller import BuyingController
class DocType(BuyingController):
@ -62,19 +61,23 @@ class DocType(BuyingController):
"purchase_receipt_details")
def get_credit_to(self):
acc_head = sql("""select name, credit_days from `tabAccount`
where (name = %s or (master_name = %s and master_type = 'supplier'))
and docstatus != 2 and company = %s""",
(cstr(self.doc.supplier) + " - " + self.company_abbr,
self.doc.supplier, self.doc.company))
ret = {}
if acc_head and acc_head[0][0]:
ret['credit_to'] = acc_head[0][0]
if not self.doc.due_date:
ret['due_date'] = add_days(cstr(self.doc.posting_date), acc_head and cint(acc_head[0][1]) or 0)
elif not acc_head:
msgprint("%s does not have an Account Head in %s. You must first create it from the Supplier Master" % (self.doc.supplier, self.doc.company))
if self.doc.supplier:
acc_head = webnotes.conn.sql("""select name, credit_days from `tabAccount`
where (name = %s or (master_name = %s and master_type = 'supplier'))
and docstatus != 2 and company = %s""",
(cstr(self.doc.supplier) + " - " + self.company_abbr,
self.doc.supplier, self.doc.company))
if acc_head and acc_head[0][0]:
ret['credit_to'] = acc_head[0][0]
if not self.doc.due_date:
ret['due_date'] = add_days(cstr(self.doc.posting_date),
acc_head and cint(acc_head[0][1]) or 0)
elif not acc_head:
msgprint("%s does not have an Account Head in %s. \
You must first create it from the Supplier Master" % \
(self.doc.supplier, self.doc.company))
return ret
def set_supplier_defaults(self):
@ -85,18 +88,10 @@ class DocType(BuyingController):
super(DocType, self).get_advances(self.doc.credit_to,
"Purchase Invoice Advance", "advance_allocation_details", "debit")
def get_rate(self,arg):
return get_obj('Purchase Common').get_rate(arg,self)
def get_rate1(self,acc):
rate = sql("select tax_rate from `tabAccount` where name='%s'"%(acc))
ret={'add_tax_rate' :rate and flt(rate[0][0]) or 0 }
return ret
def check_active_purchase_items(self):
for d in getlist(self.doclist, 'entries'):
if d.item_code: # extra condn coz item_code is not mandatory in PV
valid_item = sql("select docstatus,is_purchase_item from tabItem where name = %s",d.item_code)
valid_item = webnotes.conn.sql("select docstatus,is_purchase_item from tabItem where name = %s",d.item_code)
if valid_item[0][0] == 2:
msgprint("Item : '%s' is Inactive, you can restore it from Trash" %(d.item_code))
raise Exception
@ -116,7 +111,7 @@ class DocType(BuyingController):
def validate_bill_no(self):
if self.doc.bill_no and self.doc.bill_no.lower().strip() \
not in ['na', 'not applicable', 'none']:
b_no = sql("""select bill_no, name, ifnull(is_opening,'') from `tabPurchase Invoice`
b_no = webnotes.conn.sql("""select bill_no, name, ifnull(is_opening,'') from `tabPurchase Invoice`
where bill_no = %s and credit_to = %s and docstatus = 1 and name != %s""",
(self.doc.bill_no, self.doc.credit_to, self.doc.name))
if b_no and cstr(b_no[0][2]) == cstr(self.doc.is_opening):
@ -132,7 +127,7 @@ class DocType(BuyingController):
self.doc.remarks = "No Remarks"
def validate_credit_acc(self):
acc = sql("select debit_or_credit, is_pl_account from tabAccount where name = %s",
acc = webnotes.conn.sql("select debit_or_credit, is_pl_account from tabAccount where name = %s",
self.doc.credit_to)
if not acc:
msgprint("Account: "+ self.doc.credit_to + "does not exist")
@ -148,7 +143,7 @@ class DocType(BuyingController):
# ------------------------------------------------------------
def check_for_acc_head_of_supplier(self):
if self.doc.supplier and self.doc.credit_to:
acc_head = sql("select master_name from `tabAccount` where name = %s", self.doc.credit_to)
acc_head = webnotes.conn.sql("select master_name from `tabAccount` where name = %s", self.doc.credit_to)
if (acc_head and cstr(acc_head[0][0]) != cstr(self.doc.supplier)) or (not acc_head and (self.doc.credit_to != cstr(self.doc.supplier) + " - " + self.company_abbr)):
msgprint("Credit To: %s do not match with Supplier: %s for Company: %s.\n If both correctly entered, please select Master Type and Master Name in account master." %(self.doc.credit_to,self.doc.supplier,self.doc.company), raise_exception=1)
@ -160,7 +155,7 @@ class DocType(BuyingController):
for d in getlist(self.doclist,'entries'):
if d.purchase_order and not d.purchase_order in check_list and not d.purchase_receipt:
check_list.append(d.purhcase_order)
stopped = sql("select name from `tabPurchase Order` where status = 'Stopped' and name = '%s'" % d.purchase_order)
stopped = webnotes.conn.sql("select name from `tabPurchase Order` where status = 'Stopped' and name = '%s'" % d.purchase_order)
if stopped:
msgprint("One cannot do any transaction against 'Purchase Order' : %s, it's status is 'Stopped'" % (d.purhcase_order))
raise Exception
@ -260,11 +255,11 @@ class DocType(BuyingController):
def check_prev_docstatus(self):
for d in getlist(self.doclist,'entries'):
if d.purchase_order:
submitted = sql("select name from `tabPurchase Order` where docstatus = 1 and name = '%s'" % d.purchase_order)
submitted = webnotes.conn.sql("select name from `tabPurchase Order` where docstatus = 1 and name = '%s'" % d.purchase_order)
if not submitted:
webnotes.throw("Purchase Order : "+ cstr(d.purchase_order) +" is not submitted")
if d.purchase_receipt:
submitted = sql("select name from `tabPurchase Receipt` where docstatus = 1 and name = '%s'" % d.purchase_receipt)
submitted = webnotes.conn.sql("select name from `tabPurchase Receipt` where docstatus = 1 and name = '%s'" % d.purchase_receipt)
if not submitted:
webnotes.throw("Purchase Receipt : "+ cstr(d.purchase_receipt) +" is not submitted")
@ -334,7 +329,7 @@ class DocType(BuyingController):
)
# tax table gl entries
valuation_tax = 0
valuation_tax = {}
for tax in self.doclist.get({"parentfield": "purchase_tax_details"}):
if tax.category in ("Total", "Valuation and Total") and flt(tax.tax_amount):
gl_entries.append(
@ -349,8 +344,11 @@ class DocType(BuyingController):
)
# accumulate valuation tax
if tax.category in ("Valuation", "Valuation and Total") and flt(tax.tax_amount):
valuation_tax += (tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.tax_amount)
if tax.category in ("Valuation", "Valuation and Total") and flt(tax.tax_amount) \
and tax.cost_center:
valuation_tax.setdefault(tax.cost_center, 0)
valuation_tax[tax.cost_center] += \
(tax.add_deduct_tax == "Add" and 1 or -1) * flt(tax.tax_amount)
# item gl entries
stock_item_and_auto_accounting_for_stock = False
@ -391,15 +389,19 @@ class DocType(BuyingController):
if stock_item_and_auto_accounting_for_stock and valuation_tax:
# credit valuation tax amount in "Expenses Included In Valuation"
# this will balance out valuation amount included in cost of goods sold
gl_entries.append(
self.get_gl_dict({
"account": self.get_company_default("expenses_included_in_valuation"),
"cost_center": self.get_company_default("cost_center"),
"against": self.doc.credit_to,
"credit": valuation_tax,
"remarks": self.doc.remarks or "Accounting Entry for Stock"
})
)
expenses_included_in_valuation = \
self.get_company_default("expenses_included_in_valuation")
for cost_center, amount in valuation_tax.items():
gl_entries.append(
self.get_gl_dict({
"account": expenses_included_in_valuation,
"cost_center": cost_center,
"against": self.doc.credit_to,
"credit": amount,
"remarks": self.doc.remarks or "Accounting Entry for Stock"
})
)
# writeoff account includes petty difference in the invoice amount
# and the amount that is paid
@ -432,7 +434,7 @@ class DocType(BuyingController):
def update_raw_material_cost(self):
if self.sub_contracted_items:
for d in self.doclist.get({"parentfield": "entries"}):
rm_cost = webnotes.conn.sql(""" select raw_material_cost / quantity
rm_cost = webnotes.conn.sql("""select raw_material_cost / quantity
from `tabBOM` where item = %s and is_default = 1 and docstatus = 1
and is_active = 1 """, (d.item_code,))
rm_cost = rm_cost and flt(rm_cost[0][0]) or 0

View File

@ -2,12 +2,13 @@
{
"creation": "2013-05-21 16:16:39",
"docstatus": 0,
"modified": "2013-08-09 14:45:35",
"modified": "2013-10-02 14:24:55",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_attach": 1,
"allow_import": 1,
"autoname": "naming_series:",
"doctype": "DocType",
"icon": "icon-file-text",

View File

@ -4,6 +4,8 @@
//
//--------- ONLOAD -------------
wn.require("app/js/controllers/accounts.js");
cur_frm.cscript.onload = function(doc, cdt, cdn) {
}
@ -134,6 +136,7 @@ cur_frm.fields_dict['purchase_tax_details'].grid.get_field("cost_center").get_qu
}
}
<<<<<<< HEAD
cur_frm.cscript.account_head = function(doc, cdt, cdn) {
var d = locals[cdt][cdn];
if(!d.charge_type && d.account_head){
@ -148,6 +151,8 @@ cur_frm.cscript.account_head = function(doc, cdt, cdn) {
refresh_field('account_head',d.name,'purchase_tax_details');
}
=======
>>>>>>> f146e8b7f52a3e46e335c0fefd92c347717b370b
cur_frm.cscript.rate = function(doc, cdt, cdn) {
var d = locals[cdt][cdn];
if(!d.charge_type && d.rate) {

View File

@ -8,16 +8,10 @@ from webnotes.model import db_exists
from webnotes.model.bean import copy_doclist
from webnotes.model.code import get_obj
sql = webnotes.conn.sql
class DocType:
def __init__(self, doc, doclist=[]):
self.doc = doc
self.doclist = doclist
# Get Tax Rate if account type is Tax
# ===================================================================
def get_rate(self, arg):
return get_obj('Purchase Common').get_rate(arg, self)
self.doclist = doclist

View File

@ -7,7 +7,7 @@ erpnext.POS = Class.extend({
this.frm = frm;
this.wrapper.html('<div class="container">\
<div class="row">\
<div class="customer-area col-sm-3 col-xs-6"></div>\
<div class="party-area col-sm-3 col-xs-6"></div>\
<div class="barcode-area col-sm-3 col-xs-6"></div>\
<div class="search-area col-sm-3 col-xs-6"></div>\
<div class="item-group-area col-sm-3 col-xs-6"></div>\
@ -71,7 +71,18 @@ erpnext.POS = Class.extend({
</div>\
</div>\
</div></div>');
if (wn.meta.has_field(cur_frm.doc.doctype, "customer")) {
this.party = "Customer";
this.price_list = this.frm.doc.selling_price_list;
this.sales_or_purchase = "Sales";
}
else if (wn.meta.has_field(cur_frm.doc.doctype, "supplier")) {
this.party = "Supplier";
this.price_list = this.frm.doc.buying_price_list;
this.sales_or_purchase = "Purchase";
}
this.make();
var me = this;
@ -88,28 +99,29 @@ erpnext.POS = Class.extend({
});
},
make: function() {
this.make_customer();
this.make_party();
this.make_item_group();
this.make_search();
this.make_barcode();
this.make_item_list();
},
make_customer: function() {
make_party: function() {
var me = this;
this.customer = wn.ui.form.make_control({
this.party_field = wn.ui.form.make_control({
df: {
"fieldtype": "Link",
"options": "Customer",
"label": "Customer",
"fieldname": "pos_customer",
"placeholder": "Customer"
"options": this.party,
"label": this.party,
"fieldname": "pos_party",
"placeholder": this.party
},
parent: this.wrapper.find(".customer-area")
parent: this.wrapper.find(".party-area")
});
this.customer.make_input();
this.customer.$input.on("change", function() {
if(!me.customer.autocomplete_open)
wn.model.set_value("Sales Invoice", me.frm.docname, "customer", this.value);
this.party_field.make_input();
this.party_field.$input.on("change", function() {
if(!me.party_field.autocomplete_open)
wn.model.set_value(me.frm.doctype, me.frm.docname,
me.party.toLowerCase(), this.value);
});
},
make_item_group: function() {
@ -120,7 +132,7 @@ erpnext.POS = Class.extend({
"options": "Item Group",
"label": "Item Group",
"fieldname": "pos_item_group",
"placeholder": "Filter by Item Group"
"placeholder": "Item Group"
},
parent: this.wrapper.find(".item-group-area")
});
@ -138,7 +150,7 @@ erpnext.POS = Class.extend({
"options": "Item",
"label": "Item",
"fieldname": "pos_item",
"placeholder": "Select Item"
"placeholder": "Item"
},
parent: this.wrapper.find(".search-area")
});
@ -155,7 +167,7 @@ erpnext.POS = Class.extend({
"fieldtype": "Data",
"label": "Barcode",
"fieldname": "pos_barcode",
"placeholder": "Select Barcode"
"placeholder": "Barcode"
},
parent: this.wrapper.find(".barcode-area")
});
@ -171,7 +183,8 @@ erpnext.POS = Class.extend({
wn.call({
method: 'accounts.doctype.sales_invoice.pos.get_items',
args: {
price_list: cur_frm.doc.selling_price_list,
sales_or_purchase: this.sales_or_purchase,
price_list: this.price_list,
item_group: this.item_group.$input.val(),
item: this.search.$input.val()
},
@ -200,15 +213,18 @@ erpnext.POS = Class.extend({
});
// if form is local then allow this function
if (cur_frm.doc.docstatus===0) {
$("div.pos-item").on("click", function() {
if(!cur_frm.doc.customer) {
msgprint("Please select customer first.");
$(me.wrapper).find("div.pos-item").on("click", function() {
if(me.frm.doc.docstatus==0) {
if(!me.frm.doc[me.party.toLowerCase()] && ((me.frm.doctype == "Quotation" &&
me.frm.doc.quotation_to == "Customer")
|| me.frm.doctype != "Quotation")) {
msgprint("Please select " + me.party + " first.");
return;
}
me.add_to_cart($(this).attr("data-item_code"));
});
}
else
me.add_to_cart($(this).attr("data-item_code"));
}
});
}
});
},
@ -217,12 +233,12 @@ erpnext.POS = Class.extend({
var caught = false;
// get no_of_items
no_of_items = me.wrapper.find("#cart tbody").length;
var no_of_items = me.wrapper.find("#cart tbody tr").length;
// check whether the item is already added
if (no_of_items != 0) {
$.each(wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries",
"Sales Invoice"), function(i, d) {
$.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
this.frm.cscript.fname, this.frm.doctype), function(i, d) {
if (d.item_code == item_code)
caught = true;
});
@ -233,15 +249,16 @@ erpnext.POS = Class.extend({
me.update_qty(item_code, 1);
}
else {
var child = wn.model.add_child(me.frm.doc, "Sales Invoice Item", "entries");
var child = wn.model.add_child(me.frm.doc, this.frm.doctype + " Item",
this.frm.cscript.fname);
child.item_code = item_code;
me.frm.cscript.item_code(me.frm.doc, child.doctype, child.name);
}
},
update_qty: function(item_code, qty, textbox_qty) {
var me = this;
$.each(wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries",
"Sales Invoice"), function(i, d) {
$.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
this.frm.cscript.fname, this.frm.doctype), function(i, d) {
if (d.item_code == item_code) {
if (textbox_qty) {
if (qty == 0 && d.item_code == item_code)
@ -259,14 +276,24 @@ erpnext.POS = Class.extend({
},
refresh: function() {
var me = this;
this.customer.set_input(this.frm.doc.customer);
this.party_field.set_input(this.frm.doc[this.party.toLowerCase()]);
this.barcode.set_input("");
// add items
var $items = me.wrapper.find("#cart tbody").empty();
$.each(wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries",
"Sales Invoice"), function(i, d) {
$.each(wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
this.frm.cscript.fname, this.frm.doctype), function(i, d) {
if (me.sales_or_purchase == "Sales") {
item_amount = d.export_amount;
rate = d.export_rate;
}
else {
item_amount = d.import_amount;
rate = d.import_rate;
}
$(repl('<tr id="%(item_code)s" data-selected="false">\
<td>%(item_code)s%(item_name)s</td>\
<td><input type="text" value="%(qty)s" \
@ -277,16 +304,16 @@ erpnext.POS = Class.extend({
item_code: d.item_code,
item_name: d.item_name===d.item_code ? "" : ("<br>" + d.item_name),
qty: d.qty,
rate: format_currency(d.ref_rate, cur_frm.doc.price_list_currency),
amount: format_currency(d.export_amount, cur_frm.doc.price_list_currency)
rate: format_currency(rate, me.frm.doc.currency),
amount: format_currency(item_amount, me.frm.doc.currency)
}
)).appendTo($items);
});
// taxes
var taxes = wn.model.get_children("Sales Taxes and Charges", this.frm.doc.name, "other_charges",
"Sales Invoice");
$(".tax-table")
var taxes = wn.model.get_children(this.sales_or_purchase + " Taxes and Charges",
this.frm.doc.name, this.frm.cscript.other_fname, this.frm.doctype);
$(this.wrapper).find(".tax-table")
.toggle((taxes && taxes.length) ? true : false)
.find("tbody").empty();
@ -297,30 +324,39 @@ erpnext.POS = Class.extend({
<tr>', {
description: d.description,
rate: d.rate,
tax_amount: format_currency(d.tax_amount, me.frm.doc.price_list_currency)
tax_amount: format_currency(flt(d.tax_amount)/flt(me.frm.doc.conversion_rate),
me.frm.doc.currency)
})).appendTo(".tax-table tbody");
});
// set totals
this.wrapper.find(".net-total").text(format_currency(this.frm.doc.net_total_export,
cur_frm.doc.price_list_currency));
this.wrapper.find(".grand-total").text(format_currency(this.frm.doc.grand_total_export,
cur_frm.doc.price_list_currency));
if (this.sales_or_purchase == "Sales") {
this.wrapper.find(".net-total").text(format_currency(this.frm.doc.net_total_export,
me.frm.doc.currency));
this.wrapper.find(".grand-total").text(format_currency(this.frm.doc.grand_total_export,
me.frm.doc.currency));
}
else {
this.wrapper.find(".net-total").text(format_currency(this.frm.doc.net_total_import,
me.frm.doc.currency));
this.wrapper.find(".grand-total").text(format_currency(this.frm.doc.grand_total_import,
me.frm.doc.currency));
}
// if form is local then only run all these functions
if (cur_frm.doc.docstatus===0) {
$("input.qty").on("focus", function() {
if (this.frm.doc.docstatus===0) {
$(this.wrapper).find("input.qty").on("focus", function() {
$(this).select();
});
// append quantity to the respective item after change from input box
$("input.qty").on("change", function() {
$(this.wrapper).find("input.qty").on("change", function() {
var item_code = $(this).closest("tr")[0].id;
me.update_qty(item_code, $(this).val(), true);
});
// on td click toggle the highlighting of row
$("#cart tbody tr td").on("click", function() {
$(this.wrapper).find("#cart tbody tr td").on("click", function() {
var row = $(this).closest("tr");
if (row.attr("data-selected") == "false") {
row.attr("class", "warning");
@ -335,20 +371,37 @@ erpnext.POS = Class.extend({
});
me.refresh_delete_btn();
cur_frm.pos.barcode.$input.focus();
this.barcode.$input.focus();
}
// if form is submitted & cancelled then disable all input box & buttons
if (cur_frm.doc.docstatus>=1 && cint(cur_frm.doc.is_pos)) {
me.wrapper.find('input, button').each(function () {
if (this.frm.doc.docstatus>=1) {
$(this.wrapper).find('input, button').each(function () {
$(this).prop('disabled', true);
});
$(".delete-items").hide();
$(".make-payment").hide();
$(this.wrapper).find(".delete-items").hide();
$(this.wrapper).find(".make-payment").hide();
}
else {
$(this.wrapper).find('input, button').each(function () {
$(this).prop('disabled', false);
});
$(this.wrapper).find(".make-payment").show();
}
// Show Make Payment button only in Sales Invoice
if (this.frm.doctype != "Sales Invoice")
$(this.wrapper).find(".make-payment").hide();
// If quotation to is not Customer then remove party
if (this.frm.doctype == "Quotation") {
this.party_field.$wrapper.remove();
if (this.frm.doc.quotation_to == "Customer")
this.make_party();
}
},
refresh_delete_btn: function() {
$(".delete-items").toggle($(".item-cart .warning").length ? true : false);
$(this.wrapper).find(".delete-items").toggle($(".item-cart .warning").length ? true : false);
},
add_item_thru_barcode: function() {
var me = this;
@ -370,32 +423,32 @@ erpnext.POS = Class.extend({
remove_selected_item: function() {
var me = this;
var selected_items = [];
var no_of_items = $("#cart tbody tr").length;
var no_of_items = $(this.wrapper).find("#cart tbody tr").length;
for(var x=0; x<=no_of_items - 1; x++) {
var row = $("#cart tbody tr:eq(" + x + ")");
var row = $(this.wrapper).find("#cart tbody tr:eq(" + x + ")");
if(row.attr("data-selected") == "true") {
selected_items.push(row.attr("id"));
}
}
var child = wn.model.get_children("Sales Invoice Item", this.frm.doc.name, "entries",
"Sales Invoice");
var child = wn.model.get_children(this.frm.doctype + " Item", this.frm.doc.name,
this.frm.cscript.fname, this.frm.doctype);
$.each(child, function(i, d) {
for (var i in selected_items) {
if (d.item_code == selected_items[i]) {
// cur_frm.fields_dict["entries"].grid.grid_rows[d.idx].remove();
wn.model.clear_doc(d.doctype, d.name);
}
}
});
cur_frm.fields_dict["entries"].grid.refresh();
cur_frm.script_manager.trigger("calculate_taxes_and_totals");
this.frm.fields_dict[this.frm.cscript.fname].grid.refresh();
this.frm.script_manager.trigger("calculate_taxes_and_totals");
me.frm.dirty();
me.refresh();
},
make_payment: function() {
var me = this;
var no_of_items = $("#cart tbody tr").length;
var no_of_items = $(this.wrapper).find("#cart tbody tr").length;
var mode_of_payment = [];
if (no_of_items == 0)
@ -423,15 +476,15 @@ erpnext.POS = Class.extend({
"total_amount": $(".grand-total").text()
});
dialog.show();
cur_frm.pos.barcode.$input.focus();
me.barcode.$input.focus();
dialog.get_input("total_amount").prop("disabled", true);
dialog.fields_dict.pay.input.onclick = function() {
cur_frm.set_value("mode_of_payment", dialog.get_values().mode_of_payment);
cur_frm.set_value("paid_amount", dialog.get_values().total_amount);
cur_frm.cscript.mode_of_payment(cur_frm.doc);
cur_frm.save();
me.frm.set_value("mode_of_payment", dialog.get_values().mode_of_payment);
me.frm.set_value("paid_amount", dialog.get_values().total_amount);
me.frm.cscript.mode_of_payment(me.frm.doc);
me.frm.save();
dialog.hide();
me.refresh();
};

View File

@ -3,17 +3,21 @@
from __future__ import unicode_literals
import webnotes
from webnotes import msgprint
@webnotes.whitelist()
def get_items(price_list, item=None, item_group=None):
def get_items(price_list, sales_or_purchase, item=None, item_group=None):
condition = ""
if sales_or_purchase == "Sales":
condition = "i.is_sales_item='Yes'"
else:
condition = "i.is_purchase_item='Yes'"
if item_group and item_group != "All Item Groups":
condition = "and i.item_group='%s'" % item_group
condition += " and i.item_group='%s'" % item_group
if item:
condition = "and i.name='%s'" % item
condition += " and i.name='%s'" % item
return webnotes.conn.sql("""select i.name, i.item_name, i.image,
pl_items.ref_rate, pl_items.currency
@ -24,13 +28,18 @@ def get_items(price_list, item=None, item_group=None):
ON
pl_items.item_code=i.name
where
i.is_sales_item='Yes'%s""" % ('%s', condition), (price_list), as_dict=1)
%s""" % ('%s', condition), (price_list), as_dict=1)
@webnotes.whitelist()
def get_item_from_barcode(barcode):
return webnotes.conn.sql("""select name from `tabItem` where barcode=%s""",
(barcode), as_dict=1)
@webnotes.whitelist()
def get_item_from_serial_no(serial_no):
return webnotes.conn.sql("""select name, item_code from `tabSerial No` where
name=%s""", (serial_no), as_dict=1)
@webnotes.whitelist()
def get_mode_of_payment():
return webnotes.conn.sql("""select name from `tabMode of Payment`""", as_dict=1)

View File

@ -1,15 +0,0 @@
.pos-item {
height: 200px;
overflow: hidden;
cursor: pointer;
padding-left: 5px !important;
padding-right: 5px !important;
}
.pos-bill {
padding: 20px 5px;
font-family: Monospace;
border: 1px solid #eee;
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
}

View File

@ -29,9 +29,10 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
// toggle to pos view if is_pos is 1 in user_defaults
if ((cint(wn.defaults.get_user_defaults("is_pos"))===1 || cur_frm.doc.is_pos) &&
cint(wn.defaults.get_user_defaults("fs_pos_view"))===1) {
this.frm.set_value("is_pos", 1);
this.is_pos();
cur_frm.cscript.toggle_pos(true);
if(this.frm.doc.__islocal && !this.frm.doc.amended_from) {
this.frm.set_value("is_pos", 1);
this.is_pos(function() {cur_frm.cscript.toggle_pos(true);});
}
}
// if document is POS then change default print format to "POS Invoice"
@ -78,14 +79,11 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
cur_frm.add_custom_button(wn._('Make Payment Entry'), cur_frm.cscript.make_bank_voucher);
}
if (doc.docstatus===0) {
// Show buttons only when pos view is active
if (doc.docstatus===0 && !this.pos_active) {
cur_frm.cscript.sales_order_btn();
cur_frm.cscript.delivery_note_btn();
}
// Show POS button only if it enabled from features setup
if(cint(sys_defaults.fs_pos_view)===1)
cur_frm.cscript.pos_btn();
},
sales_order_btn: function() {
@ -124,62 +122,13 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
});
});
},
pos_btn: function() {
if(cur_frm.$pos_btn)
cur_frm.$pos_btn.remove();
if(!cur_frm.pos_active) {
var btn_label = wn._("POS View"),
icon = "icon-desktop";
cur_frm.cscript.sales_order_btn();
cur_frm.cscript.delivery_note_btn();
} else {
var btn_label = wn._("Invoice View"),
icon = "icon-file-text";
if (cur_frm.doc.docstatus===0) {
this.$delivery_note_btn.remove();
this.$sales_order_btn.remove();
}
}
cur_frm.$pos_btn = cur_frm.add_custom_button(btn_label, function() {
cur_frm.cscript.toggle_pos();
cur_frm.cscript.pos_btn();
}, icon);
},
toggle_pos: function(show) {
if (!this.frm.doc.selling_price_list)
msgprint(wn._("Please select Price List"))
else {
if((show===true && cur_frm.pos_active) || (show===false && !cur_frm.pos_active)) return;
// make pos
if(!cur_frm.pos) {
cur_frm.layout.add_view("pos");
cur_frm.pos = new erpnext.POS(cur_frm.layout.views.pos, cur_frm);
}
// toggle view
cur_frm.layout.set_view(cur_frm.pos_active ? "" : "pos");
cur_frm.pos_active = !cur_frm.pos_active;
// refresh
if(cur_frm.pos_active)
cur_frm.pos.refresh();
}
},
tc_name: function() {
this.get_terms();
},
is_pos: function() {
is_pos: function(callback_fn) {
cur_frm.cscript.hide_fields(this.frm.doc);
if(cint(this.frm.doc.is_pos)) {
if(!this.frm.doc.company) {
this.frm.set_value("is_pos", 0);
@ -192,6 +141,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
callback: function(r) {
if(!r.exc) {
me.frm.script_manager.trigger("update_stock");
if(callback_fn) callback_fn()
}
}
});
@ -256,7 +206,6 @@ cur_frm.cscript.hide_fields = function(doc) {
'total_commission', 'advances'];
item_flds_normal = ['sales_order', 'delivery_note']
item_flds_pos = ['serial_no', 'batch_no', 'actual_qty', 'expense_account']
if(cint(doc.is_pos) == 1) {
hide_field(par_flds);
@ -271,7 +220,9 @@ cur_frm.cscript.hide_fields = function(doc) {
cur_frm.fields_dict['entries'].grid.set_column_disp(item_flds_normal, true);
}
cur_frm.fields_dict['entries'].grid.set_column_disp(item_flds_pos, (cint(doc.update_stock)==1?true:false));
item_flds_stock = ['serial_no', 'batch_no', 'actual_qty', 'expense_account', 'warehouse']
cur_frm.fields_dict['entries'].grid.set_column_disp(item_flds_stock,
(cint(doc.update_stock)==1 ? true : false));
// India related fields
var cp = wn.control_panel;

View File

@ -83,7 +83,6 @@ class DocType(SellingController):
def on_submit(self):
if cint(self.doc.update_stock) == 1:
self.update_stock_ledger()
self.update_serial_nos()
else:
# Check for Approving Authority
if not self.doc.recurring_id:
@ -111,7 +110,6 @@ class DocType(SellingController):
def on_cancel(self):
if cint(self.doc.update_stock) == 1:
self.update_stock_ledger()
self.update_serial_nos(cancel = True)
sales_com_obj = get_obj(dt = 'Sales Common')
sales_com_obj.check_stop_sales_order(self)
@ -195,7 +193,7 @@ class DocType(SellingController):
pos = get_pos_settings(self.doc.company)
if pos:
if not for_validate:
if not for_validate and not self.doc.customer:
self.doc.customer = pos.customer
self.set_customer_defaults()
@ -266,13 +264,7 @@ class DocType(SellingController):
def get_adj_percent(self, arg=''):
"""Fetch ref rate from item master as per selected price list"""
get_obj('Sales Common').get_adj_percent(self)
def get_rate(self,arg):
"""Get tax rate if account type is tax"""
get_obj('Sales Common').get_rate(arg)
get_obj('Sales Common').get_adj_percent(self)
def get_comm_rate(self, sales_partner):
"""Get Commission rate of Sales Partner"""
@ -965,8 +957,7 @@ def make_delivery_note(source_name, target_doclist=None):
"doctype": "Delivery Note Item",
"field_map": {
"name": "prevdoc_detail_docname",
"parent": "prevdoc_docname",
"parenttype": "prevdoc_doctype",
"parent": "against_sales_invoice",
"serial_no": "serial_no"
},
"postprocess": update_item

View File

@ -2,12 +2,13 @@
{
"creation": "2013-05-24 19:29:05",
"docstatus": 0,
"modified": "2013-09-01 05:26:13",
"modified": "2013-10-11 13:12:38",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_attach": 1,
"allow_import": 1,
"autoname": "naming_series:",
"default_print_format": "Standard",
"doctype": "DocType",
@ -225,7 +226,6 @@
"reqd": 1
},
{
"default": "1.00",
"description": "Rate at which Customer Currency is converted to customer's base currency",
"doctype": "DocField",
"fieldname": "conversion_rate",
@ -411,7 +411,7 @@
"doctype": "DocField",
"fieldname": "other_charges",
"fieldtype": "Table",
"label": "Taxes and Charges1",
"label": "Sales Taxes and Charges",
"oldfieldname": "other_charges",
"oldfieldtype": "Table",
"options": "Sales Taxes and Charges",

View File

@ -641,8 +641,8 @@ class TestSalesInvoice(unittest.TestCase):
return new_si
# if yearly, test 3 repetitions, else test 13 repetitions
count = 3 if no_of_months == 12 else 13
# if yearly, test 1 repetition, else test 5 repetitions
count = 1 if (no_of_months == 12) else 5
for i in xrange(count):
base_si = _test(i)
@ -653,7 +653,7 @@ class TestSalesInvoice(unittest.TestCase):
def test_serialized(self):
from stock.doctype.stock_entry.test_stock_entry import make_serialized_item
from stock.doctype.stock_ledger_entry.stock_ledger_entry import get_serial_nos
from stock.doctype.serial_no.serial_no import get_serial_nos
se = make_serialized_item()
serial_nos = get_serial_nos(se.doclist[1].serial_no)
@ -674,7 +674,7 @@ class TestSalesInvoice(unittest.TestCase):
return si
def test_serialized_cancel(self):
from stock.doctype.stock_ledger_entry.stock_ledger_entry import get_serial_nos
from stock.doctype.serial_no.serial_no import get_serial_nos
si = self.test_serialized()
si.cancel()
@ -686,7 +686,7 @@ class TestSalesInvoice(unittest.TestCase):
"delivery_document_no"))
def test_serialize_status(self):
from stock.doctype.stock_ledger_entry.stock_ledger_entry import SerialNoStatusError, get_serial_nos
from stock.doctype.serial_no.serial_no import SerialNoStatusError, get_serial_nos
from stock.doctype.stock_entry.test_stock_entry import make_serialized_item
se = make_serialized_item()

View File

@ -2,6 +2,9 @@
// License: GNU General Public License v3. See license.txt
//--------- ONLOAD -------------
wn.require("app/js/controllers/accounts.js");
cur_frm.cscript.onload = function(doc, cdt, cdn) {
if(doc.doctype === "Sales Taxes and Charges Master")
erpnext.add_for_territory();
@ -142,6 +145,7 @@ cur_frm.fields_dict['other_charges'].grid.get_field("cost_center").get_query = f
}
}
<<<<<<< HEAD
cur_frm.cscript.account_head = function(doc, cdt, cdn) {
var d = locals[cdt][cdn];
@ -157,6 +161,8 @@ cur_frm.cscript.account_head = function(doc, cdt, cdn) {
refresh_field('account_head',d.name,'other_charges');
}
=======
>>>>>>> f146e8b7f52a3e46e335c0fefd92c347717b370b
cur_frm.cscript.rate = function(doc, cdt, cdn) {
var d = locals[cdt][cdn];
if(!d.charge_type && d.rate) {

View File

@ -6,11 +6,7 @@ import webnotes
from webnotes.utils import cint
from webnotes.model.controller import DocListController
class DocType(DocListController):
def get_rate(self, arg):
from webnotes.model.code import get_obj
return get_obj('Sales Common').get_rate(arg)
class DocType(DocListController):
def validate(self):
if self.doc.is_default == 1:
webnotes.conn.sql("""update `tabSales Taxes and Charges Master` set is_default = 0

View File

@ -15,7 +15,7 @@ def get_companies():
@webnotes.whitelist()
def get_children():
args = webnotes.form_dict
args = webnotes.local.form_dict
ctype, company = args['ctype'], args['comp']
# root

View File

@ -64,10 +64,10 @@ def upload():
data, start_idx = get_data(rows, company_abbr, rows[0][0])
except Exception, e:
err_msg = webnotes.message_log and "<br>".join(webnotes.message_log) or cstr(e)
err_msg = webnotes.local.message_log and "<br>".join(webnotes.local.message_log) or cstr(e)
messages.append("""<p style='color: red'>%s</p>""" % (err_msg or "No message"))
webnotes.errprint(webnotes.getTraceback())
webnotes.message_log = []
webnotes.local.message_log = []
return messages
return import_vouchers(common_values, data, start_idx, rows[0][0])
@ -117,11 +117,11 @@ def import_vouchers(common_values, data, start_idx, import_type):
d = data[i][0]
if import_type == "Voucher Import: Two Accounts" and flt(d.get("amount")) == 0:
webnotes.message_log = ["Amount not specified"]
webnotes.local.message_log = ["Amount not specified"]
raise Exception
elif import_type == "Voucher Import: Multiple Accounts" and \
(flt(d.get("total_debit")) == 0 or flt(d.get("total_credit")) == 0):
webnotes.message_log = ["Total Debit and Total Credit amount can not be zero"]
webnotes.local.message_log = ["Total Debit and Total Credit amount can not be zero"]
raise Exception
else:
d.posting_date = parse_date(d.posting_date)
@ -174,7 +174,7 @@ def import_vouchers(common_values, data, start_idx, import_type):
details.append(detail)
if not details:
webnotes.message_log = ["""No accounts found.
webnotes.local.message_log = ["""No accounts found.
If you entered accounts correctly, please check template once"""]
raise Exception
@ -193,12 +193,12 @@ def import_vouchers(common_values, data, start_idx, import_type):
webnotes.conn.commit()
except Exception, e:
webnotes.conn.rollback()
err_msg = webnotes.message_log and "<br>".join(webnotes.message_log) or cstr(e)
err_msg = webnotes.local.message_log and "<br>".join(webnotes.local.message_log) or cstr(e)
messages.append("""<p style='color: red'>[row #%s] %s failed: %s</p>"""
% ((start_idx + 1) + i, jv.name or "", err_msg or "No message"))
messages.append("<p style='color: red'>All transactions rolled back</p>")
webnotes.errprint(webnotes.getTraceback())
webnotes.message_log = []
webnotes.local.message_log = []
return messages

View File

@ -55,7 +55,7 @@ def get_stock_ledger_entries(filters):
from `tabStock Ledger Entry`"""
if filters.get("company"):
query += """ and company=%(company)s"""
query += """ where company=%(company)s"""
query += " order by item_code desc, warehouse desc, posting_date desc, posting_time desc, name desc"

View File

@ -81,12 +81,12 @@ def get_tax_accounts(item_list, columns):
if account_head not in tax_accounts:
tax_accounts.append(account_head)
invoice = item_tax.setdefault(parent, {})
if item_wise_tax_detail:
try:
item_wise_tax_detail = json.loads(item_wise_tax_detail)
for item, tax_amount in item_wise_tax_detail.items():
invoice.setdefault(item, {})[account_head] = flt(tax_amount)
item_tax.setdefault(parent, {}).setdefault(item, {})[account_head] = \
flt(tax_amount[1])
except ValueError:
continue

View File

@ -9,7 +9,7 @@ def execute(filters=None):
if not filters: filters = {}
columns = get_columns()
last_col = len(columns)
item_list = get_items(filters)
item_tax, tax_accounts = get_tax_accounts(item_list, columns)
@ -21,7 +21,7 @@ def execute(filters=None):
for tax in tax_accounts:
row.append(item_tax.get(d.parent, {}).get(d.item_code, {}).get(tax, 0))
total_tax = sum(row[last_col:])
row += [total_tax, d.amount + total_tax]
@ -71,19 +71,19 @@ def get_tax_accounts(item_list, columns):
tax_details = webnotes.conn.sql("""select parent, account_head, item_wise_tax_detail
from `tabSales Taxes and Charges` where parenttype = 'Sales Invoice'
and docstatus = 1 and ifnull(account_head, '') != ''
and parent in (%s)""" % ', '.join(['%s']*len(item_list)), tuple([item.parent for item in item_list]))
and parent in (%s)""" % ', '.join(['%s']*len(item_list)),
tuple([item.parent for item in item_list]))
for parent, account_head, item_wise_tax_detail in tax_details:
if account_head not in tax_accounts:
tax_accounts.append(account_head)
invoice = item_tax.setdefault(parent, {})
if item_wise_tax_detail:
try:
item_wise_tax_detail = json.loads(item_wise_tax_detail)
for item, tax_amount in item_wise_tax_detail.items():
invoice.setdefault(item, {})[account_head] = flt(tax_amount)
item_tax.setdefault(parent, {}).setdefault(item, {})[account_head] = \
flt(tax_amount[1])
except ValueError:
continue

View File

@ -108,7 +108,7 @@ def get_balance_on(account=None, date=None):
@webnotes.whitelist()
def add_ac(args=None):
if not args:
args = webnotes.form_dict
args = webnotes.local.form_dict
args.pop("cmd")
ac = webnotes.bean(args)
@ -121,7 +121,7 @@ def add_ac(args=None):
@webnotes.whitelist()
def add_cc(args=None):
if not args:
args = webnotes.form_dict
args = webnotes.local.form_dict
args.pop("cmd")
cc = webnotes.bean(args)

View File

@ -8,6 +8,7 @@
wn.provide("erpnext.buying");
wn.require("app/js/transaction.js");
wn.require("app/js/controllers/accounts.js");
erpnext.buying.BuyingController = erpnext.TransactionController.extend({
onload: function() {
@ -108,8 +109,7 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
var item = wn.model.get_doc(cdt, cdn);
if(item.item_code) {
if(!this.validate_company_and_party("supplier")) {
item.item_code = null;
refresh_field("item_code", item.name, item.parentfield);
cur_frm.fields_dict[me.frm.cscript.fname].grid.grid_rows[item.idx - 1].remove();
} else {
return this.frm.call({
method: "buying.utils.get_item_details",

View File

@ -10,7 +10,6 @@ from webnotes import msgprint, _
from buying.utils import get_last_purchase_details
sql = webnotes.conn.sql
from controllers.buying_controller import BuyingController
class DocType(BuyingController):
@ -23,27 +22,20 @@ class DocType(BuyingController):
msgprint(_("You need to put at least one item in the item table."), raise_exception=True)
def get_supplier_details(self, name = ''):
details = sql("select supplier_name,address from `tabSupplier` where name = '%s' and docstatus != 2" %(name), as_dict = 1)
details = webnotes.conn.sql("select supplier_name,address from `tabSupplier` where name = '%s' and docstatus != 2" %(name), as_dict = 1)
if details:
ret = {
'supplier_name' : details and details[0]['supplier_name'] or '',
'supplier_address' : details and details[0]['address'] or ''
}
# ********** get primary contact details (this is done separately coz. , in case there is no primary contact thn it would not be able to fetch customer details in case of join query)
contact_det = sql("select contact_name, contact_no, email_id from `tabContact` where supplier = '%s' and is_supplier = 1 and is_primary_contact = 'Yes' and docstatus != 2" %(name), as_dict = 1)
contact_det = webnotes.conn.sql("select contact_name, contact_no, email_id from `tabContact` where supplier = '%s' and is_supplier = 1 and is_primary_contact = 'Yes' and docstatus != 2" %(name), as_dict = 1)
ret['contact_person'] = contact_det and contact_det[0]['contact_name'] or ''
return ret
else:
msgprint("Supplier : %s does not exists" % (name))
raise Exception
# Get Available Qty at Warehouse
def get_bin_details( self, arg = ''):
arg = eval(arg)
bin = sql("select projected_qty from `tabBin` where item_code = %s and warehouse = %s", (arg['item_code'], arg['warehouse']), as_dict=1)
ret = { 'projected_qty' : bin and flt(bin[0]['projected_qty']) or 0 }
return ret
def update_last_purchase_rate(self, obj, is_submit):
"""updates last_purchase_rate in item table for each item"""
@ -70,7 +62,7 @@ class DocType(BuyingController):
# update last purchsae rate
if last_purchase_rate:
sql("update `tabItem` set last_purchase_rate = %s where name = %s",
webnotes.conn.sql("update `tabItem` set last_purchase_rate = %s where name = %s",
(flt(last_purchase_rate),d.item_code))
def get_last_purchase_rate(self, obj):
@ -107,7 +99,7 @@ class DocType(BuyingController):
raise Exception
# udpate with latest quantities
bin = sql("select projected_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
bin = webnotes.conn.sql("select projected_qty from `tabBin` where item_code = %s and warehouse = %s", (d.item_code, d.warehouse), as_dict = 1)
f_lst ={'projected_qty': bin and flt(bin[0]['projected_qty']) or 0, 'ordered_qty': 0, 'received_qty' : 0}
if d.doctype == 'Purchase Receipt Item':
@ -116,7 +108,7 @@ class DocType(BuyingController):
if d.fields.has_key(x):
d.fields[x] = f_lst[x]
item = sql("select is_stock_item, is_purchase_item, is_sub_contracted_item, end_of_life from tabItem where name=%s",
item = webnotes.conn.sql("select is_stock_item, is_purchase_item, is_sub_contracted_item, end_of_life from tabItem where name=%s",
d.item_code)
if not item:
msgprint("Item %s does not exist in Item Master." % cstr(d.item_code), raise_exception=True)
@ -139,7 +131,7 @@ class DocType(BuyingController):
# if is not stock item
f = [d.schedule_date, d.item_code, d.description]
ch = sql("select is_stock_item from `tabItem` where name = '%s'"%d.item_code)
ch = webnotes.conn.sql("select is_stock_item from `tabItem` where name = '%s'"%d.item_code)
if ch and ch[0][0] == 'Yes':
# check for same items
@ -165,18 +157,18 @@ class DocType(BuyingController):
# but if in Material Request uom KG it can change in PO
get_qty = (transaction == 'Material Request - Purchase Order') and 'qty * conversion_factor' or 'qty'
qty = sql("select sum(%s) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% ( get_qty, curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name))
qty = webnotes.conn.sql("select sum(%s) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% ( get_qty, curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name))
qty = qty and flt(qty[0][0]) or 0
# get total qty of ref doctype
#--------------------
max_qty = sql("select qty from `tab%s` where name = '%s' and docstatus = 1"% (ref_doc_tname, ref_tab_dn))
max_qty = webnotes.conn.sql("select qty from `tab%s` where name = '%s' and docstatus = 1"% (ref_doc_tname, ref_tab_dn))
max_qty = max_qty and flt(max_qty[0][0]) or 0
return cstr(qty)+'~~~'+cstr(max_qty)
def check_for_stopped_status(self, doctype, docname):
stopped = sql("select name from `tab%s` where name = '%s' and status = 'Stopped'" %
stopped = webnotes.conn.sql("select name from `tab%s` where name = '%s' and status = 'Stopped'" %
( doctype, docname))
if stopped:
msgprint("One cannot do any transaction against %s : %s, it's status is 'Stopped'" %
@ -184,7 +176,7 @@ class DocType(BuyingController):
def check_docstatus(self, check, doctype, docname , detail_doctype = ''):
if check == 'Next':
submitted = sql("""select t1.name from `tab%s` t1,`tab%s` t2
submitted = webnotes.conn.sql("""select t1.name from `tab%s` t1,`tab%s` t2
where t1.name = t2.parent and t2.prevdoc_docname = %s and t1.docstatus = 1"""
% (doctype, detail_doctype, '%s'), docname)
if submitted:
@ -192,23 +184,8 @@ class DocType(BuyingController):
+ _(" has already been submitted."), raise_exception=1)
if check == 'Previous':
submitted = sql("""select name from `tab%s`
submitted = webnotes.conn.sql("""select name from `tab%s`
where docstatus = 1 and name = %s"""% (doctype, '%s'), docname)
if not submitted:
msgprint(cstr(doctype) + ": " + cstr(submitted[0][0])
+ _(" not submitted"), raise_exception=1)
def get_rate(self, arg, obj):
arg = eval(arg)
rate = sql("select account_type, tax_rate from `tabAccount` where name = %s"
, (arg['account_head']), as_dict=1)
return {'rate': rate and (rate[0]['account_type'] == 'Tax' \
and not arg['charge_type'] == 'Actual') and flt(rate[0]['tax_rate']) or 0 }
def get_prevdoc_date(self, obj):
for d in getlist(obj.doclist, obj.fname):
if d.prevdoc_doctype and d.prevdoc_docname:
dt = sql("select transaction_date from `tab%s` where name = %s"
% (d.prevdoc_doctype, '%s'), (d.prevdoc_docname))
d.prevdoc_date = dt and dt[0][0].strftime('%Y-%m-%d') or ''

View File

@ -10,6 +10,7 @@ cur_frm.cscript.other_fname = "purchase_tax_details";
wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js');
wn.require('app/utilities/doctype/sms_control/sms_control.js');
wn.require('app/buying/doctype/purchase_common/purchase_common.js');
wn.require('app/accounts/doctype/sales_invoice/pos.js');
erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend({
refresh: function(doc, cdt, cdn) {
@ -184,9 +185,9 @@ cur_frm.pformat.indent_no = function(doc, cdt, cdn){
if(cl[i].prevdoc_doctype == 'Material Request' && cl[i].prevdoc_docname && prevdoc_list.indexOf(cl[i].prevdoc_docname) == -1) {
prevdoc_list.push(cl[i].prevdoc_docname);
if(prevdoc_list.length ==1)
out += make_row(cl[i].prevdoc_doctype, cl[i].prevdoc_docname, cl[i].prevdoc_date,0);
out += make_row(cl[i].prevdoc_doctype, cl[i].prevdoc_docname, null,0);
else
out += make_row('', cl[i].prevdoc_docname, cl[i].prevdoc_date,0);
out += make_row('', cl[i].prevdoc_docname,null,0);
}
}
}

View File

@ -9,7 +9,6 @@ from webnotes.model.bean import getlist
from webnotes.model.code import get_obj
from webnotes import msgprint
sql = webnotes.conn.sql
from controllers.buying_controller import BuyingController
class DocType(BuyingController):
@ -42,7 +41,6 @@ class DocType(BuyingController):
pc_obj = get_obj(dt='Purchase Common')
pc_obj.validate_for_items(self)
pc_obj.get_prevdoc_date(self)
self.check_for_stopped_status(pc_obj)
self.validate_uom_is_integer("uom", "qty")
@ -66,10 +64,6 @@ class DocType(BuyingController):
}
})
# get available qty at warehouse
def get_bin_details(self, arg = ''):
return get_obj(dt='Purchase Common').get_bin_details(arg)
def get_schedule_dates(self):
for d in getlist(self.doclist, 'po_details'):
if d.prevdoc_detail_docname and not d.schedule_date:
@ -133,8 +127,8 @@ class DocType(BuyingController):
update_bin(args)
def check_modified_date(self):
mod_db = sql("select modified from `tabPurchase Order` where name = '%s'" % self.doc.name)
date_diff = sql("select TIMEDIFF('%s', '%s')" % ( mod_db[0][0],cstr(self.doc.modified)))
mod_db = webnotes.conn.sql("select modified from `tabPurchase Order` where name = '%s'" % self.doc.name)
date_diff = webnotes.conn.sql("select TIMEDIFF('%s', '%s')" % ( mod_db[0][0],cstr(self.doc.modified)))
if date_diff and date_diff[0][0]:
msgprint(cstr(self.doc.doctype) +" => "+ cstr(self.doc.name) +" has been modified. Please Refresh. ")
@ -173,7 +167,7 @@ class DocType(BuyingController):
pc_obj.check_docstatus(check = 'Next', doctype = 'Purchase Receipt', docname = self.doc.name, detail_doctype = 'Purchase Receipt Item')
# Check if Purchase Invoice has been submitted against current Purchase Order
submitted = sql("select t1.name from `tabPurchase Invoice` t1,`tabPurchase Invoice Item` t2 where t1.name = t2.parent and t2.purchase_order = '%s' and t1.docstatus = 1" % self.doc.name)
submitted = webnotes.conn.sql("select t1.name from `tabPurchase Invoice` t1,`tabPurchase Invoice Item` t2 where t1.name = t2.parent and t2.purchase_order = '%s' and t1.docstatus = 1" % self.doc.name)
if submitted:
msgprint("Purchase Invoice : " + cstr(submitted[0][0]) + " has already been submitted !")
raise Exception
@ -186,9 +180,6 @@ class DocType(BuyingController):
def on_update(self):
pass
def get_rate(self,arg):
return get_obj('Purchase Common').get_rate(arg,self)
@webnotes.whitelist()
def make_purchase_receipt(source_name, target_doclist=None):
from webnotes.model.mapper import get_mapped_doclist

View File

@ -2,12 +2,13 @@
{
"creation": "2013-05-21 16:16:39",
"docstatus": 0,
"modified": "2013-09-12 18:34:54",
"modified": "2013-10-02 14:24:49",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_attach": 1,
"allow_import": 1,
"autoname": "naming_series:",
"doctype": "DocType",
"document_type": "Transaction",
@ -132,7 +133,6 @@
"fieldtype": "Date",
"in_filter": 1,
"label": "Purchase Order Date",
"no_copy": 1,
"oldfieldname": "transaction_date",
"oldfieldtype": "Date",
"reqd": 1,

View File

@ -98,11 +98,11 @@ class TestPurchaseOrder(unittest.TestCase):
self.assertEquals(len(po.doclist.get({"parentfield": "po_raw_material_details"})), 2)
def test_warehouse_company_validation(self):
from controllers.buying_controller import WrongWarehouseCompany
from stock.utils import InvalidWarehouseCompany
po = webnotes.bean(copy=test_records[0])
po.doc.company = "_Test Company 1"
po.doc.conversion_rate = 0.0167
self.assertRaises(WrongWarehouseCompany, po.insert)
self.assertRaises(InvalidWarehouseCompany, po.insert)
def test_uom_integer_validation(self):
from utilities.transaction_base import UOMMustBeIntegerError

View File

@ -2,7 +2,7 @@
{
"creation": "2013-05-24 19:29:06",
"docstatus": 0,
"modified": "2013-08-07 14:44:12",
"modified": "2013-10-10 17:01:57",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -306,21 +306,6 @@
"search_index": 1,
"width": "120px"
},
{
"doctype": "DocField",
"fieldname": "prevdoc_date",
"fieldtype": "Date",
"hidden": 1,
"in_filter": 1,
"in_list_view": 0,
"label": "Material Request Date",
"no_copy": 1,
"oldfieldname": "prevdoc_date",
"oldfieldtype": "Date",
"print_hide": 1,
"read_only": 1,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "prevdoc_detail_docname",

View File

@ -9,7 +9,6 @@ from webnotes.utils import cint
from webnotes import msgprint, _
from webnotes.model.doc import make_autoname
sql = webnotes.conn.sql
from utilities.transaction_base import TransactionBase
@ -29,7 +28,7 @@ class DocType(TransactionBase):
self.doc.name = make_autoname(self.doc.naming_series + '.#####')
def update_credit_days_limit(self):
sql("""update tabAccount set credit_days = %s where name = %s""",
webnotes.conn.sql("""update tabAccount set credit_days = %s where name = %s""",
(cint(self.doc.credit_days), self.doc.name + " - " + self.get_company_abbr()))
def on_update(self):
@ -43,7 +42,7 @@ class DocType(TransactionBase):
self.update_credit_days_limit()
def get_payables_group(self):
g = sql("select payables_group from tabCompany where name=%s", self.doc.company)
g = webnotes.conn.sql("select payables_group from tabCompany where name=%s", self.doc.company)
g = g and g[0][0] or ''
if not g:
msgprint("Update Company master, assign a default group for Payables")
@ -65,14 +64,14 @@ class DocType(TransactionBase):
msgprint(_("Created Group ") + ac)
def get_company_abbr(self):
return sql("select abbr from tabCompany where name=%s", self.doc.company)[0][0]
return webnotes.conn.sql("select abbr from tabCompany where name=%s", self.doc.company)[0][0]
def get_parent_account(self, abbr):
if (not self.doc.supplier_type):
msgprint("Supplier Type is mandatory")
raise Exception
if not sql("select name from tabAccount where name=%s and debit_or_credit = 'Credit' and ifnull(is_pl_account, 'No') = 'No'", (self.doc.supplier_type + " - " + abbr)):
if not webnotes.conn.sql("select name from tabAccount where name=%s and debit_or_credit = 'Credit' and ifnull(is_pl_account, 'No') = 'No'", (self.doc.supplier_type + " - " + abbr)):
# if not group created , create it
self.add_account(self.doc.supplier_type, self.get_payables_group(), abbr)
@ -90,7 +89,7 @@ class DocType(TransactionBase):
abbr = self.get_company_abbr()
parent_account = self.get_parent_account(abbr)
if not sql("select name from tabAccount where name=%s", (self.doc.name + " - " + abbr)):
if not webnotes.conn.sql("select name from tabAccount where name=%s", (self.doc.name + " - " + abbr)):
ac_bean = webnotes.bean({
"doctype": "Account",
'account_name': self.doc.name,
@ -121,15 +120,15 @@ class DocType(TransactionBase):
def get_contacts(self,nm):
if nm:
contact_details =webnotes.conn.convert_to_lists(sql("select name, CONCAT(IFNULL(first_name,''),' ',IFNULL(last_name,'')),contact_no,email_id from `tabContact` where supplier = '%s'"%nm))
contact_details =webnotes.conn.convert_to_lists(webnotes.conn.sql("select name, CONCAT(IFNULL(first_name,''),' ',IFNULL(last_name,'')),contact_no,email_id from `tabContact` where supplier = '%s'"%nm))
return contact_details
else:
return ''
def delete_supplier_address(self):
for rec in sql("select * from `tabAddress` where supplier=%s", (self.doc.name,), as_dict=1):
sql("delete from `tabAddress` where name=%s",(rec['name']))
for rec in webnotes.conn.sql("select * from `tabAddress` where supplier=%s", (self.doc.name,), as_dict=1):
webnotes.conn.sql("delete from `tabAddress` where name=%s",(rec['name']))
def delete_supplier_contact(self):
for contact in webnotes.conn.sql_list("""select name from `tabContact`
@ -138,7 +137,7 @@ class DocType(TransactionBase):
def delete_supplier_account(self):
"""delete supplier's ledger if exist and check balance before deletion"""
acc = sql("select name from `tabAccount` where master_type = 'Supplier' \
acc = webnotes.conn.sql("select name from `tabAccount` where master_type = 'Supplier' \
and master_name = %s and docstatus < 2", self.doc.name)
if acc:
from webnotes.model import delete_doc
@ -161,7 +160,7 @@ class DocType(TransactionBase):
('Purchase Receipt', 'supplier'),
('Serial No', 'supplier')]
for rec in update_fields:
sql("update `tab%s` set supplier_name = %s where `%s` = %s" % \
webnotes.conn.sql("update `tab%s` set supplier_name = %s where `%s` = %s" % \
(rec[0], '%s', rec[1], '%s'), (new, old))
for account in webnotes.conn.sql("""select name, account_name from

View File

@ -9,6 +9,7 @@ cur_frm.cscript.other_fname = "purchase_tax_details";
// attach required files
wn.require('app/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js');
wn.require('app/buying/doctype/purchase_common/purchase_common.js');
wn.require('app/accounts/doctype/sales_invoice/pos.js');
erpnext.buying.SupplierQuotationController = erpnext.buying.BuyingController.extend({
refresh: function() {

View File

@ -54,7 +54,6 @@ class DocType(BuyingController):
def validate_common(self):
pc = get_obj('Purchase Common')
pc.validate_for_items(self)
pc.get_prevdoc_date(self)
@webnotes.whitelist()
def make_purchase_order(source_name, target_doclist=None):

View File

@ -2,12 +2,13 @@
{
"creation": "2013-05-21 16:16:45",
"docstatus": 0,
"modified": "2013-08-09 14:45:58",
"modified": "2013-10-02 14:24:44",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_attach": 1,
"allow_import": 1,
"autoname": "naming_series:",
"doctype": "DocType",
"document_type": "Transaction",

View File

@ -2,7 +2,7 @@
{
"creation": "2013-05-22 12:43:10",
"docstatus": 0,
"modified": "2013-08-07 14:44:18",
"modified": "2013-10-10 17:02:11",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -259,21 +259,6 @@
"search_index": 1,
"width": "120px"
},
{
"doctype": "DocField",
"fieldname": "prevdoc_date",
"fieldtype": "Date",
"hidden": 1,
"in_filter": 1,
"in_list_view": 0,
"label": "Material Request Date",
"no_copy": 1,
"oldfieldname": "prevdoc_date",
"oldfieldtype": "Date",
"print_hide": 1,
"read_only": 1,
"search_index": 0
},
{
"doctype": "DocField",
"fieldname": "prevdoc_detail_docname",

View File

@ -145,6 +145,11 @@ wn.module_page["Buying"] = [
route: "query-report/Purchase Order Trends",
doctype: "Purchase Order"
},
{
"label":wn._("Supplier Addresses And Contacts"),
route: "query-report/Supplier Addresses and Contacts",
doctype: "Supplier"
},
]
}
]

View File

@ -0,0 +1,22 @@
[
{
"creation": "2013-10-09 10:38:40",
"docstatus": 0,
"modified": "2013-10-09 10:53:52",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"doctype": "Report",
"is_standard": "Yes",
"name": "__common__",
"query": "SELECT\n `tabSupplier`.name as \"Supplier:Link/Supplier:120\",\n\t`tabSupplier`.supplier_name as \"Supplier Name::120\",\n\t`tabSupplier`.supplier_type as \"Supplier Type:Link/Supplier Type:120\",\n\tconcat_ws(', ', \n\t\ttrim(',' from `tabAddress`.address_line1), \n\t\ttrim(',' from tabAddress.address_line2), \n\t\ttabAddress.state, tabAddress.pincode, tabAddress.country\n\t) as 'Address::180',\n concat_ws(', ', `tabContact`.first_name, `tabContact`.last_name) as 'Contact Name::180',\n\t`tabContact`.phone as \"Phone\",\n\t`tabContact`.mobile_no as \"Mobile No\",\n\t`tabContact`.email_id as \"Email Id::120\",\n\t`tabContact`.is_primary_contact as \"Is Primary Contact::120\"\nFROM\n\t`tabSupplier`\n\tleft join `tabAddress` on (\n\t\t`tabAddress`.supplier=`tabSupplier`.name\n\t)\n\tleft join `tabContact` on (\n\t\t`tabContact`.supplier=`tabSupplier`.name\n\t)\nWHERE\n\t`tabSupplier`.docstatus<2\nORDER BY\n\t`tabSupplier`.name asc",
"ref_doctype": "Supplier",
"report_name": "Supplier Addresses and Contacts",
"report_type": "Query Report"
},
{
"doctype": "Report",
"name": "Supplier Addresses and Contacts"
}
]

View File

@ -65,7 +65,7 @@ def _get_basic_details(args, item_bean):
out = webnotes._dict({
"description": item.description_html or item.description,
"qty": 0.0,
"qty": 1.0,
"uom": item.stock_uom,
"conversion_factor": 1.0,
"warehouse": args.warehouse or item.default_warehouse,

View File

@ -52,7 +52,7 @@ class AccountsController(TransactionBase):
msgprint(_("Account for this ") + fieldname + _(" has been freezed. ") +
self.doc.doctype + _(" can not be made."), raise_exception=1)
def set_price_list_currency(self, buying_or_selling):
def set_price_list_currency(self, buying_or_selling, for_validate=False):
if self.meta.get_field("currency"):
company_currency = get_company_currency(self.doc.company)
@ -60,14 +60,13 @@ class AccountsController(TransactionBase):
fieldname = "selling_price_list" if buying_or_selling.lower() == "selling" \
else "buying_price_list"
if self.meta.get_field(fieldname) and self.doc.fields.get(fieldname):
if not self.doc.price_list_currency:
self.doc.price_list_currency = webnotes.conn.get_value("Price List",
self.doc.fields.get(fieldname), "currency")
self.doc.price_list_currency = webnotes.conn.get_value("Price List",
self.doc.fields.get(fieldname), "currency")
if self.doc.price_list_currency == company_currency:
self.doc.plc_conversion_rate = 1.0
elif not self.doc.plc_conversion_rate:
elif not self.doc.plc_conversion_rate or not for_validate:
self.doc.plc_conversion_rate = self.get_exchange_rate(
self.doc.price_list_currency, company_currency)
@ -77,7 +76,7 @@ class AccountsController(TransactionBase):
self.doc.conversion_rate = self.doc.plc_conversion_rate
elif self.doc.currency == company_currency:
self.doc.conversion_rate = 1.0
elif not self.doc.conversion_rate:
elif not self.doc.conversion_rate or not for_validate:
self.doc.conversion_rate = self.get_exchange_rate(self.doc.currency,
company_currency)
@ -423,3 +422,7 @@ class AccountsController(TransactionBase):
self._abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr")
return self._abbr
@webnotes.whitelist()
def get_tax_rate(account_head):
return webnotes.conn.get_value("Account", account_head, "tax_rate")

View File

@ -2,7 +2,7 @@
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import webnotes
import webnotes, json
from webnotes import _, msgprint
from webnotes.utils import flt, _round
@ -11,9 +11,8 @@ from setup.utils import get_company_currency
from controllers.stock_controller import StockController
class WrongWarehouseCompany(Exception): pass
class BuyingController(StockController):
def onload_post_render(self):
# contact, address, item details
self.set_missing_values()
@ -24,13 +23,13 @@ class BuyingController(StockController):
self.doc.supplier_name = webnotes.conn.get_value("Supplier",
self.doc.supplier, "supplier_name")
self.validate_stock_or_nonstock_items()
self.validate_warehouse_belongs_to_company()
self.validate_warehouse()
def set_missing_values(self, for_validate=False):
super(BuyingController, self).set_missing_values(for_validate)
self.set_supplier_from_item_default()
self.set_price_list_currency("Buying")
self.set_price_list_currency("Buying", for_validate)
# set contact and address details for supplier, if they are not mentioned
if self.doc.supplier and not (self.doc.contact_person and self.doc.supplier_address):
@ -49,17 +48,20 @@ class BuyingController(StockController):
if supplier:
self.doc.supplier = supplier
break
def validate_warehouse(self):
from stock.utils import validate_warehouse_user, validate_warehouse_company
warehouses = list(set([d.warehouse for d in
self.doclist.get({"doctype": self.tname}) if d.warehouse]))
for w in warehouses:
validate_warehouse_user(w)
validate_warehouse_company(w, self.doc.company)
def get_purchase_tax_details(self):
self.doclist = self.doc.clear_table(self.doclist, "purchase_tax_details")
self.set_taxes("purchase_tax_details", "purchase_other_charges")
def validate_warehouse_belongs_to_company(self):
for warehouse, company in webnotes.conn.get_values("Warehouse",
self.doclist.get_distinct_values("warehouse"), "company").items():
if company and company != self.doc.company:
webnotes.msgprint(_("Company mismatch for Warehouse") + (": %s" % (warehouse,)),
raise_exception=WrongWarehouseCompany)
def validate_stock_or_nonstock_items(self):
if not self.get_stock_items():

View File

@ -14,13 +14,16 @@ class SellingController(StockController):
def onload_post_render(self):
# contact, address, item details and pos details (if applicable)
self.set_missing_values()
def get_sender(self, comm):
return webnotes.conn.get_value('Sales Email Settings', None, 'email_id')
def set_missing_values(self, for_validate=False):
super(SellingController, self).set_missing_values(for_validate)
# set contact and address details for customer, if they are not mentioned
self.set_missing_lead_customer_details()
self.set_price_list_and_item_details()
self.set_price_list_and_item_details(for_validate)
if self.doc.fields.get("__islocal"):
self.set_taxes("other_charges", "charge")
@ -38,8 +41,8 @@ class SellingController(StockController):
if not self.doc.fields.get(fieldname) and self.meta.get_field(fieldname):
self.doc.fields[fieldname] = val
def set_price_list_and_item_details(self):
self.set_price_list_currency("Selling")
def set_price_list_and_item_details(self, for_validate=False):
self.set_price_list_currency("Selling", for_validate)
self.set_missing_item_details(get_item_details)
def get_other_charges(self):
@ -233,34 +236,4 @@ class SellingController(StockController):
self.doc.order_type = "Sales"
elif self.doc.order_type not in valid_types:
msgprint(_(self.meta.get_label("order_type")) + " " +
_("must be one of") + ": " + comma_or(valid_types),
raise_exception=True)
def update_serial_nos(self, cancel=False):
from stock.doctype.stock_ledger_entry.stock_ledger_entry import update_serial_nos_after_submit, get_serial_nos
update_serial_nos_after_submit(self, self.doc.doctype, self.fname)
update_serial_nos_after_submit(self, self.doc.doctype, "packing_details")
for table_fieldname in (self.fname, "packing_details"):
for d in self.doclist.get({"parentfield": table_fieldname}):
for serial_no in get_serial_nos(d.serial_no):
sr = webnotes.bean("Serial No", serial_no)
if cancel:
sr.doc.status = "Available"
for fieldname in ("warranty_expiry_date", "delivery_document_type",
"delivery_document_no", "delivery_date", "delivery_time", "customer",
"customer_name"):
sr.doc.fields[fieldname] = None
else:
sr.doc.delivery_document_type = self.doc.doctype
sr.doc.delivery_document_no = self.doc.name
sr.doc.delivery_date = self.doc.posting_date
sr.doc.delivery_time = self.doc.posting_time
sr.doc.customer = self.doc.customer
sr.doc.customer_name = self.doc.customer_name
if sr.doc.warranty_period:
sr.doc.warranty_expiry_date = add_days(cstr(self.doc.posting_date),
cint(sr.doc.warranty_period))
sr.doc.status = 'Delivered'
sr.save()
_("must be one of") + ": " + comma_or(valid_types), raise_exception=True)

View File

@ -8,6 +8,51 @@ from webnotes import msgprint
from webnotes.model.controller import DocListController
status_map = {
"Contact": [
["Replied", "communication_sent"],
["Open", "communication_received"]
],
"Job Applicant": [
["Replied", "communication_sent"],
["Open", "communication_received"]
],
"Lead": [
["Replied", "communication_sent"],
["Converted", "has_customer"],
["Opportunity", "has_opportunity"],
["Open", "communication_received"],
],
"Opportunity": [
["Draft", None],
["Submitted", "eval:self.doc.docstatus==1"],
["Lost", "eval:self.doc.status=='Lost'"],
["Quotation", "has_quotation"],
["Replied", "communication_sent"],
["Cancelled", "eval:self.doc.docstatus==2"],
["Open", "communication_received"],
],
"Quotation": [
["Draft", None],
["Submitted", "eval:self.doc.docstatus==1"],
["Lost", "eval:self.doc.status=='Lost'"],
["Ordered", "has_sales_order"],
["Replied", "communication_sent"],
["Cancelled", "eval:self.doc.docstatus==2"],
["Open", "communication_received"],
],
"Sales Order": [
["Draft", None],
["Submitted", "eval:self.doc.docstatus==1"],
["Stopped", "eval:self.doc.status=='Stopped'"],
["Cancelled", "eval:self.doc.docstatus==2"],
],
"Support Ticket": [
["Replied", "communication_sent"],
["Open", "communication_received"]
],
}
class StatusUpdater(DocListController):
"""
Updates the status of the calling records
@ -20,6 +65,45 @@ class StatusUpdater(DocListController):
self.update_qty()
self.validate_qty()
def set_status(self, update=False):
if self.doc.get("__islocal"):
return
if self.doc.doctype in status_map:
sl = status_map[self.doc.doctype][:]
sl.reverse()
for s in sl:
if not s[1]:
self.doc.status = s[0]
break
elif s[1].startswith("eval:"):
if eval(s[1][5:]):
self.doc.status = s[0]
break
elif getattr(self, s[1])():
self.doc.status = s[0]
break
if update:
webnotes.conn.set_value(self.doc.doctype, self.doc.name, "status", self.doc.status)
def on_communication(self):
self.communication_set = True
self.set_status(update=True)
del self.communication_set
def communication_received(self):
if getattr(self, "communication_set", False):
last_comm = self.doclist.get({"doctype":"Communication"})
if last_comm:
return last_comm[-1].sent_or_received == "Received"
def communication_sent(self):
if getattr(self, "communication_set", False):
last_comm = self.doclist.get({"doctype":"Communication"})
if last_comm:
return last_comm[-1].sent_or_received == "Sent"
def validate_qty(self):
"""
Validates qty at row level

View File

@ -13,33 +13,34 @@ You can make a Sales Invoice of type POS by checking on “Is POS”. When you c
- Update Stock: If this is checked, Stock Ledger Entries will be made when you “Submit” this Sales Invoice thereby eliminating the need for a separate Delivery Note.
- In your Items table, update inventory information like Warehouse (saved as default), Serial Number, or Batch Number if applicable.
- Update Payment Details like your Bank / Cash Account, paid amount etc.
- Update Payment Details like your Bank / Cash Account, Paid amount etc.
- If you are writing off certain amount. For example when you receive extra cash as a result of not having exact denomination of change, check on Write off Outstanding Amount and set the Account.
Setup [POS Setting](docs.user.setup.pos_setting.html)
#### Enable POS View
Sales Invoice has 2 different interfaces, Invoice View and POS View. The current view used by most users is the Invoice View. This view is preferred by non-retailing companies.The POS view is used by retailing companies. For retailers it is very important to provide bill or sales invoice at the point of sale. Their customers cannot wait to receive the bill by post. The customers want an immediate bill for the payment which they make. In such cases, the POS View is preferred.
- Every Sales & Purchase documents has 2 different interfaces, Invoice View and POS View. The current view used by most users is the Invoice View. This view is preferred by non-retailing companies.The POS view is used by retailing companies. For retailers it is very important to provide bill or sales invoice at the point of sale. Their customers cannot wait to receive the bill by post. The customers want an immediate bill for the payment which they make. In such cases, the POS View is preferred.
> Setup > Show/Hide Features
![POS View](img/pos-features-setup.png)
- Setup [POS Setting](docs.user.setup.pos_setting.html)
### Adding an Item
At the billing counter, the retailer needs to select Items which the consumer buys. In the POS interface you can select an Item by two methods. One, is by clicking on the Item image and the other, is through the Barcode.
At the billing counter, the retailer needs to select Items which the consumer buys. In the POS interface you can select an Item by two methods. One, is by clicking on the Item image and the other, is through the Barcode / Serial No.
**Select Item** - To select a product click on the Item image and add it into the cart. A cart is an area that prepares a customer for checkout by allowing to edit product information, adjust taxes and add discounts.
**Barcode** - A Barcode is an optical machine-readable representation of data relating to the object to which it is attached. Enter Barcode in the barcode box and pause for a second. The Item will be automatically added to the cart.
**Barcode / Serial No** - A Barcode / Serial No is an optical machine-readable representation of data relating to the object to which it is attached. Enter Barcode / Serial No in the box as shown in the image below and pause for a second, the item will be automatically added to the cart.
![POS](img/pos-add-item.png)
> Tip: To change the quantity of an Item, enter your desired quantity in the quantity box. These are mostly used if the same Item is purchased in bulk.
If your product list is very long use the universal search field, to type the product name and select faster.
If your product list is very long use the Search field, type the product name in Search box.
### Removing an Item
@ -48,7 +49,7 @@ There are two ways to remove an Item.
- Select an Item by clicking on the row of that Item from Item cart. Then click on “Del” button. OR
- Type 0 in the select quantity field to delete the record.
- Enter 0(zero) quantity of any item to delete that item.
To remove multiple Items together, select multiple rows & click on “Del” button.
@ -62,11 +63,11 @@ After all the Items and their quantities are added into the cart, you are ready
1. Click on “Make Payment” to get the Payment window.
1. Select your “Mode of Payment”.
1. Click on “Pay” button to Save the Sales Invoice.
1. Click on “Pay” button to Save the document.
![POS Payment](img/pos-make-payment.png)
Submit the document to finalise the record. After the Invoice is submitted, you can either print an invoice or email it directly to the customer.
Submit the document to finalise the record. After the document is submitted, you can either print or email it directly to the customer.
#### Accounting entries (GL Entry) for a Point of Sale:

View File

@ -20,7 +20,15 @@ You can create a new Supplier via:
> Tip: When you select a Supplier in any transaction, one Contact and Address gets pre-selected. This is the “Default Contact or Address”. So make sure you set your defaults correctly!
### Integration with Accounts
In ERPNext, there is a separate Account record for each Supplier, of Each company.
When you create a new Supplier, ERPNext will automatically create an Account Ledger for the Supplier under “Accounts Receivable” in the Company set in the Supplier record.
> Advanced Tip: If you want to change the Account Group under which the Supplier Account is created, you can set it in the Company master.
If you want to create an Account in another Company, just change the Company value and “Save” the Supplier again.
> Buying > Contact > New Contact

View File

@ -3,9 +3,11 @@
"_label": "Supplier Type"
}
---
A supplier may be distinguished from a contractor or subcontractor, who commonly adds specialized input to deliverables. A supplier is also known as a vendor. There are different types of suppliers based on their goods and products.
Based on what the suppliers supply, they are classified into different categories called Supplier Type.
There can be different types of suppliers. You can create your own category of Supplier Type.
ERPNext allows you to create your own categories of suppliers. These categories are known as Supplier Type. For Example, if your suppliers are mainly pharmaceutical companies and FMCG distributors, You can create a new Type for them and name them accordingly.
Based on what the suppliers supply, they are classified into different categories called Supplier Type. There can be different types of suppliers. You can create your own category of Supplier Type.
> Buying > Supplier Type > New Supplier Type

View File

@ -3,6 +3,7 @@
"_label": "User Guide",
"_toc": [
"docs.user.intro",
"docs.user.five_day_setup",
"docs.user.implement",
"docs.user.setup",
"docs.user.selling",
@ -17,7 +18,7 @@
"docs.user.tools",
"docs.user.customize",
"docs.user.knowledge"
],
],
"_no_toc": 1
}
---
@ -29,6 +30,12 @@ Contents
1. [Open Source](docs.user.intro.open_source.html)
1. [Ways to get started](docs.user.intro.try.html)
1. [Getting Help](docs.user.help.html)
1. [Five-Day-Setup](docs.user.five_day_setup.html)
1. [Day-1: Setup Customer,Item, and Supplier](docs.user.five_day_setup.day_1.html)
1. [Day-2: Setup Chart of Accounts, Opening Accounts, and HR](docs.user.five_day_setup.day_2.html)
1. [Day-3: Sales Cycle and Purchase Cycle](docs.user.five_day_setup.day_3.html)
1. [Day-4: Manufacturing Cycle and Accounting Reports](docs.user.five_day_setup.day_4.html)
1. [Day-5: Projects, Calendar, and Website](docs.user.five_day_setup.day_5.html)
1. [Implementation](docs.user.implement.html)
1. [Implementation Strategy](docs.user.implement.strategy.html)
1. [Concepts](docs.user.implement.concepts.html)
@ -151,3 +158,6 @@ Contents
1. [Fiscal Year](docs.user.knowledge.fiscal_year.html)
1. [Accounting Knowledge](docs.user.knowledge.accounting.html)
1. [Accounting Entries](docs.user.knowledge.accounting_entries.html)
1. [DocType Definitions](docs.user.knowledge.doctype.html)
1. [Attachment and CSV Files](docs.user.knowledge.attachment_csv.html)
1. [Format using Markdown](docs.user.knowledge.markdown.html)

View File

@ -0,0 +1,81 @@
---
{
"_label": "Day-1: Setup Customer, Item, and Supplier"
}
---
Login to your ERPNext account with the User ID and Password sent through the mail.
After logging into your account you will receive a pop-up form to fill. Please fill this form. Select the abbreviation you would wish to have for your company. The abbreviation selected here will be used in naming most of the business documents.
#### Form Part I
![1st Form](img/firstdaysetup-1.png)
<br><br>
#### Form Part II
To understand about Company Financial Year or Fiscal Year visit [Fiscal Year](docs.user.knowledge.fiscal_year.html)
![1st Form](img/firstdaysetup-2.png)
After filling this form, you will get a pop-up message for completing the set-up process. Click on the Setup button. The Setup page will appear.
<br>
#### Setup Page - Customer
The Organisation details are updated in ERPNext, after filling the first form. Go directly to the Customer Icon.
![Customer](img/firstdaysetup-customer.png)
<br>
After clicking on Customer, a new form will appear.
<br>
![Customer](img/firstdaysetup-customer-1.png)
To see how customer details are added, visit [Customer](docs.user.selling.customer.html). Create 5 new customer records in the system.
Now proceed to make an Item. To go to the main menu, click on erpnext icon which is on the left hand corner of the page. On the main menu page, click on Setup
![Main Menu](img/firstdaysetup-main-menu.png)
<br>
#### Setup Page - Item
On the setup page go to Item.
![Item](img/firstdaysetup-item.png)
Create a new Item. An Item is your company's product or a service.The term Item is applicable to your core products as well as your raw materials. It can be a product or service that you buy/sell from your customers/ suppliers.
Filling Item details is an important step in ERPNext. Do not postpone this step. After clicking on Item, make a new Item.
![Item](img/firstdaysetup-item-1.png)
To understand how to fill an Item in detail, visit [Item](docs.user.stock.item.html). Add 5 item records to ERPnext. After adding these records, go back to the Setup Page and add Suppliers.
<br>
#### Setup Page - Suppliers
On the Setup page go to Supplier.
![Supplier](img/firstdaysetup-supplier.png)
<br>
Suppliers are companies or individuals who provide you with products or services. They are treated in exactly the same manner as Customers in ERPNext. Create a new Supplier record.
![Supplier](img/firstdaysetup-supplier-1.png)
To understand how to fill Supplier details, visit [Supplier](docs.user.buying.supplier.html).
If you wish to import your list of customers and suppliers directly to ERPNext, you can do that via the Data Import Tool.
To upload Customers or suppliers in bulk, go to the Data Import Tool.
> Note: The data import format is case-sensitive. The file will not be processed if there are any spelling mistakes or deviations from the default values.
To understand how to import data, visit [Importing Data](docs.user.setup.data_import.html).

View File

@ -0,0 +1,54 @@
---
{
"_label": "Day-2: Setup Chart of Accounts, Opening Accounts, and HR"
}
---
#### Setup Page - Accounts
<br>
Go to the Accounts icon and make ledgers under Chart of Accounts.
![Accounts](img/seconddaysetup-accounts.png)
<br>
Create acccounting ledgers.
![Tree](img/seconddaysetup-tree.png)
<br>
To begin Opening Entries, go to 'Opening Accounts and Stock' on the Setup Page.
![Ledger](img/seconddaysetup-accounts-jv.png)
<br>
To understand how to create opening entries in detail visit [Opening Entry](docs.user.setup.opening.html).
<br>
#### Opening Stock
You can upload your opening stock in the system using Stock Reconciliation. Stock Reconciliation will update your stock for any given Item.
![Stock Opening](img/seconddaysetup-stock-opening.png)
<br>
To understand Stock Opening in detail visit [Opening Stock](docs.user.accounts.opening_stock.html).
<br>
#### Setup Page - HR Setup
To setup HR, begin by creating individual employee records.
![Employee](img/seconddaysetup-hr.png)
To fill the Employee Form, refer to [Employee](docs.user.hr.employee.html)
To complete the remaining HR-Setup, see [Human Resources](docs.user.hr.html)

View File

@ -0,0 +1,139 @@
---
{
"_label": "Day-3: Sales Cycle and Purchase Cycle"
}
---
After completing the set-up and account opening process, it is advisable to complete a few cycles of sales, purchase, and manufacturing process.
### Sales Cycle
Complete a standard Sales Cycle.
> Lead > Opportunity > Quotation > Sales Order > Delivery Note > Sales Invoice > Payment (Journal Voucher)
<br>
#### Lead
To begin the sales cycle, go to the Selling Icon. On the selling page, click on Lead.
![Lead](img/thirddaysetup-lead.png)
Fill the Lead form.
> To understand Lead in detail, visit [Lead](docs.user.selling.lead.html)
<br>
#### Opportunity
After completing the Lead form, assume that, this same lead is getting converted into an Opportunity. Thus, to create an Opportunity from the existing lead, click on Create Opportunity, on the Lead page.
##### Step 1: Go to 'Lead List' Page and open the Lead that shows interested status.
![Opportunity](img/thirddaysetup-opportunity-1.png)
<br>
##### Step 2: Generate Opportunity from the selected Lead
![Opportunity](img/thirddaysetup-opportunity.png)
You can also generate an Opportunity directly from the Selling Page.
> To understand Opportunity in detail visit [Opportunity](docs.user.selling.opportunity.html).
<br>
#### Quotation
Imagine that your Opportunity has shown interest and asked for a Quotation. To generate a Quotation from the same Opportunity, open the submitted Opportunity and click on Create Quotation.
![Quotation](img/thirddaysetup-quotation.png)
You can also generate a Quotation directly from the Selling Page.
> To understand Quotation in detail visit [Quotation](docs.user.selling.quotation.html)
<br>
#### Sales Order
Imagine that the Quotation which you sent was accepted by the prospect. You are now reequired to send him a Sales Order. To make a sales order from this same Quotation, go to that Quotation page and click on Make Sales Order.
![Sales Order](img/thirddaysetup-sales-order.png)
You can also generate a Sales Order directly from the Selling Page.
> To understand Sales Order in detail visit [Sales Order](docs.user.selling.sales_order.html).
<br>
#### Delivery Note
If your organisation has the practice of sending Delivery Note, this section will be helpful. To create a Delivery Note from the a Sales Order, go to that Sales Order and click on Make Delivery.
![Delivery Note](img/thirddaysetup-delivery-note.png)
> To understand Delivery Note in detail, visit [Delivery Note](docs.user.stock.delivery_note.html)
<br>
#### Sales Invoice
Save and Submit your Delivery Note to generate a Sales Invoice. You can also generate an Invoice from Sales Order.
![Sales Invoice](img/thirddaysetup-sales-invoice.png)
<br>
#### Payment (Journal Voucher)
A Journal Voucher or a payment entry can be generated directly from the Sales Invoice.
![Payment Entry](img/thirddaysetup-payment-entry.png)
> To understand a Journal Voucher in detail, visit [Journal Voucher](docs.user.accounts.journal_voucher.html)
<br>
### Purchase Cycle
Complete a standard Purchase Cycle.
> Material Request > Purchase Order > Purchase Receipt > Payment (Journal Voucher).
<br>
#### Material Request
To create a Material Request, go to Stock/Buying and Click on Material Request.
![Material Request](img/thirddaysetup-material-request.png)
> To understand Material Request in detail, visit [Material Request](docs.user.buying.material_request.html)
<br>
#### Purchase Order
To create a Purchase Order go to Buying and click on Purchase Order
![Purchase Order](img/thirddaysetup-purchase-order.png)
> To understand Purchase Order in detail, visit [Purchase Order](docs.user.buying.purchase_order.html)
<br>
#### Purchase Receipt
To create a Purchase Receipt from an existing Purchase Order, open that purchase order and click on Make Purchase Receipt.
![Purchase Receipt](img/thirddaysetup-purchase-receipt.png)
<br>
>To understand Purchase Receipt in detail, visit [Purchase Receipt](docs.user.stock.purchase_receipt.html)
<br>
#### Payment (Journal Voucher)
Payments made against Sales Invoices or Purchase Invoices can be made by clicking on “Make Payment Entry” button on “Submitted” invoices.
![Payment Entry](img/thirddaysetup-payment-entry.png)
<br>
> To understand Payment Entry in detail, visit [Payment Entry](docs.user.accounts.payments.html).

View File

@ -0,0 +1,86 @@
---
{
"_label": "Day-4: Manufacturing Cycle and Accounting Reports"
}
---
### Manufacturing Cycle
Complete a manufacturing cycle (if applicable).
> BOM > Production Planning Tool > Production Order > Stock Entry (Material Issue) > Stock Entry (Sales Return)
<br>
#### Bill of Materials
To go to Bill of Materials, Click on Manufacturing. On the Manufacturing page, click on Bill of Materials.
![Bill of Materials](img/fourthdaysetup-bom.png)
> To understand BOM in detail, visit [Bill of Materials](docs.user.mfg.bom.html)
<br>
#### Production Planning Tool
To go to Production Planning Tool, click on the Manufacturing Icon. On the Manufacturing Page, click on Production Planning Tool to go to that page.
![Production Planning Page](img/fourthdaysetup-ppt.png)
> To understand Production Planning Tool in detail, visit [Production Planning](docs.user.mfg.planning.html)
<br>
#### Production Order
To go to Production Order click on the Manufacturing Icon. On the Manufacturing Page, click on Production Order.
![Production Order](img/fourthdaysetup-po.png)
> To understand Production Order in detail, visit [Production Order](docs.user.mfg.production_order.html)
<br>
#### Stock Entry
To go to Stock Entry, click on the Stock Icon and go to Stock Entry.
![Stock Entry](img/fourthdaysetup-stock.png)
> To understand Material Issue, visit [Material Issue](docs.user.stock.material_issue.html).
> To understand Sales Return, visit [Sales Return](docs.user.stock.sales_return.html).
<br>
#### Delivery Note
To go to Delivery Note, click on Stock. On the Stock Page, click on Delivery Note.
![Delivery Note](img/fourthdaysetup-delivery-note.png)
> To understand Delivery Note in detail, visit [Delivery Note](docs.user.stock.delivery_note.html)
<br>
#### Warehouse
To go to Warehouse, Click on Stock. On the Stock Page, go to Warehouse.
![Warehouse](img/fourthdaysetup-warehouse.png)
> To understand Warehouse in detail, visit [Warehouse](docs.user.stock.warehouse.html)
<br>
#### Accounts
Make a few Journal Vouchers. Generate some Accounting Reports.
#### Journal Voucher
To go to a Journal Voucher, click on Accounts. On the Accounts page, click on Journal Voucher.
![Journal Voucher](img/fourthdaysetup-jv.png)
> To understand Journal Voucher in detail, visit [Journal Voucher](docs.user.accounts.journal_voucher.html)
<br>
### Accounting Reports
Some of the major Accounting Reports are General Ledger, Trial Balance, Accounts Payable and Accounts Receivables, and Sales and Purchase Register.
> To be able to generate these accounts, visti [Accounting Reports](docs.user.accounts.report.html)

View File

@ -0,0 +1,32 @@
---
{
"_label": "Day-5: Projects, Calendar, and Website"
}
---
#### Projects
ERPNext helps you to manage your Projects by breaking them into Tasks and allocating them to different people.
<br>
#### Tasks
Project is divided into Tasks and each Task is allocated to a resource. In ERPNext, you can also create and allocate a Task independently of a Project.
To create a Task, go to Project and click on Task.
![Tasks](img/fifthdaysetup-tasks.png)
> To understand Projects in detail, visit [Projects](docs.user.projects.html).
> To understand Task in detail, visit [Tasks](docs.user.projects.tasks.html)
<br>
#### Calendar
> To understand Calendar in detail, visit [Calendar](docs.user.tools.calendar.html)
<br>
#### Website
> To understand Website in detail, visit [Website](docs.user.website.html)

View File

@ -0,0 +1,48 @@
---
{
"_label": "Five-Day Setup",
"_toc": [
"docs.user.five_day_setup.day_1",
"docs.user.five_day_setup.day_2",
"docs.user.five_day_setup.day_3",
"docs.user.five_day_setup.day_4",
"docs.user.five_day_setup.day_5"
]
}
---
Welcome to ERPNext. To be able to setup ERPNext account successfully, a five-day-setup process is recommended. Perform the 5-days-setup instructions and sail through the ERPNext implementation.
The setup help is divided into day-wise instructions for 5 consecutive days.
#### Day 1
- Company Setup
- Customer Setup
- Item Setup
- Supplier Setup
- Data Import Tool
#### Day 2
- Opening Accounts
- Opening Stock
- HR Setup
#### Day 3
- Sales Cycle
- Purchase Cycle
#### Day 4
- Manufacturing Cycle
- Delivery Note and Warehouse
- Accounts
#### Day 5
- Projects
- Calendar
- Website

View File

@ -10,11 +10,12 @@ Before you start managing your Operations in EPRNext, you must first become fami
### Test Phase
- Read the Manual
- Follow the Five-Day-Setup Module or the instructions given below.
- Create your first Customer, Supplier and Item. Add a few more so you get familiar with them.
- Create Customer Groups, Item Groups, Warehouses, Supplier Groups, so that you can classify your Items.
- Complete a standard sales cycle - Lead > Opportunity > Quotation > Sales Order > Delivery Note > Sales Invoice > Payment (Journal Voucher)
- Complete a standard purchase cycle - Purchase Request > Purchase Order > Purchase Receipt > Payment (Journal Voucher).
- Complete a manufacturing cycle (if applicable) - BOM > Production Planning Tool > Production Order > Stock Entry (issue) > Stock Entry (back-flush)
- Complete a standard purchase cycle - Material Request > Purchase Order > Purchase Receipt > Payment (Journal Voucher).
- Complete a manufacturing cycle (if applicable) - BOM > Production Planning Tool > Production Order > Material Issue > Sales Return
> Tip: Use the 30-day free trial at [erpnext.com](https://erpnext.com) to take your test drive.

View File

@ -22,34 +22,34 @@ Accounting Entries
The balance of account can be increased / decreased, depending on account type and transaction type.
<table class="table table-bordered">
<table class="table table-bordered text-center">
<thead>
<tr class="active">
<td style="text-align: center;">Account Type</td>
<td style="text-align: center;">Transaction Type</td>
<td style="text-align: center;">Effect on account balance</td>
<td>Account Type</td>
<td>Transaction Type</td>
<td>Effect on account balance</td>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;">Debit</td>
<td style="text-align: center;">Debit</td>
<td style="text-align: center;">Increases</td>
<td>Debit</td>
<td>Debit</td>
<td>Increases</td>
</tr>
<tr>
<td style="text-align: center;">Debit</td>
<td style="text-align: center;">Credit</td>
<td style="text-align: center;">Decreases</td>
<td>Debit</td>
<td>Credit</td>
<td>Decreases</td>
</tr>
<tr>
<td style="text-align: center;">Credit</td>
<td style="text-align: center;">Credit</td>
<td style="text-align: center;">Increases</td>
<td>Credit</td>
<td>Credit</td>
<td>Increases</td>
</tr>
<tr>
<td style="text-align: center;">Credit</td>
<td style="text-align: center;">Debit</td>
<td style="text-align: center;">Decreases</td>
<td>Credit</td>
<td>Debit</td>
<td>Decreases</td>
</tr>
</tbody>
</table>
@ -62,48 +62,48 @@ This means that every accounting entry has two parts, one debit and one credit a
As the company will receive a payment from customer, the customer is considered as an asset account. For booking income, company maintains an account called "Sales of Laptop". So, entries will be done in the following manner:
<table class="table table-bordered">
<table class="table table-bordered text-center">
<thead>
<tr class="active">
<td style="text-align: center;">Account</td>
<td style="text-align: center;">Debit</td>
<td style="text-align: center;">Credit</td>
<td>Account</td>
<td>Debit</td>
<td>Credit</td>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;">Customer A</td>
<td style="text-align: center;">50000</td>
<td style="text-align: center;"></td>
<td>Customer A</td>
<td>50000</td>
<td></td>
</tr>
<tr>
<td style="text-align: center;">Sales of Laptop</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">50000</td>
<td>Sales of Laptop</td>
<td></td>
<td>50000</td>
</tr>
</tbody>
</table>
Customer A has made the payment, so customer balance should decreased based on the paid amount, which will increase "Cash" balance.
<table class="table table-bordered">
<table class="table table-bordered text-center">
<thead>
<tr class="active">
<td style="text-align: center;">Account</td>
<td style="text-align: center;">Debit</td>
<td style="text-align: center;">Credit</td>
<td>Account</td>
<td>Debit</td>
<td>Credit</td>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;">Customer A</td>
<td style="text-align: center;"></td>
<td style="text-align: center;">50000</td>
<td>Customer A</td>
<td></td>
<td>50000</td>
</tr>
<tr>
<td style="text-align: center;">Cash</td>
<td style="text-align: center;">50000</td>
<td style="text-align: center;"></td>
<td>Cash</td>
<td>50000</td>
<td></td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,16 @@
---
{
"_label": "Attachment and CSV files"
}
---
#### How to Attach files?
When you open a form, on the right sidebar, you will see a section to attach files. Click on “Add” and select the file you want to attach. Click on “Upload” and you are set.
#### What is a CSV file?
A CSV (Comma Separated Value) file is a data file that you can upload into ERPNext to update various data. Any spreadsheet file from popular spreadsheet applications like MS Excel or Open Office Spreadsheet can be saved as a CSV file.
If you are using Microsoft Excel and using non-English characters, make sure to save your file encoded as UTF-8. For older versions of Excel, there is no clear way of saving as UTF-8. So save your file as a CSV, then open it in Notepad, and save as “UTF-8”. (Sorry blame Microsoft for this!)

View File

@ -0,0 +1,267 @@
---
{
"_label": "DocType"
}
---
ERPNext is a based on a “metadata” (data about data) framework that helps define all the different types of documents in the system. The basic building block of ERPNext is a DocType.
A DocType represents both a table in the database and a form from which a user can enter data.
Many DocTypes are single tables, but some work in groups. For example, Quotation has a “Quotation” DocType and a “Quotation Item” doctype for the Items table, among others. DocTypes contain a collection of fields called DocFields that form the basis of the columns in the database and the layout of the form.
<table class="table table-bordered text-left">
<thead>
<tr class="active">
<td width="30%">Column</td>
<td>Description</td>
</tr>
</thead>
<tbody>
<tr>
<td>Name</td>
<td>Name of the record</td>
</tr>
<tr>
<td>Owner</td>
<td>Creator and Owner of the record</td>
</tr>
<tr>
<td>Created on</td>
<td>Date and Time of Creation</td>
</tr>
<tr>
<td>Modified On </td>
<td>Date and Time of Modification</td>
</tr>
<tr>
<td>Docstatus</td>
<td>Status of the record<br>
0 = Saved/Draft<br>
1 = Submitted<br>
2 = Cancelled/Deleted
</td>
</tr>
<tr>
<td>Parent</td>
<td>Name of the Parent</td>
</tr>
<tr>
<td>Parent Type</td>
<td>Type of Parent</td>
</tr>
<tr>
<td>Parent Field</td>
<td>Specifying the relationship with the parent (there can be multiple child relationships with the same DocType).</td>
</tr>
<tr>
<td>Index(idx)</td>
<td>Index (sequence) of the record in the child table.</td>
</tr>
</tbody>
</table>
#### Single DocType
There are a certain type of DocTypes that are “Single”, i.e. they have no table associated and have only one record of its fields. DocTypes such as Global Defaults, Production Planning Tool are “Single” DocTypes.
#### Field Columns
In the fields table, there are many columns, here is an explanation of the columns of the field table.
<table class="table table-bordered text-left">
<thead>
<tr class="active">
<td width="30%">Column</td>
<td>Description</td>
</tr>
</thead>
<tbody>
<tr>
<td>Label</td>
<td>Field Label (that appears in the form).</td>
</tr>
<tr>
<td>Type</td>
<td>Field Type</td>
</tr>
<tr>
<td>Name</td>
<td>Column name in the database, must be code friendly with no white spaces, special characters and capital letters.</td>
</tr>
<tr>
<td>options</td>
<td>Field settings:<br>
For Select: List of options (each on a new line).<br>
For Link: DocType that is “linked”.<br>
For HTML: HTML Content
</tr>
<tr>
<td>Perm Level</td>
<td>Permission level (number) of the field. You can group fields by numbers, called levels, and apply rules on the levels.</td>
</tr>
<tr>
<td>Width</td>
<td>Width of the field (in pixels) - useful for “Table” types.</td>
</tr>
<tr>
<td>Reqd</td>
<td>Checked if field is mandatory (required).</td>
</tr>
<tr>
<td>In Filter</td>
<td>Checked if field appears as a standard filter in old style reports.</td>
</tr>
<tr>
<td>Hidden</td>
<td>Checked if field is hidden.</td>
</tr>
<tr>
<td>Print Hide</td>
<td>Checked if field is hidden in Print Formats.</td>
</tr>
<tr>
<td>Report Hide</td>
<td>Checked if field is hidden in old style reports.</td>
</tr>
<tr>
<td>Allow on Submit</td>
<td>Checked if this field can be edited after the document is “Submitted”.</td>
</tr>
<tr>
<td>Depends On</td>
<td>The fieldname of the field that will decide whether this field will be shown or hidden. It is useful to hide un-necessary fields.</td>
</tr>
<tr>
<td>Description</td>
<td>Description of the field</td>
</tr>
<tr>
<td>Default</td>
<td>Default value when a new record is created.<br>
Note: “user” will set the current user as default and “today” will set todays date (if the field is a Date field).</td>
</tr>
<tbody>
<table>
#### Field Types and Options
Here is a list of the different types of fields used to make / customize forms in ERPNext.
<table class="table table-bordered text-left">
<thead>
<tr class="active">
<td width="30%">Type</td>
<td>Description</td>
<td>Options/Setting</td>
</tr>
</thead>
<tbody>
<tr>
<td>Data</td>
<td>Single line text field with 180 characters</td>
<td> </td>
</tr>
<tr>
<td>Select</td>
<td>Select from a pre-determined items in a drop-down.</td>
<td>The “Options” contains the drop-down items, each on a new row</td>
</tr>
<tr>
<td>Link</td>
<td>Link an existing document / record</td>
<td>Options contains the name of the type of document (DocType)</td>
</tr>
<tr>
<td>Currency</td>
<td>Number with 2 decimal places, that will be shown separated by commas for thousands etc. in Print.</td>
<td>e.g. 1,000,000.00</td>
</tr>
<tr>
<td>Float</td>
<td>Number with 6 decimal places.</td>
<td>e.g. 3.141593</td>
</tr>
<tr>
<td>Int</td>
<td>Integer (no decimals)</td>
<td>e.g. 100</td>
</tr>
<tr>
<td>Date</td>
<td>Date</td>
<td>Format can be selected in Global Defaults</td>
</tr>
<tr>
<td>Time</td>
<td>Time</td>
<td></td>
</tr>
<tr>
<td colspan="3" class="active">Text</td>
</tr>
<tr>
<td>Text</td>
<td>Multi-line text box without formatting features</td>
<td></td>
</tr>
<tr>
<td>Text editor</td>
<td>Multi-line text box with formatting toolbar etc</td>
<td></td>
</tr>
<tr>
<td>Code</td>
<td>Code Editor</td>
<td>Options can include the type of language for syntax formatting.
Eg JS / Python / HTML</td>
</tr>
<tr>
<td colspan="3" class="active">Table (Grid)</td>
</tr>
<tr>
<td>Table</td>
<td>Table of child items linked to the record.</td>
<td>Options contains the name of the DocType of the child table. For example “Sales Invoice Item” for “Sales Invoice”</td>
</tr>
<tr>
<td colspan="3" class="active">Layout</td>
</tr>
<tr>
<td>Section Break</td>
<td>Break into a new horizontal section.</td>
<td>The layout in ERPNext is evaluated from top to bottom.</td>
</tr>
<tr>
<td>Column Break</td>
<td>Break into a new vertical column.</td>
<td></td>
</tr>
<tr>
<td>HTML</td>
<td>Add a static text / help / link etc in HTML</td>
<td>Options contains the HTML.</td>
</tr>
<tr>
<td colspan="3" class="active">Action</td>
</tr>
<tr>
<td>Button</td>
<td>Button</td>
<td>[for developers only]</td>
</tr>
<tbody>
<table>

View File

@ -0,0 +1,84 @@
---
{
"_label": "Format Using Markdown"
}
---
Markdown is a simple way of writing text to format your content. Markdown allows you easy ways to format.
1. Headings (h1 (largest), h2, h3, h4 and so on)
1. Paragraphs
1. Lists (numbered or bulleted)
1. Hyper links (links to other pages)
1. Images
1. Code
1. Embed HTML (HTML tags within your text)
#### Headings
Headings are specified by adding a `#` (hash) at the beginning of the line. The more the number of hashes, the smaller the heading:
# This is a large heading.
### This is a smaller heading.
#### Paragraphs
To start a new paragraph, just make sure that there is an empty line at the beginning and end of the paragraph.
To format text as **bold** or with _italics_ format as follows:
**This text** is **bold** and _this one_ is with _italics_
#### Lists
To define numbered lists, start your link with a number and a dot (.) and ensure there is a blank line before and after the list. The numbers are automatically generated so it does not matter what number you put:
1. list 1st item
1. second item
1. and so on
1. and so forth
To define bulleted lists, start your items with a hyphen (-)
- item 1
- item 2
- item 3
To nest lists within one another, put four spaces to indent your inner list as follows:
1. item 1
1. item 2
- sub item 1
- sub item 2
1. item 3
#### Links (to other pages)
Links to other pages can be defined by adding your text in box brackets [] followed by the link in round brackets ()
[This is an external link](http://example.com)
[A link within the site](my-page.html)
#### Images
Images can be added by adding an exclamation ! before the link.
![A flower](files/flower.gif)
#### Code
To add a code block, just leave a blank line before and after the block and make sure all code line are indented by four spaces:
This is normal text
This is a code block
#### HTML
You can embed any kind of HTML tags within your code. Any content written within HTML tags will not be formatted.
[Detailed description of the markdown format](http://daringfireball.net/projects/markdown/syntax)

View File

@ -4,8 +4,12 @@
"_toc": [
"docs.user.knowledge.fiscal_year",
"docs.user.knowledge.accounting",
"docs.user.knowledge.accounting_entries"
"docs.user.knowledge.accounting_entries",
"docs.user.knowledge.doctype",
"docs.user.knowledge.attachment_csv",
"docs.user.knowledge.markdown"
]
}
---
Knowledge Library contains definitions and explanations of various management concepts. This page is created for users who wish to elaborate their conceptual knowledge.
Knowledge Library contains definitions and explanations of various management concepts. This page is created for users who wish to elaborate their conceptual knowledge.

View File

@ -4,7 +4,9 @@
"_title_image": "img/customers.png"
}
---
You can either directly create your Customers via
A customer, who is sometimes known as a client, buyer, or purchaser is the one who receives goods, services, products, or ideas, from a seller for a monetary consideration. A customer can also receive goods or services from a vendor or a supplier for other valuable considerations.
You can either directly create your Customers via
> Selling > Customer

View File

@ -45,6 +45,14 @@ ERPNext will help you set and manage budgets on your Cost Centers. This is usefu
Budgets are also great for planning purposes. When you are making plans for the next financial year, you would typically target a revenue based on which you would set your expenses. Setting a budget will ensure that your expenses do not get out of hand, at any point, as per your plans.
You can define it in the Cost Center. If you have seasonal sales you can also define a budget distribution that the budget will follow.
> Accounts > Budget Distribution > New Budget Distribution
![Budget Distribution](img/budgeting.png)
#### Budget Actions

View File

@ -3,7 +3,7 @@
"_label": "Data Import Tool"
}
---
The Data Import Tool is a great way to upload (or edit) bulk data, specially master data, into the system. To start the tool go to:
The Data Import Tool is a great way to upload (or edit) bulk data, specially master data, into the system.
To Open the data import tool, you either go to Setup or go to the Transaction you want to Import. If Data Import is allowed, you will see an Import Button:
@ -15,7 +15,7 @@ The tool has two sections, one to download a template and the second to upload t
### 1. Downloading The Template
Data in ERPNext is stored in tables, much like a spreadsheet with columns and rows of data. Each entity in ERPNext can have multiple child tables associated with it too. The child tables are linked to the parent tables and are implemented where are multiple values for any property. For example an Item can have multiple prices, An Invoice has multiple Items and so on.
Data in ERPNext is stored in tables, much like a spreadsheet with columns and rows of data. Each entity in ERPNext can have multiple child tables associated with it too. The child tables are linked to the parent tables and are implemented where there are multiple values for any property. For example an Item can have multiple prices, An Invoice has multiple Items and so on.
You can import each table separately, or all at a time. In the child table, you must mention the parent of the row in the “parent” column so that ERPNext knows which Items price or tax you are trying to set if you are importing separately.
@ -36,7 +36,7 @@ Then export your template or save it as a **Comma Separated Values** (CSV) file.
### 3. Upload the .csv File
Finally attach the .csv file in the section section click on the "Upload and Import" button.
Finally attach the .csv file in the section. Click on the "Upload and Import" button.
![Attach and Upload](img/import-5.png)

View File

@ -18,7 +18,7 @@
"docs.user.setup.email",
"docs.user.setup.sms",
"docs.user.setup.taxes",
"docs.user.setup.price_lists",
"docs.user.setup.price_list",
"docs.user.setup.opening",
"docs.user.setup.pos_setting",
"docs.user.setup.third_party_backups"

View File

@ -7,7 +7,7 @@ A Price List is a place where different rate plans can be stored. Its a name
An Item can have multiple prices based on customer, currency, region, shipping cost etc, which can be stored as different rate plans. In ERPNext, you are required to store all the lists seperately. Buying Price List is different from Selling Price List and thus is stored separately.
> Selling > Price List
> Setup > Price List
![Price-List](img/price-lists.png)
@ -15,7 +15,14 @@ An Item can have multiple prices based on customer, currency, region, shipping c
> For multiple currencies, maintain multiple Price Lists.
<br>
### Add Item in Price List
To add a new Item to the Price List, add the Item Code and its rate in the Item Prices table.
> Setup > Item Price
You can also import Item Prices via [Data Import Tool](docs.user.setup.data_import.html)
- Enter Price List and Item Code, Valid for Buying or Selling, Item Name & Item Description will be automatically fetched.
- Enter Rate and save the document.
![Item-Price](img/item-price.png)
For bulk upload of Item Prices, use [Data Import Tool](docs.user.setup.data_import.html)

View File

@ -6,7 +6,7 @@
ERPNext has a role-based permission system, which means that you can assign Roles to Users, and permissions on Roles.Each ERPNext user has a Profile. The Profile contains the users email and authentication and can be set from:
> Setup > Users and Permissions > Users
> Setup > Profile
#### Step 1: Adding a new User

View File

@ -15,7 +15,7 @@ ERPNext is optimized for itemized management of your sales and purchase. If you
- **Item Name:** Item name is the actual name of your product or service.
- **Item Code:** Item Code is a short-form to denote your Item. If you have very few Items, it is advisable to keep the Item Name and the Item Code same. This helps new users to recognise and update Item details in all transactions. In case you have lot of Items with long names and the list runs in hundreds, it is advisable to code. To understand naming Item codes see [Item Codification](docs.user.setup.codification.html)
- **Item Group:** Item Group is used to categorize an Item under various criterias like products, raw materials, services, sub-assemblies, consumables or all Item groups. Create your default Item Group list under Setup> Item Group and pre-select the option while filling your New Item details under Item Group.
- **Item Group:** Item Group is used to categorize an Item under various criterias like products, raw materials, services, sub-assemblies, consumables or all Item groups. Create your default Item Group list under Setup> Item Group and pre-select the option while filling your New Item details under [Item Group](docs.user.stock.item_group.html)
- **Default Unit of Measure:** This is the default measuring unit that you will use for your product. It could be in nos, kgs, meters, etc. You can store all the UOMs that your product will require under Set Up> Master Data > UOM. These can be preselected while filling New Item by using % sign to get a pop up of the UOM list.
- **Brand:** If you have more than one brand save them under Set Up> Master Data> Brand and pre-select them while filling a New Item.
@ -27,11 +27,7 @@ To upload an image for your icon that will appear in all transactions, save the
![Item Properties](img/item-add-image.png)
### Item Pricing
Item Price and Price Lists: ERPNext lets you maintain multiple selling prices for an Item using Price Lists. A Price List is a place where different rate plans can be stored. Its a name you can give to a set of Item prices. In case you have different zones (based on the shipping costs), for different currencies etc, you can maintain different Price Lists. A Price List is formed when you create different Item Prices. To import Item Price see [Importing Data](docs.user.data_import.md).
## Inventory : Warehouse and Stock Setting
### Inventory : Warehouse and Stock Setting
In ERPNext, you can select different type of Warehouses to stock your different Items. This can be selected based on Item types. It could be Fixed Asset Item, Stock Item or even Manufacturing Item.
@ -95,3 +91,59 @@ Inspection Criteria: If a Quality Inspection is prepared for this Item, then thi
Visit [Manufacturing](docs.user.mfg.html) and [Website](docs.user.website.html) to understand these topics in detail.
### Listing Item on Website
To list your Item on the Website, fill the Item details and save the file. Once the file is saved, a plus (+) button will appear next to the Image icon. Click on the plus button and add your Item image. The html code will be generated automatically.
##### Step 1: Save Image
![Webimage](img/item-webimage.png)
<br>
##### Step 2: Check the 'Show in Website' box.
Under the Website section, please check the box that says 'show in Website'. Once the box is checked, the page will display other fields for entering information.
![Webimage](img/item-webimage-1.png)
<br>
##### Step 3: Enter Website Details
![Webimage](img/item-webimage-2.png)
The page name will be generated automatically. Mention the Item-Group under which the Item will be displayed.
#### Item Groups
Mention the Item Group under this column. If you wish to list your Item under the broad category products, name your Item Group as Products. In case you have various varieties of Item and want to classify them under different names, make Item Groups with those names and check the box that says 'show in Website'. For Example, if you wish to create a category called 'Bags', create a Item Group named Bags.
![Item Group](img/itemgroup-webimage-bags.png)
Once the Item Group is created go to the Website Settings page under Website. Enter the Label, Url, and Parent Label.
![Item Group](img/itemgroup-website-settings.png)
<br>
#### Webpage labels
![Webpage](img/webpage-labels.png)
Add more Items under a particular Item Group.
To add more Items under a certain Label, mention the Item Group on the Item Page. The Items will be added automatically on the Webpage, under the Item Group Label. For Example, To add Item-Kiddies Bag and Butterfly Print Bag, check the 'Show in Website'box. The Items will be placed under the Label Bags on the Webpage.
![Item Group](img/itemgroup-websettings.png)
<br>
Item Group Display
![Item Group Display](img/webpage-itemgroup-display.png)

View File

@ -15,6 +15,11 @@ To create a new blog, just create a new Blog from:
![Blog](img/blog.png)
You can format the blog using the same Markdown format
You can format a blog using the Markdown format.You can also access your blog by going to the page “blog.html”.
#### A sample blog-page.
![Blog](img/blog-look.png)
You can access your blog by going to the page “blog.html”

View File

@ -29,11 +29,36 @@ To define the Top Bar Menus, Brand, Footers and Home Page, go to:
> Website > Website Settings
#### Step 1: Landing Page Details
![Website Setting](img/website-settings.png)
<br>
#### Step 2: Banner Details
![Website Setting](img/website-settings-1.png)
<br>
#### Step 3: Top Bar Labels
![Website Setting](img/website-settings-2.png)
> Note: Create seperate web pages which will be linked to the main web-icons like company, contact, products etc.
<br>
#### Step 4: Footer Details
![Website Setting](img/website-settings-3.png)
A website can be generated once all the settings and style requirements are added.
A sample website generated by ERPNext would look like this.
![Website](img/website-settings-4.png)
<br>
#### Top Menu

View File

@ -7,7 +7,6 @@ import webnotes
from webnotes.model import db_exists
from webnotes.model.bean import copy_doclist
sql = webnotes.conn.sql

View File

@ -7,7 +7,6 @@ import webnotes
from webnotes.utils import getdate, nowdate
from webnotes import msgprint, _
sql = webnotes.conn.sql
class DocType:
def __init__(self, doc, doclist=[]):
@ -15,7 +14,7 @@ class DocType:
self.doclist = doclist
def validate_duplicate_record(self):
res = sql("""select name from `tabAttendance` where employee = %s and att_date = %s
res = webnotes.conn.sql("""select name from `tabAttendance` where employee = %s and att_date = %s
and name != %s and docstatus = 1""",
(self.doc.employee, self.doc.att_date, self.doc.name))
if res:
@ -24,7 +23,7 @@ class DocType:
def check_leave_record(self):
if self.doc.status == 'Present':
leave = sql("""select name from `tabLeave Application`
leave = webnotes.conn.sql("""select name from `tabLeave Application`
where employee = %s and %s between from_date and to_date and status = 'Approved'
and docstatus = 1""", (self.doc.employee, self.doc.att_date))
@ -42,7 +41,7 @@ class DocType:
msgprint(_("Attendance can not be marked for future dates"), raise_exception=1)
def validate_employee(self):
emp = sql("select name from `tabEmployee` where name = %s and status = 'Active'",
emp = webnotes.conn.sql("select name from `tabEmployee` where name = %s and status = 'Active'",
self.doc.employee)
if not emp:
msgprint(_("Employee: ") + self.doc.employee +

View File

@ -4,7 +4,6 @@
wn.provide("erpnext.hr");
erpnext.hr.EmployeeController = wn.ui.form.Controller.extend({
setup: function() {
this.setup_leave_approver_select();
this.frm.fields_dict.user_id.get_query = function(doc,cdt,cdn) {
return { query:"core.doctype.profile.profile.profile_query"} }
this.frm.fields_dict.reports_to.get_query = function(doc,cdt,cdn) {
@ -12,6 +11,7 @@ erpnext.hr.EmployeeController = wn.ui.form.Controller.extend({
},
onload: function() {
this.setup_leave_approver_select();
this.frm.toggle_display(["esic_card_no", "gratuity_lic_id", "pan_number", "pf_number"],
wn.control_panel.country==="India");
if(this.frm.doc.__islocal) this.frm.set_value("employee_name", "");

View File

@ -4,11 +4,10 @@
from __future__ import unicode_literals
import webnotes
from webnotes.utils import getdate, validate_email_add, cstr
from webnotes.utils import getdate, validate_email_add, cstr, cint
from webnotes.model.doc import make_autoname
from webnotes import msgprint, _
sql = webnotes.conn.sql
class DocType:
def __init__(self,doc,doclist=[]):
@ -40,12 +39,12 @@ class DocType:
self.validate_email()
self.validate_status()
self.validate_employee_leave_approver()
self.update_dob_event()
def on_update(self):
if self.doc.user_id:
self.update_user_default()
self.update_profile()
self.update_dob_event()
def update_user_default(self):
webnotes.conn.set_default("employee", self.doc.name, self.doc.user_id)
@ -156,10 +155,11 @@ class DocType:
raise_exception=InvalidLeaveApproverError)
def update_dob_event(self):
if self.doc.status == "Active" and self.doc.date_of_birth:
if self.doc.status == "Active" and self.doc.date_of_birth \
and not cint(webnotes.conn.get_value("HR Settings", None, "stop_birthday_reminders")):
birthday_event = webnotes.conn.sql("""select name from `tabEvent` where repeat_on='Every Year'
and ref_type='Employee' and ref_name=%s""", self.doc.name)
starts_on = self.doc.date_of_birth + " 00:00:00"
ends_on = self.doc.date_of_birth + " 00:15:00"

View File

@ -2,12 +2,13 @@
{
"creation": "2013-03-07 09:04:18",
"docstatus": 0,
"modified": "2013-08-08 14:22:11",
"modified": "2013-10-11 10:52:53",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_attach": 1,
"allow_rename": 1,
"autoname": "naming_series:",
"doctype": "DocType",
"document_type": "Master",

View File

@ -10,7 +10,6 @@ from webnotes.model.doc import addchild, make_autoname
from webnotes.model.bean import copy_doclist
from webnotes import msgprint
sql = webnotes.conn.sql
import datetime

View File

@ -6,6 +6,24 @@
from __future__ import unicode_literals
import webnotes
from webnotes.utils import cint
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
self.doc, self.doclist = d, dl
def validate(self):
self.original_stop_birthday_reminders = cint(webnotes.conn.get_value("HR Settings",
None, "stop_birthday_reminders"))
def on_update(self):
# reset birthday reminders
if cint(self.doc.stop_birthday_reminders) != self.original_stop_birthday_reminders:
webnotes.conn.sql("""delete from `tabEvent` where repeat_on='Every Year' and ref_type='Employee'""")
if not self.doc.stop_birthday_reminders:
for employee in webnotes.conn.sql_list("""select name from `tabEmployee` where status='Active' and
ifnull(date_of_birth, '')!=''"""):
webnotes.get_obj("Employee", employee).update_dob_event()
webnotes.msgprint(webnotes._("Updated Birthday Reminders"))

View File

@ -2,7 +2,7 @@
{
"creation": "2013-08-02 13:45:23",
"docstatus": 0,
"modified": "2013-08-02 14:22:26",
"modified": "2013-10-02 15:44:38",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -38,6 +38,12 @@
"doctype": "DocType",
"name": "HR Settings"
},
{
"doctype": "DocField",
"fieldname": "employee_settings",
"fieldtype": "Section Break",
"label": "Employee Settings"
},
{
"description": "Employee record is created using selected field. ",
"doctype": "DocField",
@ -46,6 +52,19 @@
"label": "Employee Records to be created by",
"options": "Naming Series\nEmployee Number"
},
{
"description": "Don't send Employee Birthday Reminders",
"doctype": "DocField",
"fieldname": "stop_birthday_reminders",
"fieldtype": "Check",
"label": "Stop Birthday Reminders"
},
{
"doctype": "DocField",
"fieldname": "payroll_settings",
"fieldtype": "Section Break",
"label": "Payroll Settings"
},
{
"description": "If checked, Total no. of Working Days will include holidays, and this will reduce the value of Salary Per Day",
"doctype": "DocField",

View File

@ -37,7 +37,7 @@ class JobsMailbox(POP3Mailbox):
mail.save_attachments_in_doc(applicant.doc)
make(content=mail.content, sender=mail.from_email,
doctype="Job Applicant", name=applicant.doc.name)
doctype="Job Applicant", name=applicant.doc.name, sent_or_received="Received")
def get_job_applications():
if cint(webnotes.conn.get_value('Jobs Email Settings', None, 'extract_emails')):

View File

@ -11,14 +11,9 @@ from webnotes.utils import extract_email_id
class DocType(TransactionBase):
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
def get_sender(self, comm):
return webnotes.conn.get_value('Jobs Email Settings',None,'email_id')
def on_communication(self, comm):
if webnotes.conn.get_value("Profile", extract_email_id(comm.sender), "user_type")=="System User":
status = "Replied"
else:
status = "Open"
webnotes.conn.set(self.doc, 'status', status)
return webnotes.conn.get_value('Jobs Email Settings',None,'email_id')
def validate(self):
self.set_status()

View File

@ -5,7 +5,6 @@ from __future__ import unicode_literals
import webnotes
from webnotes.utils import cint, flt
from webnotes import msgprint
sql = webnotes.conn.sql
class DocType:
def __init__(self, doc, doclist):
@ -37,7 +36,7 @@ class DocType:
def check_existing_leave_allocation(self):
"""check whether leave for same type is already allocated or not"""
leave_allocation = sql("""select name from `tabLeave Allocation`
leave_allocation = webnotes.conn.sql("""select name from `tabLeave Allocation`
where employee=%s and leave_type=%s and fiscal_year=%s and docstatus=1""",
(self.doc.employee, self.doc.leave_type, self.doc.fiscal_year))
if leave_allocation:
@ -64,14 +63,14 @@ class DocType:
return self.get_leaves_allocated(prev_fyear) - self.get_leaves_applied(prev_fyear)
def get_leaves_applied(self, fiscal_year):
leaves_applied = sql("""select SUM(ifnull(total_leave_days, 0))
leaves_applied = webnotes.conn.sql("""select SUM(ifnull(total_leave_days, 0))
from `tabLeave Application` where employee=%s and leave_type=%s
and fiscal_year=%s and docstatus=1""",
(self.doc.employee, self.doc.leave_type, fiscal_year))
return leaves_applied and flt(leaves_applied[0][0]) or 0
def get_leaves_allocated(self, fiscal_year):
leaves_allocated = sql("""select SUM(ifnull(total_leaves_allocated, 0))
leaves_allocated = webnotes.conn.sql("""select SUM(ifnull(total_leaves_allocated, 0))
from `tabLeave Allocation` where employee=%s and leave_type=%s
and fiscal_year=%s and docstatus=1 and name!=%s""",
(self.doc.employee, self.doc.leave_type, fiscal_year, self.doc.name))
@ -79,7 +78,7 @@ class DocType:
def allow_carry_forward(self):
"""check whether carry forward is allowed or not for this leave type"""
cf = sql("""select is_carry_forward from `tabLeave Type` where name = %s""",
cf = webnotes.conn.sql("""select is_carry_forward from `tabLeave Type` where name = %s""",
self.doc.leave_type)
cf = cf and cint(cf[0][0]) or 0
if not cf:
@ -110,7 +109,7 @@ class DocType:
webnotes.conn.set(self.doc,'total_leaves_allocated',flt(leave_det['total_leaves_allocated']))
def check_for_leave_application(self):
exists = sql("""select name from `tabLeave Application`
exists = webnotes.conn.sql("""select name from `tabLeave Application`
where employee=%s and leave_type=%s and fiscal_year=%s and docstatus=1""",
(self.doc.employee, self.doc.leave_type, self.doc.fiscal_year))
if exists:

View File

@ -7,6 +7,9 @@ import unittest
from hr.doctype.leave_application.leave_application import LeaveDayBlockedError, OverlapError
class TestLeaveApplication(unittest.TestCase):
def tearDown(self):
webnotes.session.user = "Administrator"
def _clear_roles(self):
webnotes.conn.sql("""delete from `tabUserRole` where parent in
("test@example.com", "test1@example.com", "test2@example.com")""")
@ -15,6 +18,7 @@ class TestLeaveApplication(unittest.TestCase):
webnotes.conn.sql("""delete from `tabLeave Application`""")
def _add_employee_leave_approver(self, employee, leave_approver):
temp_session_user = webnotes.session.user
webnotes.session.user = "Administrator"
employee = webnotes.bean("Employee", employee)
employee.doclist.append({
@ -23,6 +27,7 @@ class TestLeaveApplication(unittest.TestCase):
"leave_approver": leave_approver
})
employee.save()
webnotes.session.user = temp_session_user
def get_application(self, doclist):
application = webnotes.bean(copy=doclist)
@ -31,7 +36,6 @@ class TestLeaveApplication(unittest.TestCase):
return application
def test_block_list(self):
webnotes.session.user = "Administrator"
self._clear_roles()
from webnotes.profile import add_role
@ -54,7 +58,6 @@ class TestLeaveApplication(unittest.TestCase):
self.assertTrue(application.insert())
def test_overlap(self):
webnotes.session.user = "Administrator"
self._clear_roles()
self._clear_applications()
@ -72,7 +75,6 @@ class TestLeaveApplication(unittest.TestCase):
self.assertRaises(OverlapError, application.insert)
def test_global_block_list(self):
webnotes.session.user = "Administrator"
self._clear_roles()
from webnotes.profile import add_role
@ -98,7 +100,6 @@ class TestLeaveApplication(unittest.TestCase):
"applies_to_all_departments", 0)
def test_leave_approval(self):
webnotes.session.user = "Administrator"
self._clear_roles()
from webnotes.profile import add_role

View File

@ -7,6 +7,9 @@ import unittest
from hr.doctype.leave_block_list.leave_block_list import get_applicable_block_dates
class TestLeaveBlockList(unittest.TestCase):
def tearDown(self):
webnotes.session.user = "Administrator"
def test_get_applicable_block_dates(self):
webnotes.session.user = "test@example.com"
webnotes.conn.set_value("Department", "_Test Department", "leave_block_list",

View File

@ -9,7 +9,6 @@ from webnotes.model.doc import Document
from webnotes.model.code import get_obj
from webnotes import msgprint
sql = webnotes.conn.sql
@ -34,7 +33,7 @@ class DocType:
emp_query = "select name from `tabEmployee` "
if flag == 1:
emp_query += condition
e = sql(emp_query)
e = webnotes.conn.sql(emp_query)
return e
# ----------------

View File

@ -11,7 +11,6 @@ from webnotes.model.bean import getlist, copy_doclist
from webnotes.model.code import get_obj
from webnotes import msgprint
sql = webnotes.conn.sql
@ -30,7 +29,7 @@ class DocType:
cond = self.get_filter_condition()
cond += self.get_joining_releiving_condition()
emp_list = sql("""
emp_list = webnotes.conn.sql("""
select t1.name
from `tabEmployee` t1, `tabSalary Structure` t2
where t1.docstatus!=2 and t2.docstatus != 2
@ -68,7 +67,7 @@ class DocType:
def get_month_details(self, year, month):
ysd = sql("select year_start_date from `tabFiscal Year` where name ='%s'"%year)[0][0]
ysd = webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name ='%s'"%year)[0][0]
if ysd:
from dateutil.relativedelta import relativedelta
import calendar, datetime
@ -96,7 +95,7 @@ class DocType:
emp_list = self.get_emp_list()
ss_list = []
for emp in emp_list:
if not sql("""select name from `tabSalary Slip`
if not webnotes.conn.sql("""select name from `tabSalary Slip`
where docstatus!= 2 and employee = %s and month = %s and fiscal_year = %s and company = %s
""", (emp[0], self.doc.month, self.doc.fiscal_year, self.doc.company)):
ss = webnotes.bean({
@ -127,7 +126,7 @@ class DocType:
which are not submitted
"""
cond = self.get_filter_condition()
ss_list = sql("""
ss_list = webnotes.conn.sql("""
select t1.name from `tabSalary Slip` t1
where t1.docstatus = 0 and month = '%s' and fiscal_year = '%s' %s
""" % (self.doc.month, self.doc.fiscal_year, cond))
@ -189,7 +188,7 @@ class DocType:
Get total salary amount from submitted salary slip based on selected criteria
"""
cond = self.get_filter_condition()
tot = sql("""
tot = webnotes.conn.sql("""
select sum(rounded_total) from `tabSalary Slip` t1
where t1.docstatus = 1 and month = '%s' and fiscal_year = '%s' %s
""" % (self.doc.month, self.doc.fiscal_year, cond))
@ -202,7 +201,7 @@ class DocType:
get default bank account,default salary acount from company
"""
amt = self.get_total_salary()
com = sql("select default_bank_account from `tabCompany` where name = '%s'" % self.doc.company)
com = webnotes.conn.sql("select default_bank_account from `tabCompany` where name = '%s'" % self.doc.company)
if not com[0][0] or not com[0][1]:
msgprint("You can set Default Bank Account in Company master.")

View File

@ -9,7 +9,7 @@ test_records = []
# from webnotes.model.doc import Document
# from webnotes.model.code import get_obj
# sql = webnotes.conn.sql
# webnotes.conn.sql = webnotes.conn.sql
#
# class TestSalaryManager(unittest.TestCase):
# def setUp(self):
@ -20,15 +20,15 @@ test_records = []
# ss1[0].employee = emp1.name
# for s in ss1: s.save(1)
# for s in ss1[1:]:
# sql("update `tabSalary Structure Earning` set parent = '%s' where name = '%s'" % (ss1[0].name, s.name))
# sql("update `tabSalary Structure Deduction` set parent = '%s' where name = '%s'" % (ss1[0].name, s.name))
# webnotes.conn.sql("update `tabSalary Structure Earning` set parent = '%s' where name = '%s'" % (ss1[0].name, s.name))
# webnotes.conn.sql("update `tabSalary Structure Deduction` set parent = '%s' where name = '%s'" % (ss1[0].name, s.name))
#
#
# ss2[0].employee = emp2.name
# for s in ss2: s.save(1)
# for s in ss2[1:]:
# sql("update `tabSalary Structure Earning` set parent = '%s' where name = '%s'" % (ss2[0].name, s.name))
# sql("update `tabSalary Structure Deduction` set parent = '%s' where name = '%s'" % (ss2[0].name, s.name))
# webnotes.conn.sql("update `tabSalary Structure Earning` set parent = '%s' where name = '%s'" % (ss2[0].name, s.name))
# webnotes.conn.sql("update `tabSalary Structure Deduction` set parent = '%s' where name = '%s'" % (ss2[0].name, s.name))
#
# sman.save()
# self.sm = get_obj('Salary Manager')
@ -36,7 +36,7 @@ test_records = []
# self.sm.create_sal_slip()
#
# def test_creation(self):
# ssid = sql("""
# ssid = webnotes.conn.sql("""
# select name, department
# from `tabSalary Slip`
# where month = '08' and fiscal_year='2011-2012'""")
@ -46,7 +46,7 @@ test_records = []
#
#
# def test_lwp_calc(self):
# ss = sql("""
# ss = webnotes.conn.sql("""
# select payment_days
# from `tabSalary Slip`
# where month = '08' and fiscal_year='2011-2012' and employee = '%s'

View File

@ -11,7 +11,6 @@ from webnotes.model.code import get_obj
from webnotes import msgprint, _
from setup.utils import get_company_currency
sql = webnotes.conn.sql
from utilities.transaction_base import TransactionBase
@ -32,7 +31,7 @@ class DocType(TransactionBase):
def check_sal_struct(self):
struct = sql("select name from `tabSalary Structure` where employee ='%s' and is_active = 'Yes' "%self.doc.employee)
struct = webnotes.conn.sql("select name from `tabSalary Structure` where employee ='%s' and is_active = 'Yes' "%self.doc.employee)
if not struct:
msgprint("Please create Salary Structure for employee '%s'"%self.doc.employee)
self.doc.employee = ''
@ -100,13 +99,13 @@ class DocType(TransactionBase):
return payment_days
def get_holidays_for_employee(self, m):
holidays = sql("""select t1.holiday_date
holidays = webnotes.conn.sql("""select t1.holiday_date
from `tabHoliday` t1, tabEmployee t2
where t1.parent = t2.holiday_list and t2.name = %s
and t1.holiday_date between %s and %s""",
(self.doc.employee, m['month_start_date'], m['month_end_date']))
if not holidays:
holidays = sql("""select t1.holiday_date
holidays = webnotes.conn.sql("""select t1.holiday_date
from `tabHoliday` t1, `tabHoliday List` t2
where t1.parent = t2.name and ifnull(t2.is_default, 0) = 1
and t2.fiscal_year = %s
@ -120,7 +119,7 @@ class DocType(TransactionBase):
for d in range(m['month_days']):
dt = add_days(cstr(m['month_start_date']), d)
if dt not in holidays:
leave = sql("""
leave = webnotes.conn.sql("""
select t1.name, t1.half_day
from `tabLeave Application` t1, `tabLeave Type` t2
where t2.name = t1.leave_type
@ -134,7 +133,7 @@ class DocType(TransactionBase):
return lwp
def check_existing(self):
ret_exist = sql("""select name from `tabSalary Slip`
ret_exist = webnotes.conn.sql("""select name from `tabSalary Slip`
where month = %s and fiscal_year = %s and docstatus != 2
and employee = %s and name != %s""",
(self.doc.month, self.doc.fiscal_year, self.doc.employee, self.doc.name))
@ -201,9 +200,9 @@ class DocType(TransactionBase):
receiver = webnotes.conn.get_value("Employee", self.doc.employee, "company_email")
if receiver:
subj = 'Salary Slip - ' + cstr(self.doc.month) +'/'+cstr(self.doc.fiscal_year)
earn_ret=sql("""select e_type, e_modified_amount from `tabSalary Slip Earning`
earn_ret=webnotes.conn.sql("""select e_type, e_modified_amount from `tabSalary Slip Earning`
where parent = %s""", self.doc.name)
ded_ret=sql("""select d_type, d_modified_amount from `tabSalary Slip Deduction`
ded_ret=webnotes.conn.sql("""select d_type, d_modified_amount from `tabSalary Slip Deduction`
where parent = %s""", self.doc.name)
earn_table = ''

View File

@ -8,7 +8,6 @@ from webnotes.utils import cstr, flt
from webnotes.model.doc import addchild, make_autoname
from webnotes import msgprint, _
sql = webnotes.conn.sql
class DocType:
def __init__(self,doc,doclist=[]):
@ -20,7 +19,7 @@ class DocType:
def get_employee_details(self):
ret = {}
det = sql("""select employee_name, branch, designation, department, grade
det = webnotes.conn.sql("""select employee_name, branch, designation, department, grade
from `tabEmployee` where name = %s""", self.doc.employee)
if det:
ret = {
@ -34,7 +33,7 @@ class DocType:
return ret
def get_ss_values(self,employee):
basic_info = sql("""select bank_name, bank_ac_no, esic_card_no, pf_number
basic_info = webnotes.conn.sql("""select bank_name, bank_ac_no, esic_card_no, pf_number
from `tabEmployee` where name =%s""", employee)
ret = {'bank_name': basic_info and basic_info[0][0] or '',
'bank_ac_no': basic_info and basic_info[0][1] or '',
@ -43,7 +42,7 @@ class DocType:
return ret
def make_table(self, doct_name, tab_fname, tab_name):
list1 = sql("select name from `tab%s` where docstatus != 2" % doct_name)
list1 = webnotes.conn.sql("select name from `tab%s` where docstatus != 2" % doct_name)
for li in list1:
child = addchild(self.doc, tab_fname, tab_name, self.doclist)
if(tab_fname == 'earning_details'):
@ -58,7 +57,7 @@ class DocType:
self.make_table('Deduction Type','deduction_details', 'Salary Structure Deduction')
def check_existing(self):
ret = sql("""select name from `tabSalary Structure` where is_active = 'Yes'
ret = webnotes.conn.sql("""select name from `tabSalary Structure` where is_active = 'Yes'
and employee = %s and name!=%s""", (self.doc.employee,self.doc.name))
if ret and self.doc.is_active=='Yes':
msgprint(_("""Another Salary Structure '%s' is active for employee '%s'.

View File

@ -9,7 +9,8 @@ from webnotes.utils import cstr, add_days, date_diff
from webnotes import msgprint, _
from webnotes.utils.datautils import UnicodeWriter
doclist = None
# doclist = None
doclist = webnotes.local('uploadattendance_doclist')
class DocType():
def __init__(self, doc, doclist=[]):
@ -21,9 +22,8 @@ def get_template():
if not webnotes.has_permission("Attendance", "create"):
raise webnotes.PermissionError
args = webnotes.form_dict
global doclist
doclist = webnotes.model.doctype.get("Attendance")
args = webnotes.local.form_dict
webnotes.local.uploadattendance_doclist = webnotes.model.doctype.get("Attendance")
w = UnicodeWriter()
w = add_header(w)
@ -144,4 +144,4 @@ def upload():
webnotes.conn.rollback()
else:
webnotes.conn.commit()
return {"messages": ret, "error": error}
return {"messages": ret, "error": error}

View File

@ -9,7 +9,6 @@ from webnotes.model.bean import getlist
from webnotes.model.code import get_obj
from webnotes import msgprint, _
sql = webnotes.conn.sql
class DocType:
@ -18,7 +17,7 @@ class DocType:
self.doclist = doclist
def autoname(self):
last_name = sql("""select max(name) from `tabBOM`
last_name = webnotes.conn.sql("""select max(name) from `tabBOM`
where name like "BOM/%s/%%" """ % cstr(self.doc.item).replace('"', '\\"'))
if last_name:
idx = cint(cstr(last_name[0][0]).split('/')[-1].split('-')[0]) + 1
@ -144,7 +143,7 @@ class DocType:
webnotes.bean(self.doclist).update_after_submit()
def get_bom_unitcost(self, bom_no):
bom = sql("""select name, total_cost/quantity as unit_cost from `tabBOM`
bom = webnotes.conn.sql("""select name, total_cost/quantity as unit_cost from `tabBOM`
where is_active = 1 and name = %s""", bom_no, as_dict=1)
return bom and bom[0]['unit_cost'] or 0
@ -156,7 +155,7 @@ class DocType:
from stock.utils import get_incoming_rate
dt = self.doc.costing_date or nowdate()
time = self.doc.costing_date == nowdate() and now().split()[1] or '23:59'
warehouse = sql("select warehouse from `tabBin` where item_code = %s", args['item_code'])
warehouse = webnotes.conn.sql("select warehouse from `tabBin` where item_code = %s", args['item_code'])
rate = []
for wh in warehouse:
r = get_incoming_rate({
@ -184,7 +183,7 @@ class DocType:
if not self.doc.is_active:
webnotes.conn.set(self.doc, "is_default", 0)
sql("update `tabItem` set default_bom = null where name = %s and default_bom = %s",
webnotes.conn.sql("update `tabItem` set default_bom = null where name = %s and default_bom = %s",
(self.doc.item, self.doc.name))
def clear_operations(self):
@ -250,7 +249,7 @@ class DocType:
def validate_bom_no(self, item, bom_no, idx):
"""Validate BOM No of sub-contracted items"""
bom = sql("""select name from `tabBOM` where name = %s and item = %s
bom = webnotes.conn.sql("""select name from `tabBOM` where name = %s and item = %s
and is_active=1 and docstatus=1""",
(bom_no, item), as_dict =1)
if not bom:
@ -272,7 +271,7 @@ class DocType:
for d in check_list:
bom_list, count = [self.doc.name], 0
while (len(bom_list) > count ):
boms = sql(" select %s from `tabBOM Item` where %s = '%s' " %
boms = webnotes.conn.sql(" select %s from `tabBOM Item` where %s = '%s' " %
(d[0], d[1], cstr(bom_list[count])))
count = count + 1
for b in boms:
@ -333,6 +332,7 @@ class DocType:
d.amount = flt(d.rate) * flt(d.qty)
d.qty_consumed_per_unit = flt(d.qty) / flt(self.doc.quantity)
total_rm_cost += d.amount
self.doc.raw_material_cost = total_rm_cost
def update_exploded_items(self):
@ -364,7 +364,7 @@ class DocType:
def get_child_exploded_items(self, bom_no, qty):
""" Add all items from Flat BOM of child BOM"""
child_fb_items = sql("""select item_code, description, stock_uom, qty, rate,
child_fb_items = webnotes.conn.sql("""select item_code, description, stock_uom, qty, rate,
qty_consumed_per_unit from `tabBOM Explosion Item`
where parent = %s and docstatus = 1""", bom_no, as_dict = 1)
@ -390,12 +390,12 @@ class DocType:
ch.save(1)
def get_parent_bom_list(self, bom_no):
p_bom = sql("select parent from `tabBOM Item` where bom_no = '%s'" % bom_no)
p_bom = webnotes.conn.sql("select parent from `tabBOM Item` where bom_no = '%s'" % bom_no)
return p_bom and [i[0] for i in p_bom] or []
def validate_bom_links(self):
if not self.doc.is_active:
act_pbom = sql("""select distinct bom_item.parent from `tabBOM Item` bom_item
act_pbom = webnotes.conn.sql("""select distinct bom_item.parent from `tabBOM Item` bom_item
where bom_item.bom_no = %s and bom_item.docstatus = 1
and exists (select * from `tabBOM` where name = bom_item.parent
and docstatus = 1 and is_active = 1)""", self.doc.name)
@ -403,4 +403,53 @@ class DocType:
if act_pbom and act_pbom[0][0]:
action = self.doc.docstatus < 2 and _("deactivate") or _("cancel")
msgprint(_("Cannot ") + action + _(": It is linked to other active BOM(s)"),
raise_exception=1)
raise_exception=1)
def get_bom_items_as_dict(bom, qty=1, fetch_exploded=1):
item_dict = {}
query = """select
bom_item.item_code,
ifnull(sum(bom_item.qty_consumed_per_unit),0) * %(qty)s as qty,
item.description,
item.stock_uom,
item.default_warehouse
from
`tab%(table)s` bom_item, `tabItem` item
where
bom_item.docstatus < 2
and bom_item.parent = "%(bom)s"
and item.name = bom_item.item_code
%(conditions)s
group by item_code, stock_uom"""
if fetch_exploded:
items = webnotes.conn.sql(query % {
"qty": qty,
"table": "BOM Explosion Item",
"bom": bom,
"conditions": """and ifnull(item.is_pro_applicable, 'No') = 'No'
and ifnull(item.is_sub_contracted_item, 'No') = 'No' """
}, as_dict=True)
else:
items = webnotes.conn.sql(query % {
"qty": qty,
"table": "BOM Item",
"bom": bom,
"conditions": ""
}, as_dict=True)
# make unique
for item in items:
if item_dict.has_key(item.item_code):
item_dict[item.item_code]["qty"] += flt(item.qty)
else:
item_dict[item.item_code] = item
return item_dict
@webnotes.whitelist()
def get_bom_items(bom, qty=1, fetch_exploded=1):
items = get_bom_items_as_dict(bom, qty, fetch_exploded).values()
items.sort(lambda a, b: a.item_code > b.item_code and 1 or -1)
return items

View File

@ -7,6 +7,35 @@ import unittest
import webnotes
test_records = [
[
{
"doctype": "BOM",
"item": "_Test Item Home Desktop Manufactured",
"quantity": 1.0,
"is_active": 1,
"is_default": 1,
"docstatus": 1
},
{
"doctype": "BOM Item",
"item_code": "_Test Serialized Item With Series",
"parentfield": "bom_materials",
"qty": 1.0,
"rate": 5000.0,
"amount": 5000.0,
"stock_uom": "_Test UOM"
},
{
"doctype": "BOM Item",
"item_code": "_Test Item 2",
"parentfield": "bom_materials",
"qty": 2.0,
"rate": 1000.0,
"amount": 2000.0,
"stock_uom": "_Test UOM"
}
],
[
{
"doctype": "BOM",
@ -34,5 +63,57 @@ test_records = [
"amount": 2000.0,
"stock_uom": "_Test UOM"
}
]
]
],
[
{
"doctype": "BOM",
"item": "_Test FG Item 2",
"quantity": 1.0,
"is_active": 1,
"is_default": 1,
"docstatus": 1
},
{
"doctype": "BOM Item",
"item_code": "_Test Item",
"parentfield": "bom_materials",
"qty": 1.0,
"rate": 5000.0,
"amount": 5000.0,
"stock_uom": "_Test UOM"
},
{
"doctype": "BOM Item",
"item_code": "_Test Item Home Desktop Manufactured",
"bom_no": "BOM/_Test Item Home Desktop Manufactured/001",
"parentfield": "bom_materials",
"qty": 2.0,
"rate": 1000.0,
"amount": 2000.0,
"stock_uom": "_Test UOM"
}
],
]
class TestBOM(unittest.TestCase):
def test_get_items(self):
from manufacturing.doctype.bom.bom import get_bom_items_as_dict
items_dict = get_bom_items_as_dict(bom="BOM/_Test FG Item 2/001", qty=1, fetch_exploded=0)
self.assertTrue(test_records[2][1]["item_code"] in items_dict)
self.assertTrue(test_records[2][2]["item_code"] in items_dict)
self.assertEquals(len(items_dict.values()), 2)
def test_get_items_exploded(self):
from manufacturing.doctype.bom.bom import get_bom_items_as_dict
items_dict = get_bom_items_as_dict(bom="BOM/_Test FG Item 2/001", qty=1, fetch_exploded=1)
self.assertTrue(test_records[2][1]["item_code"] in items_dict)
self.assertFalse(test_records[2][2]["item_code"] in items_dict)
self.assertTrue(test_records[0][1]["item_code"] in items_dict)
self.assertTrue(test_records[0][2]["item_code"] in items_dict)
self.assertEquals(len(items_dict.values()), 3)
def test_get_items_list(self):
from manufacturing.doctype.bom.bom import get_bom_items
self.assertEquals(len(get_bom_items(bom="BOM/_Test FG Item 2/001", qty=1, fetch_exploded=1)), 3)

View File

@ -8,7 +8,6 @@ from webnotes.utils import cstr, flt, nowdate
from webnotes.model.code import get_obj
from webnotes import msgprint, _
sql = webnotes.conn.sql
class OverProductionError(webnotes.ValidationError): pass
@ -18,19 +17,23 @@ class DocType:
self.doclist = doclist
def validate(self):
if self.doc.docstatus == 0:
self.doc.status = "Draft"
import utilities
utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Stopped",
"In Process", "Completed", "Cancelled"])
if self.doc.production_item :
item_detail = sql("select name from `tabItem` where name = '%s' and docstatus != 2"
% self.doc.production_item, as_dict = 1)
if not item_detail:
msgprint("Item '%s' does not exist or cancelled in the system."
% cstr(self.doc.production_item), raise_exception=1)
self.validate_bom_no()
self.validate_sales_order()
self.validate_warehouse()
from utilities.transaction_base import validate_uom_is_integer
validate_uom_is_integer(self.doclist, "stock_uom", ["qty", "produced_qty"])
def validate_bom_no(self):
if self.doc.bom_no:
bom = sql("""select name from `tabBOM` where name=%s and docstatus=1
bom = webnotes.conn.sql("""select name from `tabBOM` where name=%s and docstatus=1
and is_active=1 and item=%s"""
, (self.doc.bom_no, self.doc.production_item), as_dict =1)
if not bom:
@ -38,16 +41,20 @@ class DocType:
May be BOM not exists or inactive or not submitted
or for some other item.""" % cstr(self.doc.bom_no), raise_exception=1)
def validate_sales_order(self):
if self.doc.sales_order:
if not webnotes.conn.sql("""select name from `tabSales Order`
where name=%s and docstatus = 1""", self.doc.sales_order):
msgprint("Sales Order: %s is not valid" % self.doc.sales_order, raise_exception=1)
self.validate_production_order_against_so()
from utilities.transaction_base import validate_uom_is_integer
validate_uom_is_integer(self.doclist, "stock_uom", ["qty", "produced_qty"])
def validate_warehouse(self):
from stock.utils import validate_warehouse_user, validate_warehouse_company
for w in [self.doc.fg_warehouse, self.doc.wip_warehouse]:
validate_warehouse_user(w)
validate_warehouse_company(w, self.doc.company)
def validate_production_order_against_so(self):
# already ordered qty
@ -104,7 +111,7 @@ class DocType:
def on_cancel(self):
# Check whether any stock entry exists against this Production Order
stock_entry = sql("""select name from `tabStock Entry`
stock_entry = webnotes.conn.sql("""select name from `tabStock Entry`
where production_order = %s and docstatus = 1""", self.doc.name)
if stock_entry:
msgprint("""Submitted Stock Entry %s exists against this production order.
@ -144,12 +151,6 @@ def get_item_details(item):
@webnotes.whitelist()
def make_stock_entry(production_order_id, purpose):
production_order = webnotes.bean("Production Order", production_order_id)
# validate already existing
ste = webnotes.conn.get_value("Stock Entry", {
"production_order":production_order_id,
"purpose": purpose
}, "name")
stock_entry = webnotes.new_bean("Stock Entry")
stock_entry.doc.purpose = purpose

View File

@ -2,11 +2,12 @@
{
"creation": "2013-01-10 16:34:16",
"docstatus": 0,
"modified": "2013-08-08 14:22:12",
"modified": "2013-10-02 14:25:03",
"modified_by": "Administrator",
"owner": "Administrator"
},
{
"allow_import": 1,
"autoname": "naming_series:",
"doctype": "DocType",
"icon": "icon-cogs",

View File

@ -0,0 +1,75 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import unittest
import webnotes
from stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
from manufacturing.doctype.production_order.production_order import make_stock_entry
class TestProductionOrder(unittest.TestCase):
def test_planned_qty(self):
set_perpetual_inventory(0)
webnotes.conn.sql("delete from `tabStock Ledger Entry`")
webnotes.conn.sql("""delete from `tabBin`""")
webnotes.conn.sql("""delete from `tabGL Entry`""")
pro_bean = webnotes.bean(copy = test_records[0])
pro_bean.insert()
pro_bean.submit()
from stock.doctype.stock_entry.test_stock_entry import test_records as se_test_records
mr1 = webnotes.bean(copy = se_test_records[0])
mr1.insert()
mr1.submit()
mr2 = webnotes.bean(copy = se_test_records[0])
mr2.doclist[1].item_code = "_Test Item Home Desktop 100"
mr2.insert()
mr2.submit()
stock_entry = make_stock_entry(pro_bean.doc.name, "Manufacture/Repack")
stock_entry = webnotes.bean(stock_entry)
stock_entry.doc.fg_completed_qty = 4
stock_entry.run_method("get_items")
stock_entry.submit()
self.assertEqual(webnotes.conn.get_value("Production Order", pro_bean.doc.name,
"produced_qty"), 4)
self.assertEqual(webnotes.conn.get_value("Bin", {"item_code": "_Test FG Item",
"warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty"), 6)
return pro_bean.doc.name
def test_over_production(self):
from stock.doctype.stock_entry.stock_entry import StockOverProductionError
pro_order = self.test_planned_qty()
stock_entry = make_stock_entry(pro_order, "Manufacture/Repack")
stock_entry = webnotes.bean(stock_entry)
stock_entry.doc.fg_completed_qty = 15
stock_entry.run_method("get_items")
stock_entry.insert()
self.assertRaises(StockOverProductionError, stock_entry.submit)
test_records = [
[
{
"bom_no": "BOM/_Test FG Item/001",
"company": "_Test Company",
"doctype": "Production Order",
"production_item": "_Test FG Item",
"qty": 10.0,
"fg_warehouse": "_Test Warehouse 1 - _TC",
"wip_warehouse": "_Test Warehouse - _TC",
"stock_uom": "Nos"
}
]
]

View File

@ -9,7 +9,6 @@ from webnotes.model.bean import getlist
from webnotes.model.code import get_obj
from webnotes import msgprint, _
sql = webnotes.conn.sql
class DocType:
def __init__(self, doc, doclist=[]):
@ -19,7 +18,7 @@ class DocType:
def get_so_details(self, so):
"""Pull other details from so"""
so = sql("""select transaction_date, customer, grand_total
so = webnotes.conn.sql("""select transaction_date, customer, grand_total
from `tabSales Order` where name = %s""", so, as_dict = 1)
ret = {
'sales_order_date': so and so[0]['transaction_date'] or '',
@ -31,7 +30,7 @@ class DocType:
def get_item_details(self, item_code):
""" Pull other item details from item master"""
item = sql("""select description, stock_uom, default_bom
item = webnotes.conn.sql("""select description, stock_uom, default_bom
from `tabItem` where name = %s""", item_code, as_dict =1)
ret = {
'description' : item and item[0]['description'],
@ -63,7 +62,7 @@ class DocType:
if self.doc.fg_item:
item_filter += ' and item.name = "' + self.doc.fg_item + '"'
open_so = sql("""
open_so = webnotes.conn.sql("""
select distinct so.name, so.transaction_date, so.customer, so.grand_total
from `tabSales Order` so, `tabSales Order Item` so_item
where so_item.parent = so.name
@ -108,7 +107,7 @@ class DocType:
msgprint("Please enter sales order in the above table")
return []
items = sql("""select distinct parent, item_code, reserved_warehouse,
items = webnotes.conn.sql("""select distinct parent, item_code, reserved_warehouse,
(qty - ifnull(delivered_qty, 0)) as pending_qty
from `tabSales Order Item` so_item
where parent in (%s) and docstatus = 1 and ifnull(qty, 0) > ifnull(delivered_qty, 0)
@ -117,7 +116,7 @@ class DocType:
or ifnull(item.is_sub_contracted_item, 'No') = 'Yes'))""" % \
(", ".join(["%s"] * len(so_list))), tuple(so_list), as_dict=1)
dnpi_items = sql("""select distinct dnpi.parent, dnpi.item_code, dnpi.warehouse as reserved_warhouse,
dnpi_items = webnotes.conn.sql("""select distinct dnpi.parent, dnpi.item_code, dnpi.warehouse as reserved_warhouse,
(((so_item.qty - ifnull(so_item.delivered_qty, 0)) * dnpi.qty) / so_item.qty)
as pending_qty
from `tabSales Order Item` so_item, `tabDelivery Note Packing Item` dnpi
@ -136,7 +135,7 @@ class DocType:
self.clear_item_table()
for p in items:
item_details = sql("""select description, stock_uom, default_bom
item_details = webnotes.conn.sql("""select description, stock_uom, default_bom
from tabItem where name=%s""", p['item_code'])
pi = addchild(self.doc, 'pp_details', 'Production Plan Item', self.doclist)
pi.sales_order = p['parent']
@ -162,7 +161,7 @@ class DocType:
msgprint("Please enter bom no for item: %s at row no: %s" %
(d.item_code, d.idx), raise_exception=1)
else:
bom = sql("""select name from `tabBOM` where name = %s and item = %s
bom = webnotes.conn.sql("""select name from `tabBOM` where name = %s and item = %s
and docstatus = 1 and is_active = 1""",
(d.bom_no, d.item_code), as_dict = 1)
if not bom:
@ -216,14 +215,14 @@ class DocType:
pro = webnotes.new_bean("Production Order")
pro.doc.fields.update(items[key])
webnotes.mute_messages = True
webnotes.flags.mute_messages = True
try:
pro.insert()
pro_list.append(pro.doc.name)
except OverProductionError, e:
pass
webnotes.mute_messages = False
webnotes.flags.mute_messages = False
return pro_list
@ -243,7 +242,7 @@ class DocType:
for bom in bom_dict:
if self.doc.use_multi_level_bom:
# get all raw materials with sub assembly childs
fl_bom_items = sql("""select fb.item_code,
fl_bom_items = webnotes.conn.sql("""select fb.item_code,
ifnull(sum(fb.qty_consumed_per_unit), 0)*%s as qty,
fb.description, fb.stock_uom, it.min_order_qty
from `tabBOM Explosion Item` fb,`tabItem` it
@ -254,7 +253,7 @@ class DocType:
else:
# Get all raw materials considering SA items as raw materials,
# so no childs of SA items
fl_bom_items = sql("""select bom_item.item_code,
fl_bom_items = webnotes.conn.sql("""select bom_item.item_code,
ifnull(sum(bom_item.qty_consumed_per_unit), 0) * %s,
bom_item.description, bom_item.stock_uom, item.min_order_qty
from `tabBOM Item` bom_item, tabItem item
@ -274,7 +273,7 @@ class DocType:
'Quantity Requested for Purchase', 'Ordered Qty', 'Actual Qty']]
for d in self.item_dict:
item_list.append([d, self.item_dict[d][1], self.item_dict[d][2], self.item_dict[d][0]])
item_qty= sql("""select warehouse, indented_qty, ordered_qty, actual_qty
item_qty= webnotes.conn.sql("""select warehouse, indented_qty, ordered_qty, actual_qty
from `tabBin` where item_code = %s""", d)
i_qty, o_qty, a_qty = 0, 0, 0
for w in item_qty:

View File

@ -8,7 +8,6 @@ from webnotes.utils import flt
from webnotes.model import db_exists
from webnotes.model.bean import copy_doclist
sql = webnotes.conn.sql
@ -18,9 +17,9 @@ class DocType:
self.doclist = doclist
def update_bom_operation(self):
bom_list = sql(" select DISTINCT parent from `tabBOM Operation` where workstation = '%s'" % self.doc.name)
bom_list = webnotes.conn.sql(" select DISTINCT parent from `tabBOM Operation` where workstation = '%s'" % self.doc.name)
for bom_no in bom_list:
sql("update `tabBOM Operation` set hour_rate = '%s' where parent = '%s' and workstation = '%s'"%( self.doc.hour_rate, bom_no[0], self.doc.name))
webnotes.conn.sql("update `tabBOM Operation` set hour_rate = '%s' where parent = '%s' and workstation = '%s'"%( self.doc.hour_rate, bom_no[0], self.doc.name))
def on_update(self):
webnotes.conn.set(self.doc, 'overhead', flt(self.doc.hour_rate_electricity) + flt(self.doc.hour_rate_consumable) + flt(self.doc.hour_rate_rent))

Some files were not shown because too many files have changed in this diff Show More