diff --git a/erpnext/accounts/__init__.py b/erpnext/accounts/__init__.py index 0f98d2bc6a..c3c50052e4 100644 --- a/erpnext/accounts/__init__.py +++ b/erpnext/accounts/__init__.py @@ -1,4 +1,6 @@ import webnotes +from webnotes.utils import flt +from webnotes.model.code import get_obj def get_default_bank_account(): """ @@ -11,3 +13,208 @@ def get_default_bank_account(): WHERE name=%s AND docstatus<2""", company) if res: return res[0][0] + + +def get_new_jv_details(): + """ + Get details which will help create new jv on sales/purchase return + """ + doclist = webnotes.form_dict.get('doclist') + fiscal_year = webnotes.form_dict.get('fiscal_year') + if not (isinstance(doclist, basestring) and isinstance(fiscal_year, basestring)): return + + import json + doclist = json.loads(doclist) + doc, children = doclist[0], doclist[1:] + + if doc.get('return_type')=='Sales Return': + if doc.get('sales_invoice_no'): + return get_invoice_details(doc, children, fiscal_year) + elif doc.get('delivery_note_no'): + return get_delivery_note_details(doc, children, fiscal_year) + + elif doc.get('purchase_receipt_no'): + return get_purchase_receipt_details(doc, children, fiscal_year) + + +def get_invoice_details(doc, children, fiscal_year): + """ + Gets details from an invoice to make new jv + Returns [{ + 'account': , + 'balance': , + 'debit': , + 'credit': , + 'against_invoice': , + 'against_payable': + }, { ... }, ...] + """ + if doc.get('return_type')=='Sales Return': + obj = get_obj('Receivable Voucher', doc.get('sales_invoice_no'), with_children=1) + else: + obj = get_obj('Payable Voucher', doc.get('purchase_invoice_no'), with_children=1) + if not obj.doc.docstatus==1: return + + # Build invoice account jv detail record + invoice_rec = get_invoice_account_jv_record(doc, children, fiscal_year, obj) + + # Build item accountwise jv detail records + item_accountwise_list = get_item_accountwise_jv_record(doc, children, fiscal_year, obj) + + return [invoice_rec] + item_accountwise_list + + +def get_invoice_account_jv_record(doc, children, fiscal_year, obj): + """ + Build customer/supplier account jv detail record + """ + # Calculate total return amount + total_amt = sum([(flt(ch.get('rate')) * flt(ch.get('returned_qty'))) for ch in children]) + + ret = {} + + if doc.get('return_type')=='Sales Return': + account = obj.doc.debit_to + ret['against_invoice'] = doc.get('sales_invoice_no') + ret['credit'] = total_amt + else: + account = obj.doc.credit_to + ret['against_voucher'] = doc.get('purchase_invoice_no') + ret['debit'] = total_amt + + ret.update({ + 'account': account, + 'balance': get_obj('GL Control').get_bal(account + "~~~" + fiscal_year) + }) + + return ret + + +def get_item_accountwise_jv_record(doc, children, fiscal_year, obj): + """ + Build item accountwise jv detail records + """ + if doc.get('return_type')=='Sales Return': + amt_field = 'debit' + ac_field = 'income_account' + else: + amt_field = 'credit' + ac_field = 'expense_head' + + inv_children = dict([[ic.fields.get('item_code'), ic] for ic in obj.doclist if ic.fields.get('item_code')]) + + accwise_list = [] + + for ch in children: + inv_ch = inv_children.get(ch.get('item_code')) + if not inv_ch: continue + + amount = flt(ch.get('rate')) * flt(ch.get('returned_qty')) + + accounts = [[jvd['account'], jvd['cost_center']] for jvd in accwise_list] + + if [inv_ch.fields.get(ac_field), inv_ch.fields.get('cost_center')] not in accounts: + rec = { + 'account': inv_ch.fields.get(ac_field), + 'cost_center': inv_ch.fields.get('cost_center'), + 'balance': get_obj('GL Control').get_bal(inv_ch.fields.get(ac_field) + "~~~" + fiscal_year) + } + rec[amt_field] = amount + accwise_list.append(rec) + else: + rec = accwise_list[accounts.index([inv_ch.fields.get(ac_field), inv_ch.fields.get('cost_center')])] + rec[amt_field] = rec[amt_field] + amount + + return accwise_list + + +def get_jv_details_from_inv_list(doc, children, fiscal_year, inv_list, jv_details_list): + """ + Get invoice details and make jv detail records + """ + for inv in inv_list: + if not inv[0]: continue + + if doc.get('return_type')=='Sales Return': + doc['sales_invoice_no'] = inv[0] + else: + doc['purchase_invoice_no'] = inv[0] + + jv_details = get_invoice_details(doc, children, fiscal_year) + + if jv_details and len(jv_details)>1: jv_details_list.extend(jv_details) + + return jv_details_list + + +def get_prev_doc_list(obj, prev_doctype): + """ + Returns a list of previous doc's names + """ + prevdoc_list = [] + for ch in obj.doclist: + if ch.fields.get('prevdoc_docname') and ch.fields.get('prevdoc_doctype')==prev_doctype: + prevdoc_list.append(ch.fields.get('prevdoc_docname')) + return prevdoc_list + + +def get_inv_list(table, field, value): + """ + Returns invoice list + """ + if isinstance(value, basestring): + return webnotes.conn.sql("""\ + SELECT DISTINCT parent FROM `%s` + WHERE %s='%s' AND docstatus=1""" % (table, field, value)) + elif isinstance(value, list): + return webnotes.conn.sql("""\ + SELECT DISTINCT parent FROM `%s` + WHERE %s IN ("%s") AND docstatus=1""" % (table, field, '", "'.join(value))) + else: + return [] + + +def get_delivery_note_details(doc, children, fiscal_year): + """ + Gets sales invoice numbers from delivery note details + and returns detail records for jv + """ + jv_details_list = [] + + dn_obj = get_obj('Delivery Note', doc['delivery_note_no'], with_children=1) + + inv_list = get_inv_list('tabRV Detail', 'delivery_note', doc['delivery_note_no']) + + if inv_list: + jv_details_list = get_jv_details_from_inv_list(doc, children, fiscal_year, inv_list, jv_details_list) + + if not (inv_list and jv_details_list): + so_list = get_prev_doc_list(dn_obj, 'Sales Order') + inv_list = get_inv_list('tabRV Detail', 'sales_order', so_list) + if inv_list: + jv_details_list = get_jv_details_from_inv_list(doc, children, fiscal_year, inv_list, jv_details_list) + + return jv_details_list + + +def get_purchase_receipt_details(doc, children, fiscal_year): + """ + Gets purchase invoice numbers from purchase receipt details + and returns detail records for jv + """ + jv_details_list = [] + + pr_obj = get_obj('Purchase Receipt', doc['purchase_receipt_no'], with_children=1) + + inv_list = get_inv_list('tabPV Detail', 'purchase_receipt', doc['purchase_receipt_no']) + + if inv_list: + jv_details_list = get_jv_details_from_inv_list(doc, children, fiscal_year, inv_list, jv_details_list) + + if not (inv_list and jv_details_list): + po_list = get_prev_doc_list(pr_obj, 'Purchase Order') + inv_list = get_inv_list('tabPV Detail', 'purchase_order', po_list) + if inv_list: + jv_details_list = get_jv_details_from_inv_list(doc, children, fiscal_year, inv_list, jv_details_list) + + return jv_details_list diff --git a/erpnext/accounts/doctype/payable_voucher/payable_voucher.js b/erpnext/accounts/doctype/payable_voucher/payable_voucher.js index 44dea8a598..3bdeadddd8 100644 --- a/erpnext/accounts/doctype/payable_voucher/payable_voucher.js +++ b/erpnext/accounts/doctype/payable_voucher/payable_voucher.js @@ -61,12 +61,16 @@ cur_frm.cscript.supplier = function(doc,dt,dn) { } var callback2 = function(r,rt){ - var doc = locals[cur_frm.doctype][cur_frm.docname]; + var doc = locals[cur_frm.doctype][cur_frm.docname]; var el = getchildren('PV Detail',doc.name,'entries'); for(var i in el){ if(el[i].item_code && (!el[i].expense_head || !el[i].cost_center)){ - args = "{'item_code':'" + el[i].item_code + "','expense_head':'" + el[i].expense_head + "','cost_center':'" + el[i].cost_center + "'}"; - get_server_fields('get_default_values', args, 'entries', doc, el[i].doctype, el[i].name, 1); + args = { + item_code: el[i].item_code, + expense_head: el[i].expense_head, + cost_center: el[i].cost_center + }; + get_server_fields('get_default_values', JSON.stringify(args), 'entries', doc, el[i].doctype, el[i].name, 1); } } cur_frm.cscript.calc_amount(doc, 1); diff --git a/erpnext/accounts/doctype/payable_voucher/payable_voucher.py b/erpnext/accounts/doctype/payable_voucher/payable_voucher.py index e220756a81..14d5e5e863 100644 --- a/erpnext/accounts/doctype/payable_voucher/payable_voucher.py +++ b/erpnext/accounts/doctype/payable_voucher/payable_voucher.py @@ -61,7 +61,8 @@ class DocType(TransactionBase): # Get Default Cost Center and Expense Head from Item Master # ---------------------------------------------------------- def get_default_values(self,args): - args = eval(args) + import json + args = json.loads(args) ret = {} if sql("select name from `tabItem` where name = '%s'" % args['item_code']): if not args['expense_head'] or args['expense_head'] == 'undefined': @@ -105,6 +106,7 @@ class DocType(TransactionBase): def get_pv_details(self, arg): + import json item_det = sql("select item_name, brand, description, item_group,purchase_account,cost_center from tabItem where name=%s",arg,as_dict=1) tax = sql("select tax_type, tax_rate from `tabItem Tax` where parent = %s" , arg) t = {} @@ -119,7 +121,7 @@ class DocType(TransactionBase): 'amount' : 0.00, 'expense_head' : item_det and item_det[0]['purchase_account'] or '', 'cost_center' : item_det and item_det[0]['cost_center'] or '', - 'item_tax_rate' : str(t) + 'item_tax_rate' : json.dumps(t) } return ret diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js index 541a225e36..d7d88bbbc2 100644 --- a/erpnext/buying/doctype/purchase_common/purchase_common.js +++ b/erpnext/buying/doctype/purchase_common/purchase_common.js @@ -34,7 +34,7 @@ cur_frm.cscript.load_defaults = function(doc, dt, dn) { // Update existing item details cur_frm.cscript.update_item_details = function(doc, dt, dn) { - if(!cur_frm.doc.__islocal) return; + if(!cur_frm.doc.__islocal) { return; } var children = getchildren(cur_frm.cscript.tname, doc.name, cur_frm.cscript.fname); if(children) { $c_obj(make_doclist(doc.doctype, doc.name), 'get_item_details', '', diff --git a/erpnext/home/page/event_updates/event_updates.js b/erpnext/home/page/event_updates/event_updates.js index ee348e6307..74f12d8147 100644 --- a/erpnext/home/page/event_updates/event_updates.js +++ b/erpnext/home/page/event_updates/event_updates.js @@ -585,6 +585,7 @@ HomeStatusBar = function() { this.wrapper.innerHTML = ''; this.profile_settings = $a($a(this.wrapper, 'p'), 'span', 'link_type', {fontWeight:'bold'}); this.profile_settings.innerHTML = user_fullname + ' (Profile Settings)'; + this.profile_settings.id = "user_fullname"; this.profile_settings.onclick = function() { loadpage('profile-settings'); } this.span = $a($a(this.wrapper, 'p'), 'span', 'link_type', {fontWeight:'bold'}); @@ -614,7 +615,7 @@ pscript.home_make_status = function() { // complete registration if(in_list(user_roles,'System Manager')) { - pscript.complete_registration(r.message.registration_complete); + pscript.complete_registration(r.message.registration_complete, r.message.profile); } // setup wizard @@ -627,15 +628,19 @@ pscript.home_make_status = function() { // complete my company registration // -------------------------------- -pscript.complete_registration = function(is_complete) { +pscript.complete_registration = function(is_complete, profile) { if(is_complete == 'No'){ - var d = new Dialog(400, 200, "Please Complete Your Registration"); + var d = new Dialog(400, 200, "Setup your Account"); if(user != 'Administrator'){ d.no_cancel(); // Hide close image $dh(page_body.wntoolbar.wrapper); } d.make_body([ + ['HTML', 'Your Profile Details', '

Your Profile Details

'], + ['Data', 'First Name'], + ['Data', 'Last Name'], + ['HTML', 'Company Details', '

Create your first company

'], ['Data','Company Name','Example: Your Company LLC'], ['Data','Company Abbreviation', 'Example: YC (all your acconts will have this as a suffix)'], ['Select','Fiscal Year Start Date'], @@ -649,7 +654,16 @@ pscript.complete_registration = function(is_complete) { d.widgets['Company Name'].value = locals['Control Panel']['Control Panel'].company_name; d.widgets['Company Name'].disabled = 1; } - + + if(profile && profile.length>0) { + if(profile[0].first_name && profile[0].first_name!='None') { + d.widgets['First Name'].value = profile[0].first_name; + } + + if(profile[0].last_name && profile[0].last_name!='None') { + d.widgets['Last Name'].value = profile[0].last_name; + } + } //d.widgets['Save'].disabled = true; // disable Save button pscript.make_dialog_field(d); @@ -666,14 +680,20 @@ pscript.complete_registration = function(is_complete) { d.widgets['Company Name'].value, d.widgets['Company Abbreviation'].value, d.widgets['Fiscal Year Start Date'].value, - d.widgets['Default Currency'].value + d.widgets['Default Currency'].value, + d.widgets['First Name'].value, + d.widgets['Last Name'].value ]; $c_obj('Setup Control','setup_account',JSON.stringify(args),function(r, rt){ - sys_defaults = r.message; + sys_defaults = r.message.sys_defaults; + user_fullname = r.message.user_fullname; d.hide(); $ds(page_body.wntoolbar.wrapper); + $('#user_fullname').html(user_fullname + " (Profile Settings)"); }); + } else { + d.widgets['Save'].done_working(); } } d.show(); @@ -699,12 +719,12 @@ pscript.make_dialog_field = function(d) // --------------- pscript.validate_fields = function(d) { - var lst = ['Company Abbreviation', 'Fiscal Year Start Date', 'Default Currency']; - var msg = 'Please enter the following fields'; + var lst = ['First Name', 'Company Name', 'Company Abbreviation', 'Fiscal Year Start Date', 'Default Currency']; + var msg = 'Please enter the following fields\n'; var flag = 1; for(var i=0; i cl[i].qty) { - msgprint("Returned Qty can not be greater than qty. Please check for item: " + cl[i].item_code); - flag = 1 - } - } - return flag + flag = 0 + for(var i = 0; i cl[i].qty) { + msgprint("Returned Qty can not be greater than qty. Please check for item: " + cl[i].item_code); + flag = 1 + } + } + return flag } // map parent fields of stock entry //---------------------------------- cur_frm.cscript.map_parent_fields = function(doc, cdt, cdn) { - var se = LocalDB.create('Stock Entry'); - se = locals['Stock Entry'][se]; - se.posting_date = dateutil.obj_to_str(new Date()); - se.transfer_date = dateutil.obj_to_str(new Date()); - se.fiscal_year = sys_defaults.fiscal_year; - se.purpose = doc.return_type; - se.remarks = doc.return_type + ' of ' + (doc.delivery_note_no || doc.sales_invoice_no || doc.purchase_receipt_no); - if(doc.return_type == 'Sales Return'){ - se.delivery_note_no = doc.delivery_note_no; - se.sales_invoice_no = doc.sales_invoice_no; - se.customer = doc.cust_supp_name; - se.customer_name = doc.cust_supp_name; - se.customer_address = doc.cust_supp_address; - } - else if(doc.return_type == 'Purchase Return'){ - se.purchase_receipt_no = doc.purchase_receipt_no; - se.supplier = doc.cust_supp_name; - se.supplier_name = doc.cust_supp_name; - se.supplier_address = doc.cust_supp_address; - } - return se + var se = LocalDB.create('Stock Entry'); + se = locals['Stock Entry'][se]; + se.posting_date = dateutil.obj_to_str(new Date()); + se.transfer_date = dateutil.obj_to_str(new Date()); + se.fiscal_year = sys_defaults.fiscal_year; + se.purpose = doc.return_type; + se.remarks = doc.return_type + ' of ' + (doc.delivery_note_no || doc.sales_invoice_no || doc.purchase_receipt_no); + if(doc.return_type == 'Sales Return'){ + se.delivery_note_no = doc.delivery_note_no; + se.sales_invoice_no = doc.sales_invoice_no; + se.customer = doc.cust_supp_name; + se.customer_name = doc.cust_supp_name; + se.customer_address = doc.cust_supp_address; + } + else if(doc.return_type == 'Purchase Return'){ + se.purchase_receipt_no = doc.purchase_receipt_no; + se.supplier = doc.cust_supp_name; + se.supplier_name = doc.cust_supp_name; + se.supplier_address = doc.cust_supp_address; + } + return se } // map child fields of stock entry //--------------------------------- cur_frm.cscript.map_child_fields = function(cl, se) { - for(var i = 0; i