mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-17 02:26:33 +00:00
moved directory structure
This commit is contained in:
1
selling/doctype/__init__.py
Normal file
1
selling/doctype/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
1
selling/doctype/campaign/__init__.py
Normal file
1
selling/doctype/campaign/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
26
selling/doctype/campaign/campaign.js
Normal file
26
selling/doctype/campaign/campaign.js
Normal file
@@ -0,0 +1,26 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
//--------- ONLOAD -------------
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
|
||||
}
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
|
||||
}
|
||||
162
selling/doctype/campaign/campaign.txt
Normal file
162
selling/doctype/campaign/campaign.txt
Normal file
@@ -0,0 +1,162 @@
|
||||
# DocType, Campaign
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-07-03 13:30:38',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-07-12 13:21:52',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1326102553',
|
||||
'allow_trash': 1,
|
||||
'autoname': u'field:campaign_name',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'description': u'Keep Track of Sales Campaigns. Keep track of Leads, Quotations, Sales Order etc from Campaigns to gauge Return on Investment. ',
|
||||
'doctype': 'DocType',
|
||||
'document_type': u'Master',
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Campaign',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Campaign',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1,
|
||||
'submit': 0
|
||||
},
|
||||
|
||||
# DocType, Campaign
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Campaign'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales Manager',
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Manager',
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales Master Manager',
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales User',
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales User',
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Master Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'trash_reason',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Trash Reason',
|
||||
'oldfieldname': u'trash_reason',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'campaign',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Campaign',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'campaign_name',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Campaign Name',
|
||||
'oldfieldname': u'campaign_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Text',
|
||||
'permlevel': 0,
|
||||
'width': u'300px'
|
||||
}
|
||||
]
|
||||
1
selling/doctype/customer/__init__.py
Normal file
1
selling/doctype/customer/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
209
selling/doctype/customer/customer.js
Normal file
209
selling/doctype/customer/customer.js
Normal file
@@ -0,0 +1,209 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
wn.require('erpnext/setup/doctype/contact_control/contact_control.js');
|
||||
wn.require('erpnext/support/doctype/communication/communication.js');
|
||||
|
||||
/* ********************************* onload ********************************************* */
|
||||
|
||||
cur_frm.cscript.onload = function(doc,dt,dn){
|
||||
// history doctypes and scripts
|
||||
cur_frm.history_dict = {
|
||||
'Quotation' : 'cur_frm.cscript.make_qtn_list(this.body, this.doc)',
|
||||
'Sales Order' : 'cur_frm.cscript.make_so_list(this.body, this.doc)',
|
||||
'Delivery Note' : 'cur_frm.cscript.make_dn_list(this.body, this.doc)',
|
||||
'Sales Invoice' : 'cur_frm.cscript.make_si_list(this.body, this.doc)'
|
||||
}
|
||||
// make address, contact, shipping, history list body
|
||||
cur_frm.cscript.make_hl_body();
|
||||
//cur_frm.cscript.make_sl_body();
|
||||
|
||||
cur_frm.cscript.load_defaults(doc, dt, dn);
|
||||
|
||||
cur_frm.cscript.make_communication_body();
|
||||
}
|
||||
|
||||
cur_frm.cscript.load_defaults = function(doc, dt, dn) {
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
if(!(doc.__islocal && doc.lead_name)) { return; }
|
||||
|
||||
var fields_to_refresh = LocalDB.set_default_values(doc);
|
||||
if(fields_to_refresh) { refresh_many(fields_to_refresh); }
|
||||
}
|
||||
|
||||
cur_frm.add_fetch('lead_name', 'company_name', 'customer_name');
|
||||
cur_frm.add_fetch('default_sales_partner','commission_rate','default_commission_rate');
|
||||
|
||||
/* ********************************* refresh ********************************************* */
|
||||
|
||||
cur_frm.cscript.refresh = function(doc,dt,dn) {
|
||||
if(sys_defaults.cust_master_name == 'Customer Name')
|
||||
hide_field('naming_series');
|
||||
else
|
||||
unhide_field('naming_series');
|
||||
|
||||
if(doc.__islocal){
|
||||
hide_field(['address_html','contact_html']);
|
||||
//cur_frm.cscript.set_hl_msg(doc);
|
||||
//cur_frm.cscript.set_sl_msg(doc);
|
||||
}else{
|
||||
unhide_field(['address_html','contact_html']);
|
||||
// make lists
|
||||
cur_frm.cscript.make_address(doc,dt,dn);
|
||||
cur_frm.cscript.make_contact(doc,dt,dn);
|
||||
cur_frm.cscript.make_history(doc,dt,dn);
|
||||
cur_frm.cscript.render_communication_list(doc, cdt, cdn);
|
||||
//cur_frm.cscript.make_shipping_address(doc,dt,dn);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.make_address = function() {
|
||||
if(!cur_frm.address_list) {
|
||||
cur_frm.address_list = new wn.ui.Listing({
|
||||
parent: cur_frm.fields_dict['address_html'].wrapper,
|
||||
page_length: 2,
|
||||
new_doctype: "Address",
|
||||
get_query: function() {
|
||||
return "select name, address_type, address_line1, address_line2, city, state, country, pincode, fax, email_id, phone, is_primary_address, is_shipping_address from tabAddress where customer='"+cur_frm.docname+"' and docstatus != 2 order by is_primary_address desc"
|
||||
},
|
||||
as_dict: 1,
|
||||
no_results_message: 'No addresses created',
|
||||
render_row: cur_frm.cscript.render_address_row,
|
||||
});
|
||||
// note: render_address_row is defined in contact_control.js
|
||||
}
|
||||
cur_frm.address_list.run();
|
||||
}
|
||||
|
||||
cur_frm.cscript.make_contact = function() {
|
||||
if(!cur_frm.contact_list) {
|
||||
cur_frm.contact_list = new wn.ui.Listing({
|
||||
parent: cur_frm.fields_dict['contact_html'].wrapper,
|
||||
page_length: 2,
|
||||
new_doctype: "Contact",
|
||||
get_query: function() {
|
||||
return "select name, first_name, last_name, email_id, phone, mobile_no, department, designation, is_primary_contact from tabContact where customer='"+cur_frm.docname+"' and docstatus != 2 order by is_primary_contact desc"
|
||||
},
|
||||
as_dict: 1,
|
||||
no_results_message: 'No contacts created',
|
||||
render_row: cur_frm.cscript.render_contact_row,
|
||||
});
|
||||
// note: render_contact_row is defined in contact_control.js
|
||||
}
|
||||
cur_frm.contact_list.run();
|
||||
|
||||
}
|
||||
|
||||
/* ********************************* client triggers ************************************** */
|
||||
|
||||
// ---------------
|
||||
// customer group
|
||||
// ---------------
|
||||
cur_frm.fields_dict['customer_group'].get_query = function(doc,dt,dn) {
|
||||
return 'SELECT `tabCustomer Group`.`name`, `tabCustomer Group`.`parent_customer_group` FROM `tabCustomer Group` WHERE `tabCustomer Group`.`is_group` = "No" AND `tabCustomer Group`.`docstatus`!= 2 AND `tabCustomer Group`.%(key)s LIKE "%s" ORDER BY `tabCustomer Group`.`name` ASC LIMIT 50';
|
||||
}
|
||||
|
||||
|
||||
// -----
|
||||
// lead
|
||||
// -----
|
||||
cur_frm.fields_dict['lead_name'].get_query = function(doc,dt,dn){
|
||||
return 'SELECT `tabLead`.`name` FROM `tabLead` WHERE `tabLead`.`status`!="Converted" AND `tabLead`.%(key)s LIKE "%s" ORDER BY `tabLead`.`name` ASC LIMIT 50';
|
||||
}
|
||||
|
||||
|
||||
// Transaction History
|
||||
// functions called by these functions are defined in communication.js
|
||||
cur_frm.cscript.make_qtn_list = function(parent, doc) {
|
||||
cur_frm.cscript.get_common_list_view(parent, doc, 'Quotation');
|
||||
}
|
||||
|
||||
cur_frm.cscript.make_so_list = function(parent, doc) {
|
||||
cur_frm.cscript.get_common_list_view(parent, doc, 'Sales Order');
|
||||
}
|
||||
|
||||
cur_frm.cscript.make_dn_list = function(parent, doc) {
|
||||
cur_frm.cscript.get_common_list_view(parent, doc, 'Delivery Note');
|
||||
}
|
||||
|
||||
cur_frm.cscript.get_common_list_view = function(parent, doc, doctype) {
|
||||
var ListView = wn.views.ListView.extend({
|
||||
init: function(doclistview) {
|
||||
this._super(doclistview);
|
||||
this.fields = this.fields.concat([
|
||||
"`tab" + doctype + "`.status",
|
||||
"`tab" + doctype + "`.currency",
|
||||
"ifnull(`tab" + doctype + "`.grand_total_export, 0) as grand_total_export",
|
||||
|
||||
]);
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
data.grand_total_export = data.currency + " " + fmt_money(data.grand_total_export)
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content: 'docstatus'},
|
||||
{width: '25%', content: 'name'},
|
||||
{width: '25%', content: 'status'},
|
||||
{width: '35%', content: 'grand_total_export', css: {'text-align': 'right'}},
|
||||
{width: '12%', content:'modified', css: {'text-align': 'right'}}
|
||||
],
|
||||
});
|
||||
|
||||
cur_frm.cscript.render_list(doc, doctype, parent, ListView);
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.make_si_list = function(parent, doc) {
|
||||
var ListView = wn.views.ListView.extend({
|
||||
init: function(doclistview) {
|
||||
this._super(doclistview);
|
||||
this.fields = this.fields.concat([
|
||||
"ifnull(`tabSales Invoice`.outstanding_amount, 0) as outstanding_amount",
|
||||
"`tabSales Invoice`.currency",
|
||||
"ifnull(`tabSales Invoice`.conversion_rate, 0) as conversion_rate",
|
||||
"ifnull(`tabSales Invoice`.grand_total_export, 0) as grand_total_export",
|
||||
|
||||
]);
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
if (data.outstanding_amount) {
|
||||
data.outstanding_amount = data.currency + " " +
|
||||
fmt_money(flt(data.outstanding_amount)/flt(data.conversion_rate)) +
|
||||
" [outstanding]";
|
||||
|
||||
} else {
|
||||
data.outstanding_amount = '';
|
||||
}
|
||||
data.grand_total_export = data.currency + " " + fmt_money(data.grand_total_export);
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content: 'docstatus'},
|
||||
{width: '25%', content: 'name'},
|
||||
{width: '25%', content: 'outstanding_amount',
|
||||
css: {'text-align': 'right', 'color': '#777'}},
|
||||
{width: '35%', content: 'grand_total_export', css: {'text-align': 'right'}},
|
||||
{width: '12%', content:'modified', css: {'text-align': 'right'}}
|
||||
],
|
||||
});
|
||||
|
||||
cur_frm.cscript.render_list(doc, 'Sales Invoice', parent, ListView);
|
||||
}
|
||||
288
selling/doctype/customer/customer.py
Normal file
288
selling/doctype/customer/customer.py
Normal file
@@ -0,0 +1,288 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import cstr, date_diff, flt, formatdate, get_defaults, getdate, has_common, now, nowdate, replace_newlines, sendmail, set_default, user_format, validate_email_add
|
||||
from webnotes.model.doc import Document, make_autoname
|
||||
from webnotes.model.code import get_obj
|
||||
from webnotes import msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
class DocType:
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
|
||||
# ******************************************************* autoname ***********************************************************
|
||||
def autoname(self):
|
||||
cust_master_name = get_defaults().get('cust_master_name')
|
||||
if cust_master_name == 'Customer Name':
|
||||
# filter out bad characters in name
|
||||
#cust = self.doc.customer_name.replace('&','and').replace('.','').replace("'",'').replace('"','').replace(',','').replace('`','')
|
||||
cust = self.doc.customer_name
|
||||
|
||||
supp = sql("select name from `tabSupplier` where name = %s", (cust))
|
||||
supp = supp and supp[0][0] or ''
|
||||
if supp:
|
||||
msgprint("You already have a Supplier with same name")
|
||||
raise Exception("You already have a Supplier with same name")
|
||||
else:
|
||||
self.doc.name = cust
|
||||
else:
|
||||
self.doc.name = make_autoname(self.doc.naming_series+'.#####')
|
||||
|
||||
|
||||
# ******************************************************* triggers ***********************************************************
|
||||
# ----------------
|
||||
# get company abbr
|
||||
# -----------------
|
||||
def get_company_abbr(self):
|
||||
return get_value('Company', self.doc.company, 'abbr')
|
||||
|
||||
# -----------------------------------------------------------------------------------------------------
|
||||
# get parent account(i.e receivables group from company where default account head need to be created)
|
||||
# -----------------------------------------------------------------------------------------------------
|
||||
def get_receivables_group(self):
|
||||
g = sql("select receivables_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 Receivables")
|
||||
raise Exception
|
||||
return g
|
||||
|
||||
# ******************************************************* validate *********************************************************
|
||||
# ----------------
|
||||
# validate values
|
||||
# ----------------
|
||||
def validate_values(self):
|
||||
# Master name by naming series -> Series field mandatory
|
||||
if get_defaults().get('cust_master_name') == 'Naming Series' and not self.doc.naming_series:
|
||||
msgprint("Series is Mandatory.")
|
||||
raise Exception
|
||||
|
||||
# ---------
|
||||
# validate
|
||||
# ---------
|
||||
def validate(self):
|
||||
self.validate_values()
|
||||
|
||||
# ******************************************************* on update *********************************************************
|
||||
# ------------------------
|
||||
# create customer address
|
||||
# ------------------------
|
||||
def create_customer_address(self):
|
||||
addr_flds = [self.doc.address_line1, self.doc.address_line2, self.doc.city, self.doc.state, self.doc.country, self.doc.pincode]
|
||||
address_line = "\n".join(filter(lambda x : (x!='' and x!=None),addr_flds))
|
||||
|
||||
if self.doc.phone_1:
|
||||
address_line = address_line + "\n" + "Phone: " + cstr(self.doc.phone_1)
|
||||
if self.doc.email_id:
|
||||
address_line = address_line + "\n" + "E-mail: " + cstr(self.doc.email_id)
|
||||
set(self.doc,'address', address_line)
|
||||
|
||||
telephone = "(O): " + cstr(self.doc.phone_1) +"\n"+ cstr(self.doc.phone_2) + "\n" + "(M): " + "\n" + "(fax): " + cstr(self.doc.fax_1)
|
||||
set(self.doc,'telephone',telephone)
|
||||
|
||||
|
||||
# ------------------------------------
|
||||
# create primary contact for customer
|
||||
# ------------------------------------
|
||||
def create_p_contact(self,nm,phn_no,email_id,mob_no,fax,cont_addr):
|
||||
c1 = Document('Contact')
|
||||
c1.first_name = nm
|
||||
c1.contact_name = nm
|
||||
c1.contact_no = phn_no
|
||||
c1.email_id = email_id
|
||||
c1.mobile_no = mob_no
|
||||
c1.fax = fax
|
||||
c1.contact_address = cont_addr
|
||||
c1.is_primary_contact = 'Yes'
|
||||
c1.is_customer =1
|
||||
c1.customer = self.doc.name
|
||||
c1.customer_name = self.doc.customer_name
|
||||
c1.customer_address = self.doc.address
|
||||
c1.customer_group = self.doc.customer_group
|
||||
c1.save(1)
|
||||
|
||||
|
||||
# ------------------------
|
||||
# create customer contact
|
||||
# ------------------------
|
||||
def create_customer_contact(self):
|
||||
contact = sql("select distinct name from `tabContact` where customer_name=%s", (self.doc.customer_name))
|
||||
contact = contact and contact[0][0] or ''
|
||||
if not contact:
|
||||
# create primary contact for individual customer
|
||||
if self.doc.customer_type == 'Individual':
|
||||
self.create_p_contact(self.doc.customer_name,self.doc.phone_1,self.doc.email_id,'',self.doc.fax_1,self.doc.address)
|
||||
|
||||
# create primary contact for lead
|
||||
elif self.doc.lead_name:
|
||||
c_detail = sql("select lead_name, company_name, contact_no, mobile_no, email_id, fax, address from `tabLead` where name =%s", self.doc.lead_name, as_dict=1)
|
||||
self.create_p_contact(c_detail and c_detail[0]['lead_name'] or '', c_detail and c_detail[0]['contact_no'] or '', c_detail and c_detail[0]['email_id'] or '', c_detail and c_detail[0]['mobile_no'] or '', c_detail and c_detail[0]['fax'] or '', c_detail and c_detail[0]['address'] or '')
|
||||
|
||||
|
||||
# -------------------
|
||||
# update lead status
|
||||
# -------------------
|
||||
def update_lead_status(self):
|
||||
if self.doc.lead_name:
|
||||
sql("update `tabLead` set status='Converted' where name = %s", self.doc.lead_name)
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# create accont head - in tree under receivables_group of selected company
|
||||
# -------------------------------------------------------------------------
|
||||
def create_account_head(self):
|
||||
if self.doc.company :
|
||||
abbr = self.get_company_abbr()
|
||||
if not sql("select name from tabAccount where name=%s", (self.doc.name + " - " + abbr)):
|
||||
parent_account = self.get_receivables_group()
|
||||
arg = {'account_name':self.doc.name,'parent_account': parent_account, 'group_or_ledger':'Ledger', 'company':self.doc.company,'account_type':'','tax_rate':'0','master_type':'Customer','master_name':self.doc.name,'address':self.doc.address}
|
||||
# create
|
||||
ac = get_obj('GL Control').add_ac(cstr(arg))
|
||||
msgprint("Account Head created for "+ac)
|
||||
else :
|
||||
msgprint("Please Select Company under which you want to create account head")
|
||||
|
||||
|
||||
# ----------------------------------------
|
||||
# update credit days and limit in account
|
||||
# ----------------------------------------
|
||||
def update_credit_days_limit(self):
|
||||
sql("update tabAccount set credit_days = '%s', credit_limit = '%s' where name = '%s'" % (self.doc.credit_days, self.doc.credit_limit, self.doc.name + " - " + self.get_company_abbr()))
|
||||
|
||||
|
||||
#create address and contact from lead
|
||||
def create_lead_address_contact(self):
|
||||
if self.doc.lead_name:
|
||||
details = sql("select name, lead_name, address_line1, address_line2, city, country, state, pincode, phone, mobile_no, fax, email_id from `tabLead` where name = '%s'" %(self.doc.lead_name), as_dict = 1)
|
||||
d = Document('Address')
|
||||
d.address_line1 = details[0]['address_line1']
|
||||
d.address_line2 = details[0]['address_line2']
|
||||
d.city = details[0]['city']
|
||||
d.country = details[0]['country']
|
||||
d.pincode = details[0]['pincode']
|
||||
d.state = details[0]['state']
|
||||
d.fax = details[0]['fax']
|
||||
d.email_id = details[0]['email_id']
|
||||
d.phone = details[0]['phone']
|
||||
d.customer = self.doc.name
|
||||
d.customer_name = self.doc.customer_name
|
||||
d.is_primary_address = 1
|
||||
d.address_type = 'Office'
|
||||
try:
|
||||
d.save(1)
|
||||
except NameError, e:
|
||||
pass
|
||||
|
||||
c = Document('Contact')
|
||||
c.first_name = details[0]['lead_name']
|
||||
c.email_id = details[0]['email_id']
|
||||
c.phone = details[0]['phone']
|
||||
c.mobile_no = details[0]['mobile_no']
|
||||
c.customer = self.doc.name
|
||||
c.customer_name = self.doc.customer_name
|
||||
c.is_primary_contact = 1
|
||||
try:
|
||||
c.save(1)
|
||||
except NameError, e:
|
||||
pass
|
||||
|
||||
# ----------
|
||||
# on update
|
||||
# ----------
|
||||
def on_update(self):
|
||||
# create customer addr
|
||||
#self.create_customer_address()
|
||||
# create customer contact
|
||||
#self.create_customer_contact()
|
||||
# update lead status
|
||||
self.update_lead_status()
|
||||
# create account head
|
||||
self.create_account_head()
|
||||
# update credit days and limit in account
|
||||
self.update_credit_days_limit()
|
||||
#create address and contact from lead
|
||||
self.create_lead_address_contact()
|
||||
|
||||
def delete_customer_address(self):
|
||||
for rec in sql("select * from `tabAddress` where customer='%s'" %(self.doc.name), as_dict=1):
|
||||
sql("delete from `tabAddress` where name=%s",(rec['name']))
|
||||
|
||||
def delete_customer_contact(self):
|
||||
for rec in sql("select * from `tabContact` where customer='%s'" %(self.doc.name), as_dict=1):
|
||||
sql("delete from `tabContact` where name=%s",(rec['name']))
|
||||
|
||||
def delete_customer_communication(self):
|
||||
webnotes.conn.sql("""\
|
||||
delete from `tabCommunication`
|
||||
where customer = %s and supplier is null""", self.doc.name)
|
||||
|
||||
def delete_customer_account(self):
|
||||
"""delete customer's ledger if exist and check balance before deletion"""
|
||||
acc = sql("select name from `tabAccount` where master_type = 'Customer' \
|
||||
and master_name = %s and docstatus < 2", self.doc.name)
|
||||
if acc:
|
||||
from webnotes.model import delete_doc
|
||||
delete_doc('Account', acc[0][0])
|
||||
|
||||
def on_trash(self):
|
||||
self.delete_customer_address()
|
||||
self.delete_customer_contact()
|
||||
self.delete_customer_communication()
|
||||
self.delete_customer_account()
|
||||
if self.doc.lead_name:
|
||||
sql("update `tabLead` set status='Interested' where name=%s",self.doc.lead_name)
|
||||
|
||||
# on rename
|
||||
# ---------
|
||||
def on_rename(self,newdn,olddn):
|
||||
#update customer_name if not naming series
|
||||
if get_defaults().get('cust_master_name') == 'Customer Name':
|
||||
update_fields = [
|
||||
('Customer', 'name'),
|
||||
('Address', 'customer'),
|
||||
('Contact', 'customer'),
|
||||
('Customer Issue', 'customer'),
|
||||
('Delivery Note', 'customer'),
|
||||
('Opportunity', 'customer'),
|
||||
('Installation Note', 'customer'),
|
||||
('Maintenance Schedule', 'customer'),
|
||||
('Maintenance Visit', 'customer'),
|
||||
('Project', 'customer'),
|
||||
('Quotation', 'customer'),
|
||||
('Sales Invoice', 'customer'),
|
||||
('Sales Order', 'customer'),
|
||||
('Serial No', 'customer'),
|
||||
('Shipping Address', 'customer'),
|
||||
('Stock Entry', 'customer'),
|
||||
('Support Ticket', 'customer'),
|
||||
('Task', 'customer')]
|
||||
for rec in update_fields:
|
||||
sql("update `tab%s` set customer_name = '%s' where %s = '%s'" %(rec[0],newdn,rec[1],olddn))
|
||||
|
||||
#update master_name in doctype account
|
||||
sql("update `tabAccount` set master_name = '%s', master_type = 'Customer' where master_name = '%s'" %(newdn,olddn))
|
||||
534
selling/doctype/customer/customer.txt
Normal file
534
selling/doctype/customer/customer.txt
Normal file
@@ -0,0 +1,534 @@
|
||||
# DocType, Customer
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
u'creation': '2012-07-18 20:34:41',
|
||||
u'docstatus': 0,
|
||||
u'modified': '2012-09-17 11:31:55',
|
||||
u'modified_by': u'Administrator',
|
||||
u'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1330501485',
|
||||
'allow_print': 0,
|
||||
'allow_trash': 1,
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
u'doctype': u'DocType',
|
||||
'document_type': u'Master',
|
||||
'module': u'Selling',
|
||||
u'name': u'__common__',
|
||||
'search_fields': u'customer_name,customer_group,country,territory',
|
||||
'section_style': u'Tabbed',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'subject': u'eval:"%(customer_name)s"=="%(name)s" ? "" : "%(customer_name)s"',
|
||||
'tag_fields': u'customer_group,customer_type',
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
u'name': u'__common__',
|
||||
'parent': u'Customer',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
u'name': u'__common__',
|
||||
'parent': u'Customer',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Customer
|
||||
{
|
||||
u'doctype': u'DocType',
|
||||
u'name': u'Customer'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Note: You Can Manage Multiple Address or Contacts via Addresses & Contacts',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'basic_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Basic Info',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'customer_name',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Customer Name',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'customer_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'report_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'customer_type',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Customer Type',
|
||||
'oldfieldname': u'customer_type',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nCompany\nIndividual',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'naming_series',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Series',
|
||||
'no_copy': 1,
|
||||
'options': u'\nCUST\nCUSTMUM',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Fetch lead which will be converted into customer.',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'lead_name',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Lead Ref',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'lead_name',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Lead',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'column_break0',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'<a href="#!Sales Browser/Customer Group">To manage Customer Groups, click here</a>',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'customer_group',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Customer Group',
|
||||
'oldfieldname': u'customer_group',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Customer Group',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'<a href="#!Sales Browser/Territory">To manage Territory, click here</a>',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'territory',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Territory',
|
||||
'oldfieldname': u'territory',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Territory',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'address_contacts',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Address & Contacts',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u'eval:doc.__islocal',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'address_desc',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'Address Desc',
|
||||
'options': u'<em>Addresses will appear only when you save the customer</em>',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'address_html',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'Address HTML',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'column_break1',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u'eval:doc.__islocal',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'contact_desc',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'Contact Desc',
|
||||
'options': u'<em>Contact Details will appear only when you save the customer</em>',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'contact_html',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'Contact HTML',
|
||||
'oldfieldtype': u'HTML',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'communication_history',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Communication History',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'communication_html',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'Communication HTML',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'more_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'More Info',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'column_break2',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'To create an Account Head under a different company, select the company and save customer.',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'company',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Company',
|
||||
'oldfieldname': u'company',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Company',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'default_price_list',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Default Price List',
|
||||
'options': u'Price List',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'This currency will get fetched in Sales transactions of this customer',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'default_currency',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Default Currency',
|
||||
'no_copy': 1,
|
||||
'options': u'link:Currency',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u"Your Customer's TAX registration numbers (if applicable) or any general information",
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'customer_details',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Customer Details',
|
||||
'oldfieldname': u'customer_details',
|
||||
'oldfieldtype': u'Code',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'column_break3',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'credit_days',
|
||||
'fieldtype': u'Int',
|
||||
'label': u'Credit Days',
|
||||
'oldfieldname': u'credit_days',
|
||||
'oldfieldtype': u'Int',
|
||||
'permlevel': 2
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'credit_limit',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Credit Limit',
|
||||
'oldfieldname': u'credit_limit',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 2
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'website',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Website',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'sales_team_section_break',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Sales Team',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'default_sales_partner',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Default Sales Partner',
|
||||
'oldfieldname': u'default_sales_partner',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Sales Partner',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'default_commission_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Default Commission Rate',
|
||||
'oldfieldname': u'default_commission_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'sales_team',
|
||||
'fieldtype': u'Table',
|
||||
'label': u'Sales Team Details',
|
||||
'oldfieldname': u'sales_team',
|
||||
'oldfieldtype': u'Table',
|
||||
'options': u'Sales Team',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u'eval:!doc.__islocal',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'transaction_history',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Transaction History',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u'eval:!doc.__islocal',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'history_html',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'History HTML',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'trash_reason',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Trash Reason',
|
||||
'oldfieldname': u'trash_reason',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Master Manager',
|
||||
'submit': 0,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Accounts Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Manager',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales User',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'All',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 2,
|
||||
'role': u'Accounts Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 2,
|
||||
'role': u'System Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 2,
|
||||
'role': u'All'
|
||||
}
|
||||
]
|
||||
28
selling/doctype/customer/customer_list.js
Normal file
28
selling/doctype/customer/customer_list.js
Normal file
@@ -0,0 +1,28 @@
|
||||
// render
|
||||
wn.doclistviews['Customer'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d)
|
||||
this.fields = this.fields.concat([
|
||||
"`tabCustomer`.customer_name",
|
||||
"`tabCustomer`.territory",
|
||||
]);
|
||||
this.show_hide_check_column();
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
data.customer_name = repl("<a href=\"#!Form/Customer/%(name)s\">%(customer_name)s</a>",
|
||||
data);
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content:'check'},
|
||||
{width: '5%', content:'avatar'},
|
||||
{width: '50%', content:'customer_name'},
|
||||
{width: '10%', content:'tags'},
|
||||
{width: '20%', content:'territory',
|
||||
css: {'color': '#aaa'}},
|
||||
{width: '12%', content:'modified',
|
||||
css: {'text-align': 'right', 'color':'#777'}}
|
||||
],
|
||||
});
|
||||
1
selling/doctype/industry_type/__init__.py
Normal file
1
selling/doctype/industry_type/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
26
selling/doctype/industry_type/industry_type.js
Normal file
26
selling/doctype/industry_type/industry_type.js
Normal file
@@ -0,0 +1,26 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
//--------- ONLOAD -------------
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
|
||||
}
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
|
||||
}
|
||||
85
selling/doctype/industry_type/industry_type.txt
Normal file
85
selling/doctype/industry_type/industry_type.txt
Normal file
@@ -0,0 +1,85 @@
|
||||
# DocType, Industry Type
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:09',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:09',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'harshada@webnotestech.com'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'autoname': u'field:industry',
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'document_type': u'Master',
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'version': 4
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'industry',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Industry',
|
||||
'name': '__common__',
|
||||
'oldfieldname': u'industry',
|
||||
'oldfieldtype': u'Data',
|
||||
'parent': u'Industry Type',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Industry Type',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0,
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Industry Type
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Industry Type'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'role': u'Sales Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'role': u'Sales User'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'role': u'Sales Master Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField'
|
||||
}
|
||||
]
|
||||
1
selling/doctype/installation_note/__init__.py
Normal file
1
selling/doctype/installation_note/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
85
selling/doctype/installation_note/installation_note.js
Normal file
85
selling/doctype/installation_note/installation_note.js
Normal file
@@ -0,0 +1,85 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
cur_frm.cscript.tname = "Installation Note Item";
|
||||
cur_frm.cscript.fname = "installed_item_details";
|
||||
|
||||
cur_frm.cscript.onload = function(doc, dt, dn) {
|
||||
if(!doc.status) set_multiple(dt,dn,{status:'Draft'});
|
||||
if(doc.__islocal){
|
||||
set_multiple(dt,dn,{inst_date:get_today()});
|
||||
hide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
}
|
||||
if (doc.customer) {
|
||||
unhide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['delivery_note_no'].get_query = function(doc) {
|
||||
doc = locals[this.doctype][this.docname];
|
||||
var cond = '';
|
||||
if(doc.customer) {
|
||||
cond = '`tabDelivery Note`.customer = "'+doc.customer+'" AND';
|
||||
}
|
||||
return repl('SELECT DISTINCT `tabDelivery Note`.name, `tabDelivery Note`.customer_name FROM `tabDelivery Note`, `tabDelivery Note Item` WHERE `tabDelivery Note`.company = "%(company)s" AND `tabDelivery Note`.docstatus = 1 AND ifnull(`tabDelivery Note`.per_installed,0) < 100 AND %(cond)s `tabDelivery Note`.name LIKE "%s" ORDER BY `tabDelivery Note`.name DESC LIMIT 50', {company:doc.company, cond:cond});
|
||||
}
|
||||
|
||||
|
||||
cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s" ORDER BY `tabTerritory`.`name` ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.cscript.get_items = function(doc, dt, dn) {
|
||||
var callback = function(r,rt) {
|
||||
unhide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
cur_frm.refresh();
|
||||
}
|
||||
get_server_fields('pull_delivery_note_details','','',doc, dt, dn,1,callback);
|
||||
}
|
||||
|
||||
//customer
|
||||
cur_frm.cscript.customer = function(doc,dt,dn) {
|
||||
var callback = function(r,rt) {
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
cur_frm.refresh();
|
||||
}
|
||||
|
||||
if(doc.customer) $c_obj(make_doclist(doc.doctype, doc.name), 'get_default_customer_address', '', callback);
|
||||
if(doc.customer) unhide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
}
|
||||
|
||||
cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
||||
if(doc.customer) get_server_fields('get_customer_address', JSON.stringify({customer: doc.customer, address: doc.customer_address, contact: doc.contact_person}),'', doc, dt, dn, 1);
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.customer_address.on_new = function(dn) {
|
||||
locals['Address'][dn].customer = locals[cur_frm.doctype][cur_frm.docname].customer;
|
||||
locals['Address'][dn].customer_name = locals[cur_frm.doctype][cur_frm.docname].customer_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.contact_person.on_new = function(dn) {
|
||||
locals['Contact'][dn].customer = locals[cur_frm.doctype][cur_frm.docname].customer;
|
||||
locals['Contact'][dn].customer_name = locals[cur_frm.doctype][cur_frm.docname].customer_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,address_line1,city FROM tabAddress WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,CONCAT(first_name," ",ifnull(last_name,"")) As FullName,department,designation FROM tabContact WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
213
selling/doctype/installation_note/installation_note.py
Normal file
213
selling/doctype/installation_note/installation_note.py
Normal file
@@ -0,0 +1,213 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
from utilities.transaction_base import TransactionBase
|
||||
|
||||
class DocType(TransactionBase):
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
self.tname = 'Installation Note Item'
|
||||
self.fname = 'installed_item_details'
|
||||
|
||||
# Autoname
|
||||
# ---------
|
||||
def autoname(self):
|
||||
self.doc.name = make_autoname(self.doc.naming_series+'.#####')
|
||||
|
||||
|
||||
#fetch delivery note details
|
||||
#====================================
|
||||
def pull_delivery_note_details(self):
|
||||
self.validate_prev_docname()
|
||||
self.doclist = get_obj('DocType Mapper', 'Delivery Note-Installation Note').dt_map('Delivery Note', 'Installation Note', self.doc.delivery_note_no, self.doc, self.doclist, "[['Delivery Note', 'Installation Note'],['Delivery Note Item', 'Installation Note Item']]")
|
||||
|
||||
# Validates that Delivery Note is not pulled twice
|
||||
#============================================
|
||||
def validate_prev_docname(self):
|
||||
for d in getlist(self.doclist, 'installed_item_details'):
|
||||
if self.doc.delivery_note_no == d.prevdoc_docname:
|
||||
msgprint(cstr(self.doc.delivery_note_no) + " delivery note details have already been pulled. ")
|
||||
raise Exception, "Validation Error. "
|
||||
|
||||
#Fiscal Year Validation
|
||||
#================================
|
||||
def validate_fiscal_year(self):
|
||||
get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.inst_date,'Installation Date')
|
||||
|
||||
# Validate Mandatory
|
||||
#===============================
|
||||
def validate_mandatory(self):
|
||||
# Amendment Date
|
||||
if self.doc.amended_from and not self.doc.amendment_date:
|
||||
msgprint("Please Enter Amendment Date")
|
||||
raise Exception, "Validation Error. "
|
||||
|
||||
# Validate values with reference document
|
||||
#----------------------------------------
|
||||
def validate_reference_value(self):
|
||||
get_obj('DocType Mapper', 'Delivery Note-Installation Note', with_children = 1).validate_reference_value(self, self.doc.name)
|
||||
|
||||
#check if serial no added
|
||||
#-----------------------------
|
||||
def is_serial_no_added(self,item_code,serial_no):
|
||||
ar_required = sql("select has_serial_no from tabItem where name = '%s'" % item_code)
|
||||
ar_required = ar_required and ar_required[0][0] or ''
|
||||
if ar_required == 'Yes' and not serial_no:
|
||||
msgprint("Serial No is mandatory for item: "+ item_code)
|
||||
raise Exception
|
||||
elif ar_required != 'Yes' and cstr(serial_no).strip():
|
||||
msgprint("If serial no required, please select 'Yes' in 'Has Serial No' in Item :"+item_code)
|
||||
raise Exception
|
||||
|
||||
#check if serial no exist in system
|
||||
#-------------------------------------
|
||||
def is_serial_no_exist(self, item_code, serial_no):
|
||||
for x in serial_no:
|
||||
chk = sql("select name from `tabSerial No` where name =%s", x)
|
||||
if not chk:
|
||||
msgprint("Serial No "+x+" does not exist in the system")
|
||||
raise Exception
|
||||
|
||||
#check if serial no already installed
|
||||
#------------------------------------------
|
||||
def is_serial_no_installed(self,cur_s_no,item_code):
|
||||
for x in cur_s_no:
|
||||
status = sql("select status from `tabSerial No` where name = %s", x)
|
||||
status = status and status[0][0] or ''
|
||||
|
||||
if status == 'Installed':
|
||||
msgprint("Item "+item_code+" with serial no. "+x+" already installed")
|
||||
raise Exception, "Validation Error."
|
||||
|
||||
#get list of serial no from previous_doc
|
||||
#----------------------------------------------
|
||||
def get_prevdoc_serial_no(self, prevdoc_detail_docname, prevdoc_docname):
|
||||
from stock.doctype.stock_ledger.stock_ledger import get_sr_no_list
|
||||
|
||||
res = sql("select serial_no from `tabDelivery Note Item` where name = '%s' and parent ='%s'" % (prevdoc_detail_docname, prevdoc_docname))
|
||||
return get_sr_no_list(res[0][0])
|
||||
|
||||
#check if all serial nos from current record exist in resp delivery note
|
||||
#---------------------------------------------------------------------------------
|
||||
def is_serial_no_match(self, cur_s_no, prevdoc_s_no, prevdoc_docname):
|
||||
for x in cur_s_no:
|
||||
if not(x in prevdoc_s_no):
|
||||
msgprint("Serial No. "+x+" not present in the Delivery Note "+prevdoc_docname, raise_exception = 1)
|
||||
raise Exception, "Validation Error."
|
||||
|
||||
#validate serial number
|
||||
#----------------------------------------
|
||||
def validate_serial_no(self):
|
||||
cur_s_no, prevdoc_s_no, sr_list = [], [], []
|
||||
from stock.doctype.stock_ledger.stock_ledger import get_sr_no_list
|
||||
|
||||
for d in getlist(self.doclist, 'installed_item_details'):
|
||||
self.is_serial_no_added(d.item_code, d.serial_no)
|
||||
|
||||
if d.serial_no:
|
||||
|
||||
sr_list = get_sr_no_list(d.serial_no, d.qty, d.item_code)
|
||||
self.is_serial_no_exist(d.item_code, sr_list)
|
||||
|
||||
prevdoc_s_no = self.get_prevdoc_serial_no(d.prevdoc_detail_docname, d.prevdoc_docname)
|
||||
if prevdoc_s_no:
|
||||
self.is_serial_no_match(sr_list, prevdoc_s_no, d.prevdoc_docname)
|
||||
|
||||
self.is_serial_no_installed(sr_list, d.item_code)
|
||||
return sr_list
|
||||
|
||||
#validate installation date
|
||||
#-------------------------------
|
||||
def validate_installation_date(self):
|
||||
for d in getlist(self.doclist, 'installed_item_details'):
|
||||
if d.prevdoc_docname:
|
||||
d_date = sql("select posting_date from `tabDelivery Note` where name=%s", d.prevdoc_docname)
|
||||
d_date = d_date and d_date[0][0] or ''
|
||||
|
||||
if d_date > getdate(self.doc.inst_date):
|
||||
msgprint("Installation Date can not be before Delivery Date "+cstr(d_date)+" for item "+d.item_code)
|
||||
raise Exception
|
||||
|
||||
def validate(self):
|
||||
self.validate_fiscal_year()
|
||||
self.validate_installation_date()
|
||||
self.check_item_table()
|
||||
sales_com_obj = get_obj(dt = 'Sales Common')
|
||||
sales_com_obj.check_active_sales_items(self)
|
||||
sales_com_obj.get_prevdoc_date(self)
|
||||
self.validate_mandatory()
|
||||
self.validate_reference_value()
|
||||
|
||||
def check_item_table(self):
|
||||
if not(getlist(self.doclist, 'installed_item_details')):
|
||||
msgprint("Please fetch items from Delivery Note selected")
|
||||
raise Exception
|
||||
|
||||
def on_update(self):
|
||||
set(self.doc, 'status', 'Draft')
|
||||
|
||||
def on_submit(self):
|
||||
valid_lst = []
|
||||
valid_lst = self.validate_serial_no()
|
||||
|
||||
get_obj("Sales Common").update_prevdoc_detail(1,self)
|
||||
|
||||
for x in valid_lst:
|
||||
wp = sql("select warranty_period from `tabSerial No` where name = '%s'"% x)
|
||||
wp = wp and wp[0][0] or 0
|
||||
if wp:
|
||||
sql("update `tabSerial No` set maintenance_status = 'Under Warranty' where name = '%s'" % x)
|
||||
|
||||
sql("update `tabSerial No` set status = 'Installed' where name = '%s'" % x)
|
||||
|
||||
set(self.doc, 'status', 'Submitted')
|
||||
|
||||
|
||||
def on_cancel(self):
|
||||
cur_s_no = []
|
||||
sales_com_obj = get_obj(dt = 'Sales Common')
|
||||
sales_com_obj.update_prevdoc_detail(0,self)
|
||||
|
||||
for d in getlist(self.doclist, 'installed_item_details'):
|
||||
if d.serial_no:
|
||||
#get current list of serial no
|
||||
cur_serial_no = d.serial_no.replace(' ', '')
|
||||
cur_s_no = cur_serial_no.split(',')
|
||||
|
||||
for x in cur_s_no:
|
||||
sql("update `tabSerial No` set status = 'Delivered' where name = '%s'" % x)
|
||||
|
||||
set(self.doc, 'status', 'Cancelled')
|
||||
453
selling/doctype/installation_note/installation_note.txt
Normal file
453
selling/doctype/installation_note/installation_note.txt
Normal file
@@ -0,0 +1,453 @@
|
||||
# DocType, Installation Note
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:09',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 18:48:02',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1306480044',
|
||||
'autoname': u'IN/.####',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'is_submittable': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'subject': u'At %(customer_name)s on %(inst_date)s',
|
||||
'version': 98
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Installation Note',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Installation Note',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Installation Note
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Installation Note'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'System Manager',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'System Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales User',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Manager',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales User'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales Manager'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'installation_note',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Installation Note',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break0',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'naming_series',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Series',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'naming_series',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nIN',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Customer',
|
||||
'oldfieldname': u'customer',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Customer',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_address',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Customer Address',
|
||||
'options': u'Address',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_person',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Contact Person',
|
||||
'options': u'Contact',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_name',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Name',
|
||||
'oldfieldname': u'customer_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'address_display',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Address',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_display',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Contact',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_mobile',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Mobile No',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_email',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Contact Email',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'territory',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Territory',
|
||||
'options': u'Territory',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_group',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Customer Group',
|
||||
'options': u'Customer Group',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break1',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'inst_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Installation Date',
|
||||
'oldfieldname': u'inst_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'inst_time',
|
||||
'fieldtype': u'Time',
|
||||
'label': u'Installation Time',
|
||||
'oldfieldname': u'inst_time',
|
||||
'oldfieldtype': u'Time',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'Draft',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'status',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Status',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'status',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'Draft\nSubmitted\nCancelled',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Select the relevant company name if you have multiple companies.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'company',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Company',
|
||||
'oldfieldname': u'company',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'link:Company',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'fiscal_year',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Fiscal Year',
|
||||
'oldfieldname': u'fiscal_year',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'link:Fiscal Year',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amended_from',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Amended From',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'amended_from',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'The date at which current entry is corrected in the system.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amendment_date',
|
||||
'fieldtype': u'Date',
|
||||
'hidden': 1,
|
||||
'label': u'Amendment Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'amendment_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'remarks',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Remarks',
|
||||
'oldfieldname': u'remarks',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'cancel_reason',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u'Cancel Reason',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'cancel_reason',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_details',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Item Details',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'options': u'Simple',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'delivery_note_no',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Delivery Note No',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'delivery_note_no',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Delivery Note',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'get_items',
|
||||
'fieldtype': u'Button',
|
||||
'hidden': 0,
|
||||
'label': u'Get Items',
|
||||
'oldfieldtype': u'Button',
|
||||
'options': u'pull_delivery_note_details',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'installed_item_details',
|
||||
'fieldtype': u'Table',
|
||||
'label': u'Installation Note Item',
|
||||
'oldfieldname': u'installed_item_details',
|
||||
'oldfieldtype': u'Table',
|
||||
'options': u'Installation Note Item',
|
||||
'permlevel': 0
|
||||
}
|
||||
]
|
||||
1
selling/doctype/installation_note_item/__init__.py
Normal file
1
selling/doctype/installation_note_item/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -0,0 +1,153 @@
|
||||
# DocType, Installation Note Item
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:10',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:10',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'autoname': u'IID/.#####',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 25
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Installation Note Item',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# DocType, Installation Note Item
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Installation Note Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_code',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Item Code',
|
||||
'oldfieldname': u'item_code',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_date',
|
||||
'fieldtype': u'Date',
|
||||
'hidden': 0,
|
||||
'label': u'Delivery Date',
|
||||
'oldfieldname': u'prevdoc_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 1,
|
||||
'print_hide': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'serial_no',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Serial No',
|
||||
'oldfieldname': u'serial_no',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 0,
|
||||
'width': u'180px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_detail_docname',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u'Against Document Detail No',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'prevdoc_detail_docname',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_docname',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Against Document No',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'prevdoc_docname',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_doctype',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Document Type',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'prevdoc_doctype',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Installed Qty',
|
||||
'oldfieldname': u'qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
}
|
||||
]
|
||||
1
selling/doctype/lead/__init__.py
Normal file
1
selling/doctype/lead/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
143
selling/doctype/lead/lead.js
Normal file
143
selling/doctype/lead/lead.js
Normal file
@@ -0,0 +1,143 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Module CRM
|
||||
|
||||
wn.require('erpnext/utilities/doctype/sms_control/sms_control.js');
|
||||
wn.require('erpnext/support/doctype/communication/communication.js');
|
||||
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
if(user =='Guest'){
|
||||
hide_field(['status', 'naming_series', 'order_lost_reason',
|
||||
'customer', 'rating', 'fax', 'website', 'territory',
|
||||
'address_line1', 'address_line2', 'city', 'state',
|
||||
'country', 'pincode', 'address', 'lead_owner', 'market_segment',
|
||||
'industry', 'campaign_name', 'interested_in', 'company',
|
||||
'fiscal_year', 'contact_by', 'contact_date', 'last_contact_date',
|
||||
'contact_date_ref', 'to_discuss', 'more_info', 'follow_up',
|
||||
'communication_history', 'cc_to', 'subject', 'message', 'lead_attachment_detail',
|
||||
'Create Customer', 'Create Opportunity', 'transaction_date', 'type', 'source']);
|
||||
doc.source = 'Website';
|
||||
}
|
||||
if(!doc.status) set_multiple(dt,dn,{status:'Open'});
|
||||
|
||||
if (!doc.date){
|
||||
doc.date = date.obj_to_str(new Date());
|
||||
}
|
||||
// set naming series
|
||||
if(user=='Guest') doc.naming_series = 'WebLead';
|
||||
|
||||
cur_frm.add_fetch('customer', 'customer_name', 'company_name');
|
||||
|
||||
cur_frm.cscript.make_communication_body();
|
||||
}
|
||||
|
||||
cur_frm.cscript.refresh_custom_buttons = function() {
|
||||
cur_frm.clear_custom_buttons();
|
||||
if(!doc.__islocal && !in_list(['Converted', 'Lead Lost'], doc.status)) {
|
||||
if (doc.source != 'Existing Customer') {
|
||||
cur_frm.add_custom_button('Create Customer',
|
||||
cur_frm.cscript['Create Customer']);
|
||||
}
|
||||
cur_frm.add_custom_button('Create Opportunity',
|
||||
cur_frm.cscript['Create Opportunity']);
|
||||
cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
// custom buttons
|
||||
//---------------
|
||||
cur_frm.cscript.refresh_custom_buttons();
|
||||
|
||||
erpnext.hide_naming_series();
|
||||
|
||||
if (!doc.__islocal) cur_frm.cscript.render_communication_list(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
|
||||
// Client Side Triggers
|
||||
// ===========================================================
|
||||
// ************ Status ******************
|
||||
cur_frm.cscript.status = function(doc, cdt, cdn){
|
||||
cur_frm.cscript.refresh(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
//Trigger in Item Table
|
||||
//===================================
|
||||
cur_frm.cscript.item_code=function(doc,cdt,cdn){
|
||||
var d = locals[cdt][cdn];
|
||||
if (d.item_code) { get_server_fields('get_item_detail',d.item_code,'lead_item_detail',doc,cdt,cdn,1);}
|
||||
}
|
||||
|
||||
// Create New Customer
|
||||
// ===============================================================
|
||||
cur_frm.cscript['Create Customer'] = function(){
|
||||
var doc = cur_frm.doc;
|
||||
$c('runserverobj',args={ 'method':'check_status', 'docs':compress_doclist(make_doclist(doc.doctype, doc.name))},
|
||||
function(r,rt){
|
||||
if(r.message == 'Converted'){
|
||||
msgprint("This lead is already converted to customer");
|
||||
}
|
||||
else{
|
||||
n = createLocal("Customer");
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals["Customer"][n]]),
|
||||
'from_doctype':'Lead',
|
||||
'to_doctype':'Customer',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Lead', 'Customer']]"
|
||||
},
|
||||
function(r,rt) {
|
||||
loaddoc("Customer", n);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Create New Opportunity
|
||||
// ===============================================================
|
||||
cur_frm.cscript['Create Opportunity'] = function(){
|
||||
var doc = cur_frm.doc;
|
||||
$c('runserverobj',args={ 'method':'check_status', 'docs':compress_doclist(make_doclist(doc.doctype, doc.name))},
|
||||
function(r,rt){
|
||||
if(r.message == 'Converted'){
|
||||
msgprint("This lead is now converted to customer. Please create enquiry on behalf of customer");
|
||||
}
|
||||
else{
|
||||
n = createLocal("Opportunity");
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals["Opportunity"][n]]),
|
||||
'from_doctype':'Lead',
|
||||
'to_doctype':'Opportunity',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Lead', 'Opportunity']]"
|
||||
}
|
||||
, function(r,rt) {
|
||||
loaddoc("Opportunity", n);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
//get query select Territory
|
||||
cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s" ORDER BY `tabTerritory`.`name` ASC LIMIT 50';
|
||||
}
|
||||
147
selling/doctype/lead/lead.py
Normal file
147
selling/doctype/lead/lead.py
Normal file
@@ -0,0 +1,147 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class DocType:
|
||||
def __init__(self, doc, doclist):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
|
||||
# Autoname
|
||||
# ---------
|
||||
def autoname(self):
|
||||
self.doc.name = make_autoname(self.doc.naming_series+'.#####')
|
||||
|
||||
#check status of lead
|
||||
#------------------------
|
||||
def check_status(self):
|
||||
chk = sql("select status from `tabLead` where name=%s", self.doc.name)
|
||||
chk = chk and chk[0][0] or ''
|
||||
return cstr(chk)
|
||||
|
||||
|
||||
# Get item detail (will be removed later)
|
||||
#=======================================
|
||||
def get_item_detail(self,item_code):
|
||||
it=sql("select item_name,brand,item_group,description,stock_uom from `tabItem` where name='%s'"%item_code)
|
||||
if it:
|
||||
ret = {
|
||||
'item_name' : it and it[0][0] or '',
|
||||
'brand' : it and it[0][1] or '',
|
||||
'item_group' : it and it[0][2] or '',
|
||||
'description': it and it[0][3] or '',
|
||||
'uom' : it and it[0][4] or ''
|
||||
}
|
||||
return ret
|
||||
|
||||
def validate(self):
|
||||
import string
|
||||
if self.doc.status == 'Lead Lost' and not self.doc.order_lost_reason:
|
||||
msgprint("Please Enter Lost Reason under More Info section")
|
||||
raise Exception
|
||||
|
||||
if self.doc.source == 'Campaign' and not self.doc.campaign_name and session['user'] != 'Guest':
|
||||
msgprint("Please specify campaign name")
|
||||
raise Exception
|
||||
|
||||
if self.doc.email_id:
|
||||
if not validate_email_add(self.doc.email_id):
|
||||
msgprint('Please enter valid email id.')
|
||||
raise Exception
|
||||
|
||||
|
||||
def on_update(self):
|
||||
if self.doc.contact_by:
|
||||
self.add_calendar_event()
|
||||
|
||||
if not self.doc.naming_series:
|
||||
if session['user'] == 'Guest':
|
||||
import webnotes.model.doctype
|
||||
docfield = webnotes.model.doctype.get('Lead')
|
||||
series = [d.options for d in docfield if d.doctype == 'DocField' and d.fieldname == 'naming_series']
|
||||
if series:
|
||||
sr = series[0].split("\n")
|
||||
set(self.doc, 'naming_series', sr[0])
|
||||
else:
|
||||
msgprint("Please specify naming series")
|
||||
raise Exception
|
||||
|
||||
# Add to Calendar
|
||||
# ===========================================================================
|
||||
def add_calendar_event(self):
|
||||
# delete any earlier event by this lead
|
||||
sql("delete from tabEvent where ref_type='Lead' and ref_name=%s", self.doc.name)
|
||||
|
||||
in_calendar_of = self.doc.lead_owner
|
||||
|
||||
# get profile (id) if exists for contact_by
|
||||
email_id = webnotes.conn.get_value('Sales Person', self.doc.contact_by, 'email_id')
|
||||
if webnotes.conn.exists('Profile', email_id):
|
||||
in_calendar_of = email_id
|
||||
|
||||
ev = Document('Event')
|
||||
ev.owner = in_calendar_of
|
||||
ev.description = 'Contact ' + cstr(self.doc.lead_name) + '.By : ' + cstr(self.doc.contact_by) + '.To Discuss : ' + cstr(self.doc.remark)
|
||||
ev.event_date = self.doc.contact_date
|
||||
ev.event_hour = '10:00'
|
||||
ev.event_type = 'Private'
|
||||
ev.ref_type = 'Lead'
|
||||
ev.ref_name = self.doc.name
|
||||
ev.save(1)
|
||||
|
||||
def add_in_follow_up(self,message,type):
|
||||
import datetime
|
||||
child = addchild( self.doc, 'follow_up', 'Communication Log', 1, self.doclist)
|
||||
child.date = datetime.datetime.now().date().strftime('%Y-%m-%d')
|
||||
child.notes = message
|
||||
child.follow_up_type = type
|
||||
child.save()
|
||||
|
||||
#-------------------SMS----------------------------------------------
|
||||
def send_sms(self):
|
||||
if not self.doc.sms_message or not self.doc.mobile_no:
|
||||
msgprint("Please enter mobile number in Basic Info Section and message in SMS Section ")
|
||||
raise Exception
|
||||
else:
|
||||
receiver_list = []
|
||||
if self.doc.mobile_no:
|
||||
receiver_list.append(self.doc.mobile_no)
|
||||
for d in getlist(self.doclist,'lead_sms_detail'):
|
||||
if d.other_mobile_no:
|
||||
receiver_list.append(d.other_mobile_no)
|
||||
|
||||
if receiver_list:
|
||||
msgprint(get_obj('SMS Control', 'SMS Control').send_sms(receiver_list, self.doc.sms_message))
|
||||
# self.add_in_follow_up(self.doc.sms_message,'SMS')
|
||||
702
selling/doctype/lead/lead.txt
Normal file
702
selling/doctype/lead/lead.txt
Normal file
@@ -0,0 +1,702 @@
|
||||
# DocType, Lead
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
u'creation': '2012-06-05 20:03:20',
|
||||
u'docstatus': 0,
|
||||
u'modified': '2012-08-06 14:49:48',
|
||||
u'modified_by': u'Administrator',
|
||||
u'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1332222225',
|
||||
'allow_trash': 1,
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
u'doctype': u'DocType',
|
||||
'document_type': u'Master',
|
||||
'module': u'Selling',
|
||||
u'name': u'__common__',
|
||||
'search_fields': u'lead_name,lead_owner,status',
|
||||
'section_style': u'Tabbed',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'subject': u'%(lead_name)s from %(company_name)s | To Discuss: %(to_discuss)s',
|
||||
'tag_fields': u'status,source',
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
u'name': u'__common__',
|
||||
'parent': u'Lead',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
u'name': u'__common__',
|
||||
'parent': u'Lead',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Lead
|
||||
{
|
||||
u'doctype': u'DocType',
|
||||
u'name': u'Lead'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'basic_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Basic Info',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'column_break0',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'To manage multiple series please go to Setup > Manage Series',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'naming_series',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Naming Series',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'naming_series',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'LEAD\nLEAD/10-11/\nLEAD/MUMBAI/',
|
||||
'permlevel': 0,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'lead_name',
|
||||
'fieldtype': u'Data',
|
||||
'in_filter': 1,
|
||||
'label': u'Contact Name',
|
||||
'oldfieldname': u'lead_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Name of organization from where lead has come',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'company_name',
|
||||
'fieldtype': u'Data',
|
||||
'in_filter': 1,
|
||||
'label': u'Company Name',
|
||||
'oldfieldname': u'company_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Source of the lead. If via a campaign, select "Campaign"',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'source',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Source',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'source',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nAdvertisement\nBlog\nCampaign\nCall\nCustomer\nExhibition\nSupplier\nWebsite',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u"eval:doc.source == 'Existing Customer'",
|
||||
'description': u'Source of th',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'customer',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'label': u'From Customer',
|
||||
'oldfieldname': u'customer',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Customer',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u"eval:doc.source == 'Campaign'",
|
||||
'description': u'Enter campaign name if the source of lead is campaign.',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'campaign_name',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'label': u'Campaign Name',
|
||||
'oldfieldname': u'campaign_name',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Campaign',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'column_break1',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'default': u'Open',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'status',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Status',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'status',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nOpen\nAttempted to Contact\nContact in Future\nContacted\nInterested\nNot interested\nLead Lost\nConverted',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'type',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Lead Type',
|
||||
'oldfieldname': u'type',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nClient\nChannel Partner\nConsultant',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'remark',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Remark',
|
||||
'oldfieldname': u'remark',
|
||||
'oldfieldtype': u'Text',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'communication_history',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Communication History',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'communication_html',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'Communication HTML',
|
||||
'oldfieldname': u'follow_up',
|
||||
'oldfieldtype': u'Table',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'contact_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Contact Info',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'phone',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Phone',
|
||||
'oldfieldname': u'contact_no',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'mobile_no',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Mobile No.',
|
||||
'oldfieldname': u'mobile_no',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'email_id',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Email Id',
|
||||
'oldfieldname': u'email_id',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'fax',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Fax',
|
||||
'oldfieldname': u'fax',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'website',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Website',
|
||||
'oldfieldname': u'website',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'<a href="javascript:cur_frm.cscript.TerritoryHelp();">To manage Territory, click here</a>',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'territory',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Territory',
|
||||
'oldfieldname': u'territory',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Territory',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'column_break2',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'address_line1',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Address Line 1',
|
||||
'oldfieldname': u'address_line1',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'address_line2',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Address Line 2',
|
||||
'oldfieldname': u'address_line2',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'city',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'City',
|
||||
'oldfieldname': u'city',
|
||||
'oldfieldtype': u'Select',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'country',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Country',
|
||||
'oldfieldname': u'country',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'link:Country',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'state',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'State',
|
||||
'oldfieldname': u'state',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'Suggest',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'pincode',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Pin Code',
|
||||
'oldfieldname': u'pincode',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'more_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'More Info',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'__user',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'lead_owner',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Lead Owner',
|
||||
'oldfieldname': u'lead_owner',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Profile',
|
||||
'permlevel': 0,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'market_segment',
|
||||
'fieldtype': u'Select',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Market Segment',
|
||||
'oldfieldname': u'market_segment',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nLower Income\nMiddle Income\nUpper Income',
|
||||
'permlevel': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'industry',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Industry',
|
||||
'oldfieldname': u'industry',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Industry Type',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'request_type',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Request Type',
|
||||
'oldfieldname': u'request_type',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nProduct Enquiry\nRequest for Information\nSuggestions\nOther',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'fiscal_year',
|
||||
'fieldtype': u'Select',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Fiscal Year',
|
||||
'oldfieldname': u'fiscal_year',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'link:Fiscal Year',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'column_break3',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'depends_on': u"eval:doc.status == 'Lead Lost'",
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'order_lost_reason',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'label': u'Lost Reason',
|
||||
'oldfieldname': u'order_lost_reason',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Quotation Lost Reason',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Your sales person who will contact the lead in future',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'contact_by',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Next Contact By',
|
||||
'oldfieldname': u'contact_by',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Profile',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'reqd': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Your sales person will get a reminder on this date to contact the lead',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'contact_date',
|
||||
'fieldtype': u'Date',
|
||||
'in_filter': 1,
|
||||
'label': u'Next Contact Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'contact_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'reqd': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u'eval:!doc.__islocal',
|
||||
'description': u'Date on which the lead was last contacted',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'last_contact_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Last Contact Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'last_contact_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'company',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Company',
|
||||
'oldfieldname': u'company',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Company',
|
||||
'permlevel': 0,
|
||||
'reqd': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'trash_reason',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Trash Reason',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'trash_reason',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'unsubscribed',
|
||||
'fieldtype': u'Check',
|
||||
'label': u'Unsubscribed',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
u'doctype': u'DocField',
|
||||
'fieldname': u'blog_subscriber',
|
||||
'fieldtype': u'Check',
|
||||
'label': u'Blog Subscriber',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales User',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales Manager',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Manager',
|
||||
'submit': 0,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales User',
|
||||
'submit': 0,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'All'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'System Manager',
|
||||
'submit': 0,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
u'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Guest',
|
||||
'write': 1
|
||||
}
|
||||
]
|
||||
34
selling/doctype/lead/lead_list.js
Normal file
34
selling/doctype/lead/lead_list.js
Normal file
@@ -0,0 +1,34 @@
|
||||
wn.doclistviews['Lead'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d)
|
||||
this.fields = this.fields.concat([
|
||||
'tabLead.lead_name',
|
||||
'tabLead.status',
|
||||
'tabLead.source'
|
||||
]);
|
||||
this.stats = this.stats.concat(['status', 'source', 'rating', 'company']);
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
if(data.status=='Interested') {
|
||||
data.label_type = 'success'
|
||||
}
|
||||
else if(['Open', 'Attempted to Contact', 'Contacted', 'Contact in Future'].indexOf(data.status)!=-1) {
|
||||
data.label_type = 'info'
|
||||
}
|
||||
data.status_html = repl('<span class="label label-%(label_type)s">%(status)s</span>', data);
|
||||
data.lead_name = repl("<a href=\"#!Form/Lead/%(name)s\">%(lead_name)s</a>",
|
||||
data);
|
||||
data.lead_status = (data.rating ? ('['+data.rating+'] ') : '') + '['+data.source+']';
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content: 'check'},
|
||||
{width: '5%', content:'avatar'},
|
||||
{width: '30%', content:'lead_name'},
|
||||
{width: '12%', content:'status_html'},
|
||||
{width: '38%', content:'lead_status+tags', css: {color:'#222'}},
|
||||
{width: '12%', content:'modified', css: {'text-align': 'right', 'color':'#777'}}
|
||||
]
|
||||
})
|
||||
1
selling/doctype/opportunity/__init__.py
Normal file
1
selling/doctype/opportunity/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
215
selling/doctype/opportunity/opportunity.js
Normal file
215
selling/doctype/opportunity/opportunity.js
Normal file
@@ -0,0 +1,215 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
wn.require('erpnext/utilities/doctype/sms_control/sms_control.js');
|
||||
wn.require('erpnext/support/doctype/communication/communication.js');
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn){
|
||||
erpnext.hide_naming_series();
|
||||
|
||||
cur_frm.clear_custom_buttons();
|
||||
if(doc.docstatus == 1) {
|
||||
cur_frm.add_custom_button('Create Quotation', cur_frm.cscript['Create Quotation']);
|
||||
cur_frm.add_custom_button('Opportunity Lost', cur_frm.cscript['Declare Opportunity Lost']);
|
||||
cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms);
|
||||
}
|
||||
if(!doc.__islocal) cur_frm.cscript.render_communication_list(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
// ONLOAD
|
||||
// ===============================================================
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
|
||||
if(!doc.enquiry_from) hide_field(['customer', 'customer_address', 'contact_person', 'customer_name','lead', 'lead_name', 'address_display', 'contact_display', 'contact_mobile', 'contact_email', 'territory', 'customer_group']);
|
||||
if(!doc.status) set_multiple(cdt,cdn,{status:'Draft'});
|
||||
if(!doc.date) doc.transaction_date = date.obj_to_str(new Date());
|
||||
if(!doc.company && sys_defaults.company) set_multiple(cdt,cdn,{company:sys_defaults.company});
|
||||
if(!doc.fiscal_year && sys_defaults.fiscal_year) set_multiple(cdt,cdn,{fiscal_year:sys_defaults.fiscal_year});
|
||||
|
||||
if(doc.enquiry_from) {
|
||||
if(doc.enquiry_from == 'Customer') {
|
||||
hide_field(['lead', 'lead_name']);
|
||||
}
|
||||
else if (doc.enquiry_from == 'Lead') {
|
||||
hide_field(['customer', 'customer_address', 'contact_person', 'customer_name', 'contact_display', 'customer_group']);
|
||||
}
|
||||
}
|
||||
|
||||
// setup fetch
|
||||
cur_frm.cscript.set_fetch();
|
||||
cur_frm.cscript.make_communication_body();
|
||||
}
|
||||
|
||||
cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {
|
||||
if(doc.enquiry_from == 'Lead' && doc.lead) {
|
||||
cur_frm.cscript.lead(doc,cdt,cdn);
|
||||
}
|
||||
}
|
||||
|
||||
// fetch
|
||||
// ===============================================================
|
||||
cur_frm.cscript.set_fetch = function() {
|
||||
// item
|
||||
cur_frm.add_fetch('item_code', 'item_name', 'item_name');
|
||||
cur_frm.add_fetch('item_code', 'stock_uom', 'uom');
|
||||
cur_frm.add_fetch('item_code', 'description', 'description');
|
||||
cur_frm.add_fetch('item_code', 'item_group', 'item_group');
|
||||
cur_frm.add_fetch('item_code', 'brand', 'brand');
|
||||
|
||||
// customer
|
||||
}
|
||||
|
||||
// hide - unhide fields on basis of enquiry_from lead or customer
|
||||
cur_frm.cscript.enquiry_from = function(doc,cdt,cdn){
|
||||
cur_frm.cscript.lead_cust_show(doc,cdt,cdn);
|
||||
}
|
||||
|
||||
// hide - unhide fields based on lead or customer
|
||||
cur_frm.cscript.lead_cust_show = function(doc,cdt,cdn){
|
||||
if(doc.enquiry_from == 'Lead'){
|
||||
unhide_field(['lead']);
|
||||
hide_field(['lead_name','customer','customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
doc.lead = doc.lead_name = doc.customer = doc.customer_address = doc.contact_person = doc.address_display = doc.contact_display = doc.contact_mobile = doc.contact_email = doc.territory = doc.customer_group = "";
|
||||
}
|
||||
else if(doc.enquiry_from == 'Customer'){
|
||||
unhide_field(['customer']);
|
||||
hide_field(['lead','lead_name','address_display','contact_display','contact_mobile','contact_email','territory']);
|
||||
doc.lead = doc.lead_name = doc.customer = doc.customer_address = doc.contact_person = doc.address_display = doc.contact_display = doc.contact_mobile = doc.contact_email = doc.territory = doc.customer_group = "";
|
||||
}
|
||||
}
|
||||
|
||||
// customer
|
||||
cur_frm.cscript.customer = function(doc,dt,dn) {
|
||||
if(doc.customer) get_server_fields('get_default_customer_address', JSON.stringify({customer: doc.customer}),'', doc, dt, dn, 1);
|
||||
if(doc.customer) unhide_field(['customer_name','customer_address','contact_person','address_display','contact_display','contact_mobile','contact_email','territory','customer_group']);
|
||||
}
|
||||
|
||||
cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
||||
if(doc.customer) get_server_fields('get_customer_address', JSON.stringify({customer: doc.customer, address: doc.customer_address, contact: doc.contact_person}),'', doc, dt, dn, 1);
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.customer_address.on_new = function(dn) {
|
||||
locals['Address'][dn].customer = locals[cur_frm.doctype][cur_frm.docname].customer;
|
||||
locals['Address'][dn].customer_name = locals[cur_frm.doctype][cur_frm.docname].customer_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.contact_person.on_new = function(dn) {
|
||||
locals['Contact'][dn].customer = locals[cur_frm.doctype][cur_frm.docname].customer;
|
||||
locals['Contact'][dn].customer_name = locals[cur_frm.doctype][cur_frm.docname].customer_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,address_line1,city FROM tabAddress WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,CONCAT(first_name," ",ifnull(last_name,"")) As FullName,department,designation FROM tabContact WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
// lead
|
||||
cur_frm.fields_dict['lead'].get_query = function(doc,cdt,cdn){
|
||||
return 'SELECT `tabLead`.name, `tabLead`.lead_name FROM `tabLead` WHERE `tabLead`.%(key)s LIKE "%s" ORDER BY `tabLead`.`name` ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.cscript.lead = function(doc, cdt, cdn) {
|
||||
if(doc.lead) get_server_fields('get_lead_details', doc.lead,'', doc, cdt, cdn, 1);
|
||||
if(doc.lead) unhide_field(['lead_name','address_display','contact_mobile','contact_email','territory']);
|
||||
}
|
||||
|
||||
|
||||
//item getquery
|
||||
//=======================================
|
||||
cur_frm.fields_dict['enquiry_details'].grid.get_field('item_code').get_query = function(doc, cdt, cdn) {
|
||||
if (doc.enquiry_type == 'Maintenance')
|
||||
return 'SELECT tabItem.name,tabItem.item_name,tabItem.description FROM tabItem WHERE tabItem.is_service_item="Yes" AND (ifnull(`tabItem`.`end_of_life`,"") = "" OR `tabItem`.`end_of_life` > NOW() OR `tabItem`.`end_of_life`="0000-00-00") AND tabItem.%(key)s LIKE "%s" LIMIT 50';
|
||||
else
|
||||
return 'SELECT tabItem.name,tabItem.item_name,tabItem.description FROM tabItem WHERE tabItem.is_sales_item="Yes" AND (ifnull(`tabItem`.`end_of_life`,"") = "" OR `tabItem`.`end_of_life` > NOW() OR `tabItem`.`end_of_life`="0000-00-00") AND tabItem.%(key)s LIKE "%s" LIMIT 50';
|
||||
}
|
||||
|
||||
// Create New Quotation
|
||||
cur_frm.cscript['Create Quotation'] = function(){
|
||||
n = createLocal("Quotation");
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals["Quotation"][n]]),
|
||||
'from_doctype':'Opportunity',
|
||||
'to_doctype':'Quotation',
|
||||
'from_docname':cur_frm.docname,
|
||||
'from_to_list':"[['Opportunity', 'Quotation'],['Opportunity Item','Quotation Item']]"
|
||||
}
|
||||
, function(r,rt) {
|
||||
loaddoc("Quotation", n);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// declare enquiry lost
|
||||
//-------------------------
|
||||
cur_frm.cscript['Declare Opportunity Lost'] = function(){
|
||||
var e_lost_dialog;
|
||||
|
||||
set_e_lost_dialog = function(){
|
||||
e_lost_dialog = new Dialog(400,150,'Add Opportunity Lost Reason');
|
||||
e_lost_dialog.make_body([
|
||||
['HTML', 'Message', '<div class="comment">Please add enquiry lost reason</div>'],
|
||||
['Text', 'Opportunity Lost Reason'],
|
||||
['HTML', 'Response', '<div class = "comment" id="update_enquiry_dialog_response"></div>'],
|
||||
['HTML', 'Add Reason', '<div></div>']
|
||||
]);
|
||||
|
||||
var add_reason_btn1 = $a($i(e_lost_dialog.widgets['Add Reason']), 'button', 'button');
|
||||
add_reason_btn1.innerHTML = 'Add';
|
||||
add_reason_btn1.onclick = function(){ e_lost_dialog.add(); }
|
||||
|
||||
var add_reason_btn2 = $a($i(e_lost_dialog.widgets['Add Reason']), 'button', 'button');
|
||||
add_reason_btn2.innerHTML = 'Cancel';
|
||||
$y(add_reason_btn2,{marginLeft:'4px'});
|
||||
add_reason_btn2.onclick = function(){ e_lost_dialog.hide();}
|
||||
|
||||
e_lost_dialog.onshow = function() {
|
||||
e_lost_dialog.widgets['Opportunity Lost Reason'].value = '';
|
||||
$i('update_enquiry_dialog_response').innerHTML = '';
|
||||
}
|
||||
|
||||
e_lost_dialog.add = function() {
|
||||
// sending...
|
||||
$i('update_enquiry_dialog_response').innerHTML = 'Processing...';
|
||||
var arg = strip(e_lost_dialog.widgets['Opportunity Lost Reason'].value);
|
||||
var call_back = function(r,rt) {
|
||||
if(r.message == 'true'){
|
||||
$i('update_enquiry_dialog_response').innerHTML = 'Done';
|
||||
e_lost_dialog.hide();
|
||||
}
|
||||
}
|
||||
if(arg) {
|
||||
$c_obj(make_doclist(cur_frm.doc.doctype, cur_frm.doc.name),'declare_enquiry_lost',arg,call_back);
|
||||
}
|
||||
else{
|
||||
msgprint("Please add enquiry lost reason");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(!e_lost_dialog){
|
||||
set_e_lost_dialog();
|
||||
}
|
||||
e_lost_dialog.show();
|
||||
}
|
||||
|
||||
//get query select Territory
|
||||
cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s" ORDER BY `tabTerritory`.`name` ASC LIMIT 50';}
|
||||
229
selling/doctype/opportunity/opportunity.py
Normal file
229
selling/doctype/opportunity/opportunity.py
Normal file
@@ -0,0 +1,229 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
from utilities.transaction_base import TransactionBase
|
||||
|
||||
class DocType(TransactionBase):
|
||||
def __init__(self,doc,doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
self.fname = 'enq_details'
|
||||
self.tname = 'Opportunity Item'
|
||||
|
||||
# Autoname
|
||||
# ====================================================================================================================
|
||||
def autoname(self):
|
||||
self.doc.name = make_autoname(self.doc.naming_series+'.####')
|
||||
|
||||
#--------Get customer address-------
|
||||
# ====================================================================================================================
|
||||
def get_cust_address(self,name):
|
||||
details = sql("select customer_name, address, territory, customer_group from `tabCustomer` where name = '%s' and docstatus != 2" %(name), as_dict = 1)
|
||||
if details:
|
||||
ret = {
|
||||
'customer_name': details and details[0]['customer_name'] or '',
|
||||
'address' : details and details[0]['address'] or '',
|
||||
'territory' : details and details[0]['territory'] or '',
|
||||
'customer_group' : details and details[0]['customer_group'] 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 customer = '%s' and is_customer = 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 ''
|
||||
ret['contact_no'] = contact_det and contact_det[0]['contact_no'] or ''
|
||||
ret['email_id'] = contact_det and contact_det[0]['email_id'] or ''
|
||||
|
||||
return ret
|
||||
else:
|
||||
msgprint("Customer : %s does not exist in system." % (name))
|
||||
raise Exception
|
||||
|
||||
|
||||
# ====================================================================================================================
|
||||
def get_contact_details(self, arg):
|
||||
arg = eval(arg)
|
||||
contact = sql("select contact_no, email_id from `tabContact` where contact_name = '%s' and customer_name = '%s'" %(arg['contact_person'],arg['customer']), as_dict = 1)
|
||||
ret = {
|
||||
'contact_no' : contact and contact[0]['contact_no'] or '',
|
||||
'email_id' : contact and contact[0]['email_id'] or ''
|
||||
}
|
||||
return ret
|
||||
|
||||
# ====================================================================================================================
|
||||
def on_update(self):
|
||||
# Add to calendar
|
||||
#if self.doc.contact_date and self.doc.last_contact_date != self.doc.contact_date:
|
||||
if self.doc.contact_date and self.doc.contact_date_ref != self.doc.contact_date:
|
||||
if self.doc.contact_by:
|
||||
self.add_calendar_event()
|
||||
set(self.doc, 'contact_date_ref',self.doc.contact_date)
|
||||
set(self.doc, 'status', 'Draft')
|
||||
|
||||
# Add to Calendar
|
||||
# ====================================================================================================================
|
||||
def add_calendar_event(self):
|
||||
desc=''
|
||||
user_lst =[]
|
||||
if self.doc.customer:
|
||||
if self.doc.contact_person:
|
||||
desc = 'Contact '+cstr(self.doc.contact_person)
|
||||
else:
|
||||
desc = 'Contact customer '+cstr(self.doc.customer)
|
||||
elif self.doc.lead:
|
||||
if self.doc.lead_name:
|
||||
desc = 'Contact '+cstr(self.doc.lead_name)
|
||||
else:
|
||||
desc = 'Contact lead '+cstr(self.doc.lead)
|
||||
desc = desc+ '. By : ' + cstr(self.doc.contact_by)
|
||||
|
||||
if self.doc.to_discuss:
|
||||
desc = desc+' To Discuss : ' + cstr(self.doc.to_discuss)
|
||||
|
||||
ev = Document('Event')
|
||||
ev.description = desc
|
||||
ev.event_date = self.doc.contact_date
|
||||
ev.event_hour = '10:00'
|
||||
ev.event_type = 'Private'
|
||||
ev.ref_type = 'Opportunity'
|
||||
ev.ref_name = self.doc.name
|
||||
ev.save(1)
|
||||
|
||||
user_lst.append(self.doc.owner)
|
||||
|
||||
chk = sql("select t1.name from `tabProfile` t1, `tabSales Person` t2 where t2.email_id = t1.name and t2.name=%s",self.doc.contact_by)
|
||||
if chk:
|
||||
user_lst.append(chk[0][0])
|
||||
|
||||
for d in user_lst:
|
||||
ch = addchild(ev, 'event_individuals', 'Event User', 0)
|
||||
ch.person = d
|
||||
ch.save(1)
|
||||
|
||||
#--------------Validation For Last Contact Date-----------------
|
||||
# ====================================================================================================================
|
||||
def set_last_contact_date(self):
|
||||
if self.doc.contact_date_ref and self.doc.contact_date_ref != self.doc.contact_date:
|
||||
if getdate(self.doc.contact_date_ref) < getdate(self.doc.contact_date):
|
||||
self.doc.last_contact_date=self.doc.contact_date_ref
|
||||
else:
|
||||
msgprint("Contact Date Cannot be before Last Contact Date")
|
||||
raise Exception
|
||||
|
||||
# check if item present in item table
|
||||
# ====================================================================================================================
|
||||
def validate_item_details(self):
|
||||
if not getlist(self.doclist, 'enquiry_details'):
|
||||
msgprint("Please select items for which enquiry needs to be made")
|
||||
raise Exception
|
||||
|
||||
#check if enquiry date in the range of fiscal year selected
|
||||
#=====================================================
|
||||
def validate_fiscal_year(self):
|
||||
fy=sql("select year_start_date from `tabFiscal Year` where name='%s'"%self.doc.fiscal_year)
|
||||
ysd=fy and fy[0][0] or ""
|
||||
yed=add_days(str(ysd),365)
|
||||
if str(self.doc.transaction_date) < str(ysd) or str(self.doc.transaction_date) > str(yed):
|
||||
msgprint("Opportunity Date is not within the Fiscal Year selected")
|
||||
raise Exception
|
||||
|
||||
def validate_lead_cust(self):
|
||||
if self.doc.enquiry_from == 'Lead' and not self.doc.lead:
|
||||
msgprint("Lead Id is mandatory if 'Opportunity From' is selected as Lead", raise_exception=1)
|
||||
elif self.doc.enquiry_from == 'Customer' and not self.doc.customer:
|
||||
msgprint("Customer is mandatory if 'Opportunity From' is selected as Customer", raise_exception=1)
|
||||
|
||||
|
||||
def validate(self):
|
||||
self.validate_fiscal_year()
|
||||
self.set_last_contact_date()
|
||||
self.validate_item_details()
|
||||
self.validate_lead_cust()
|
||||
|
||||
# On Submit Functions
|
||||
# ====================================================================================================================
|
||||
def on_submit(self):
|
||||
set(self.doc, 'status', 'Submitted')
|
||||
|
||||
# ====================================================================================================================
|
||||
def on_cancel(self):
|
||||
chk = sql("select t1.name from `tabQuotation` t1, `tabQuotation Item` t2 where t2.parent = t1.name and t1.docstatus=1 and (t1.status!='Order Lost' and t1.status!='Cancelled') and t2.prevdoc_docname = %s",self.doc.name)
|
||||
if chk:
|
||||
msgprint("Quotation No. "+cstr(chk[0][0])+" is submitted against this Opportunity. Thus can not be cancelled.")
|
||||
raise Exception
|
||||
else:
|
||||
set(self.doc, 'status', 'Cancelled')
|
||||
|
||||
# declare as enquiry lost
|
||||
#---------------------------
|
||||
def declare_enquiry_lost(self,arg):
|
||||
chk = sql("select t1.name from `tabQuotation` t1, `tabQuotation Item` t2 where t2.parent = t1.name and t1.docstatus=1 and (t1.status!='Order Lost' and t1.status!='Cancelled') and t2.prevdoc_docname = %s",self.doc.name)
|
||||
if chk:
|
||||
msgprint("Quotation No. "+cstr(chk[0][0])+" is submitted against this Opportunity. Thus 'Opportunity Lost' can not be declared against it.")
|
||||
raise Exception
|
||||
else:
|
||||
set(self.doc, 'status', 'Opportunity Lost')
|
||||
set(self.doc, 'order_lost_reason', arg)
|
||||
return 'true'
|
||||
|
||||
#---------------------- Add details in follow up table----------------
|
||||
# ====================================================================================================================
|
||||
def add_in_follow_up(self,message,type):
|
||||
import datetime
|
||||
child = addchild( self.doc, 'follow_up', 'Communication Log', 1, self.doclist)
|
||||
child.date = datetime.datetime.now().date().strftime('%Y-%m-%d')
|
||||
child.notes = message
|
||||
child.follow_up_type = type
|
||||
child.save()
|
||||
|
||||
#-------------------SMS----------------------------------------------
|
||||
# ====================================================================================================================
|
||||
def send_sms(self):
|
||||
if not self.doc.sms_message:
|
||||
msgprint("Please enter message in SMS Section ")
|
||||
raise Exception
|
||||
elif not getlist(self.doclist, 'enquiry_sms_detail'):
|
||||
msgprint("Please mention mobile no. to which sms needs to be sent")
|
||||
raise Exception
|
||||
else:
|
||||
receiver_list = []
|
||||
for d in getlist(self.doclist,'enquiry_sms_detail'):
|
||||
if d.other_mobile_no:
|
||||
receiver_list.append(d.other_mobile_no)
|
||||
|
||||
if receiver_list:
|
||||
msgprint(get_obj('SMS Control', 'SMS Control').send_sms(receiver_list, self.doc.sms_message))
|
||||
self.add_in_follow_up(self.doc.sms_message,'SMS')
|
||||
640
selling/doctype/opportunity/opportunity.txt
Normal file
640
selling/doctype/opportunity/opportunity.txt
Normal file
@@ -0,0 +1,640 @@
|
||||
# DocType, Opportunity
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-05-15 12:14:52',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-05-31 12:42:38',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1324284087',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'document_type': u'Transaction',
|
||||
'is_submittable': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'search_fields': u'status,transaction_date,customer,lead,enquiry_type,territory,company',
|
||||
'section_style': u'Tabbed',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'subject': u'To %(customer_name)s%(lead_name)s on %(transaction_date)s',
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Opportunity',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Opportunity',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Opportunity
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Opportunity'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales Manager',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'System Manager',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'System Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales User',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 0,
|
||||
'cancel': 0,
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales User',
|
||||
'submit': 0,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'amend': 1,
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Manager',
|
||||
'submit': 1,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Enter customer enquiry for which you might raise a quotation in future',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'basic_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Basic Info',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'To manage multiple series please go to Setup > Manage Series',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'naming_series',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Naming Series',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'naming_series',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'ENQUIRY\nENQ',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'enquiry_from',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Opportunity From',
|
||||
'oldfieldname': u'enquiry_from',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nLead\nCustomer',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'reqd': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Customer',
|
||||
'oldfieldname': u'customer',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Customer',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'lead',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Lead',
|
||||
'oldfieldname': u'lead',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Lead',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break0',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'default': u'Draft',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'status',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Status',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'status',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nDraft\nSubmitted\nQuotation Sent\nOrder Confirmed\nOpportunity Lost\nCancelled',
|
||||
'permlevel': 1,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'enquiry_type',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Opportunity Type',
|
||||
'oldfieldname': u'enquiry_type',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'\nSales\nMaintenance',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'items',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Items',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u"Items which do not exist in Item master can also be entered on customer's request",
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'enquiry_details',
|
||||
'fieldtype': u'Table',
|
||||
'label': u'Opportunity Items',
|
||||
'oldfieldname': u'enquiry_details',
|
||||
'oldfieldtype': u'Table',
|
||||
'options': u'Opportunity Item',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Keep a track of communication related to this enquiry which will help for future reference.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'communication_history',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Communication History',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 1,
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'communication_html',
|
||||
'fieldtype': u'HTML',
|
||||
'label': u'Communication HTML',
|
||||
'oldfieldname': u'follow_up',
|
||||
'oldfieldtype': u'Table',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'Contact Info',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_person',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Contact Person',
|
||||
'options': u'Contact',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_address',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Customer Address',
|
||||
'options': u'Address',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_name',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Customer Name',
|
||||
'permlevel': 1,
|
||||
'print_hide': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'address_display',
|
||||
'fieldtype': u'Small Text',
|
||||
'hidden': 0,
|
||||
'label': u'Address',
|
||||
'oldfieldname': u'address',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break3',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_display',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Contact',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_email',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Contact Email',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_mobile',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Contact Mobile No',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'lead_name',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 0,
|
||||
'label': u'Name',
|
||||
'oldfieldname': u'lead_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u'eval:doc.enquiry_from=="Customer"',
|
||||
'description': u'<a href="javascript:cur_frm.cscript.CGHelp();">To Manage Customer Groups, click here</a>',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_group',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Customer Group',
|
||||
'oldfieldname': u'customer_group',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Customer Group',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'<a href="javascript:cur_frm.cscript.TerritoryHelp();">To Manage Territory, click here</a>',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'territory',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Territory',
|
||||
'options': u'Territory',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Filing in Additional Information about the Opportunity will help you analyze your data better.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'more_info',
|
||||
'fieldtype': u'Section Break',
|
||||
'label': u'More Info',
|
||||
'oldfieldtype': u'Section Break',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break1',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'Today',
|
||||
'description': u'The date at which current entry is made in system.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'transaction_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Opportunity Date',
|
||||
'oldfieldname': u'transaction_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'width': u'50px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'fiscal_year',
|
||||
'fieldtype': u'Select',
|
||||
'in_filter': 1,
|
||||
'label': u'Fiscal Year',
|
||||
'oldfieldname': u'fiscal_year',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u'link:Fiscal Year',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'source',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Source',
|
||||
'oldfieldname': u'source',
|
||||
'oldfieldtype': u'Select',
|
||||
'options': u"\nExisting Customer\nReference\nAdvertisement\nCold Calling\nExhibition\nSupplier Reference\nMass Mailing\nCustomer's Vendor\nCampaign\nWalk In",
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Enter name of campaign if source of enquiry is campaign',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'campaign',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Campaign',
|
||||
'oldfieldname': u'campaign',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Campaign',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u'eval:!doc.__islocal',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'order_lost_reason',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Quotation Lost Reason',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'order_lost_reason',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 1,
|
||||
'report_hide': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'company',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Company',
|
||||
'oldfieldname': u'company',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Company',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break2',
|
||||
'fieldtype': u'Column Break',
|
||||
'oldfieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Your sales person who will contact the customer in future',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_by',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Next Contact By',
|
||||
'oldfieldname': u'contact_by',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Profile',
|
||||
'permlevel': 0,
|
||||
'width': u'75px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'Your sales person will get a reminder on this date to contact the customer',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Next Contact Date',
|
||||
'oldfieldname': u'contact_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 0,
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u'eval:!doc.__islocal',
|
||||
'description': u'Date on which the lead was last contacted',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'last_contact_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Last Contact Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'last_contact_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'to_discuss',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'To Discuss',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'to_discuss',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amended_from',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Amended From',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'amended_from',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amendment_date',
|
||||
'fieldtype': u'Date',
|
||||
'label': u'Amendment Date',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'amendment_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'150px'
|
||||
}
|
||||
]
|
||||
41
selling/doctype/opportunity/opportunity_list.js
Normal file
41
selling/doctype/opportunity/opportunity_list.js
Normal file
@@ -0,0 +1,41 @@
|
||||
wn.doclistviews['Opportunity'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d)
|
||||
this.fields = this.fields.concat([
|
||||
'tabOpportunity.enquiry_from',
|
||||
'tabOpportunity.lead_name',
|
||||
'tabOpportunity.customer_name',
|
||||
'tabOpportunity.status',
|
||||
'tabOpportunity.transaction_date',
|
||||
]);
|
||||
this.stats = this.stats.concat(['status', 'source', 'enquiry_from', 'company']);
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
if(['Order Confirmed', 'Quotation Sent']
|
||||
.indexOf(data.status)!=-1) {
|
||||
data.label_type = 'success';
|
||||
} else if(data.status == 'Draft') {
|
||||
data.label_type = 'info';
|
||||
} else if(data.status == 'Submit') {
|
||||
data.label_type = 'important';
|
||||
}
|
||||
data.status_html = repl('<span class="label label-%(label_type)s">%(status)s</span>', data);
|
||||
if(data.enquiry_from == 'Lead') {
|
||||
data.enquiry_name = repl('[%(enquiry_from)s] %(lead_name)s', data);
|
||||
} else {
|
||||
data.enquiry_name = repl('[%(enquiry_from)s] %(customer_name)s', data);
|
||||
}
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content: 'check'},
|
||||
{width: '15%', content:'name'},
|
||||
{width: '18%', content:'status_html'},
|
||||
{width: '52%', content:'enquiry_name+tags', css: {color:'#222'}},
|
||||
{width: '12%', content:'transaction_date',
|
||||
css: {'text-align': 'right', 'color':'#777'},
|
||||
title: "Opportunity Date", type: "date"}
|
||||
]
|
||||
})
|
||||
1
selling/doctype/opportunity_item/__init__.py
Normal file
1
selling/doctype/opportunity_item/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
140
selling/doctype/opportunity_item/opportunity_item.txt
Normal file
140
selling/doctype/opportunity_item/opportunity_item.txt
Normal file
@@ -0,0 +1,140 @@
|
||||
# DocType, Opportunity Item
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:08',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:08',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 59
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Opportunity Item',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocType, Opportunity Item
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Opportunity Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_code',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Item Code',
|
||||
'oldfieldname': u'item_code',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item',
|
||||
'reqd': 0,
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_name',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Item Name',
|
||||
'oldfieldname': u'item_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Text',
|
||||
'reqd': 1,
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_group',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'label': u'Item Group',
|
||||
'oldfieldname': u'item_group',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item Group',
|
||||
'print_hide': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'brand',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'label': u'Brand',
|
||||
'oldfieldname': u'brand',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Brand',
|
||||
'print_hide': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'basic_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 1,
|
||||
'label': u'Basic Rate',
|
||||
'oldfieldname': u'basic_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Qty',
|
||||
'oldfieldname': u'qty',
|
||||
'oldfieldtype': u'Currency'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'uom',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'UOM',
|
||||
'oldfieldname': u'uom',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'UOM',
|
||||
'search_index': 0
|
||||
}
|
||||
]
|
||||
1
selling/doctype/plot_control/__init__.py
Normal file
1
selling/doctype/plot_control/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
246
selling/doctype/plot_control/plot_control.py
Normal file
246
selling/doctype/plot_control/plot_control.py
Normal file
@@ -0,0 +1,246 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class DocType:
|
||||
def __init__(self,doc,doclist = []):
|
||||
self.doc ,self.doclist = doc, doclist
|
||||
|
||||
#============================get monthly sales====================================================
|
||||
def get_monthwise_amount(self,lst):
|
||||
lst = lst.split(',')
|
||||
if not lst[1]:
|
||||
ret = convert_to_lists(sql("SELECT SUM(grand_total) AMOUNT,CASE MONTH(due_date) WHEN 1 THEN 'JAN' WHEN 2 THEN 'FEB' WHEN 3 THEN 'MAR' WHEN 4 THEN 'APR' WHEN 5 THEN 'MAY' WHEN 6 THEN 'JUN' WHEN 7 THEN 'JUL' WHEN 8 THEN 'AUG' WHEN 9 THEN 'SEP' WHEN 10 THEN 'OCT' WHEN 11 THEN 'NOV' WHEN 12 THEN 'DEC' END MONTHNAME FROM `tabSales Invoice` WHERE docstatus = 1 AND fiscal_year = '%s' GROUP BY MONTH(due_date) ORDER BY MONTH(due_date)"%lst[0]))
|
||||
else:
|
||||
ret = convert_to_lists(sql("select sum(t2.amount) AMOUNT ,CASE MONTH(t1.due_date) WHEN 1 THEN 'JAN' WHEN 2 THEN 'FEB' WHEN 3 THEN 'MAR' WHEN 4 THEN 'APR' WHEN 5 THEN 'MAY' WHEN 6 THEN 'JUN' WHEN 7 THEN 'JUL' WHEN 8 THEN 'AUG' WHEN 9 THEN 'SEP' WHEN 10 THEN 'OCT' WHEN 11 THEN 'NOV' WHEN 12 THEN 'DEC' END MONTHNAME from `tabSales Invoice` t1,`tabSales Invoice Item` t2 WHERE t1.name = t2.parent and t1.docstatus = 1 and t2.item_group = '%s' AND t1.fiscal_year = '%s' GROUP BY MONTH(t1.due_date) ORDER BY MONTH(t1.due_date)"%(lst[1],lst[0])))
|
||||
|
||||
m =cint(sql("select month('%s')"%(get_defaults()['year_start_date']))[0][0])
|
||||
|
||||
lst1 = [[1,'JAN'],[2 ,'FEB'], [3,'MAR'],[4,'APR'],[5,'MAY'],[6,'JUN'],[7,'JUL'],[8,'AUG'],[9,'SEP'],[10,'OCT'],[11,'NOV'],[12,'DEC']]
|
||||
lst2=[]
|
||||
k=1
|
||||
|
||||
for i in range(1,13):
|
||||
for j in lst1:
|
||||
if j[0]==m:
|
||||
lst2.append([k,j[1]])
|
||||
m +=1
|
||||
if m==13: m=1
|
||||
k +=1
|
||||
return {'msg_data':ret,'x_axis':lst2}
|
||||
|
||||
#===============================get weekly sales=================================================
|
||||
def get_weekwise_amount(self,lst):
|
||||
|
||||
lst = lst.split(',')
|
||||
|
||||
cases = self.get_week_cases(lst[0],lst[1])
|
||||
|
||||
if not lst[2]:
|
||||
query = "SELECT SUM(grand_total) AMOUNT,CASE WEEK(due_date)"+ cases +"END Weekly FROM `tabSales Invoice` WHERE MONTH(due_date) = %d AND docstatus = 1 AND fiscal_year = '%s' GROUP BY Weekly ORDER BY Weekly"
|
||||
|
||||
ret = convert_to_lists(sql(query%(cint(lst[0]),lst[1])))
|
||||
|
||||
else:
|
||||
|
||||
query = "SELECT SUM(t2.amount) AMOUNT,CASE WEEK(t1.due_date)" + cases + "END Weekly FROM `tabSales Invoice` t1, `tabSales Invoice Item` t2 WHERE MONTH(t1.due_date) = %d AND t1.docstatus = 1 AND t1.fiscal_year = '%s' AND t1.name = t2.parent AND t2.item_group ='%s' GROUP BY Weekly ORDER BY Weekly"
|
||||
|
||||
ret =convert_to_lists(sql(query%(cint(lst[0]),lst[1],lst[2])))
|
||||
|
||||
return ret and ret or ''
|
||||
#================================================================================
|
||||
def get_week_cases(self,m1,fy):
|
||||
d1 = self.make_date("%s,%s"%(cstr(m1),fy))
|
||||
|
||||
w = sql("select week('%s'),week(last_day('%s'))"%(d1,d1))
|
||||
w1 = cint(w[0][0])
|
||||
w2 = cint(w[0][1])
|
||||
|
||||
w3 = []
|
||||
str1 = " "
|
||||
for i in range(1,7):
|
||||
if(w1 <= w2):
|
||||
w3.append(w1)
|
||||
str1 += "WHEN "+ cstr(w1) +" THEN 'Week"+cstr(i) +"' "
|
||||
w1 += 1
|
||||
|
||||
return str1
|
||||
|
||||
#===============================get yearly weekwise sales=================================================
|
||||
def get_year_weekwise_amount(self,lst):
|
||||
|
||||
lst = lst.split(',')
|
||||
yr_st = get_defaults()['year_start_date']
|
||||
|
||||
fy = lst[0]
|
||||
m1 = cint(yr_st.split('-')[1])
|
||||
|
||||
cases = ' '
|
||||
for i in range(1,13):
|
||||
cases += self.get_week_cases(m1,fy)
|
||||
m1 +=1
|
||||
if(m1 == 13): m1 = 1
|
||||
|
||||
if not lst[1]:
|
||||
query = "SELECT SUM(grand_total) AMOUNT,CASE WEEK(due_date)"+cases+"END Weekly, month(due_date) month FROM `tabSales Invoice` WHERE docstatus = 1 AND fiscal_year = '%s' GROUP BY `month`,weekly ORDER BY `month`,weekly"
|
||||
ret = convert_to_lists(sql(query%lst[0]))
|
||||
|
||||
else:
|
||||
|
||||
query = "SELECT SUM(t2.amount) AMOUNT,CASE WEEK(t1.due_date)" + cases + "END Weekly, month(due_date) month FROM `tabSales Invoice` t1, `tabSales Invoice Item` t2 WHERE t1.docstatus = 1 AND t1.fiscal_year = '%s' AND t1.name = t2.parent AND t2.item_group ='%s' GROUP BY Weekly ORDER BY Weekly"
|
||||
ret = convert_to_lists(sql(query%(lst[0],lst[1])))
|
||||
|
||||
|
||||
return ret and ret or ''
|
||||
|
||||
|
||||
#====================================make yearly weekwise dates================================================
|
||||
def yr_wk_dates(self,fy):
|
||||
|
||||
from datetime import date
|
||||
yr_st = get_defaults()['year_start_date']
|
||||
yr_en = get_defaults()['year_end_date']
|
||||
|
||||
fy = fy.split('-')
|
||||
y1 = yr_st.split('-')
|
||||
date1 = date(cint(fy[0]),cint(y1[1]),cint(y1[2]))
|
||||
|
||||
y2 = yr_en.split('-')
|
||||
date2 = date(cint(fy[1]),cint(y2[1]),cint(y2[2]))
|
||||
|
||||
|
||||
|
||||
date_lst = [[1,self.get_months(cint(y1[1]))]]
|
||||
m1=cint(y1[1])+1
|
||||
x_axis_lst = [[1,'Week1',cint(y1[1])]]
|
||||
|
||||
from datetime import date, timedelta
|
||||
d =dt= date1
|
||||
|
||||
week=k=1
|
||||
for i in range(0,53):
|
||||
|
||||
if dt <= date2:
|
||||
|
||||
if(d.weekday()>3):
|
||||
d = d+timedelta(7-d.weekday())
|
||||
else:
|
||||
d = d - timedelta(d.weekday())
|
||||
dlt = timedelta(days = (week-1)*7)
|
||||
dt = d + dlt + timedelta(days=6)
|
||||
|
||||
m2 = cint(sql("Select month('%s')"%dt)[0][0])
|
||||
|
||||
if(m1 == m2):
|
||||
date_lst.append([i+2,self.get_months(m2)])
|
||||
x_axis_lst.append([i+2,'Week1',m2])
|
||||
k=1
|
||||
m1 += 1
|
||||
if(m1==13): m1 =1
|
||||
else:
|
||||
date_lst.append([i+2,' '])
|
||||
x_axis_lst.append([i+2,'Week%d'%k,m2])
|
||||
week += 1
|
||||
k +=1
|
||||
|
||||
|
||||
return [date_lst,x_axis_lst]
|
||||
#===================================================================================
|
||||
|
||||
def get_months(self,m):
|
||||
m_lst = {1:'JAN',2:'FEB',3:'MAR',4:'APR',5:'MAY',6:'JUN',7:'JUL',8:'AUG',9:'SEP',10:'OCT',11:'NOV',12:'DEC'}
|
||||
return m_lst[m]
|
||||
|
||||
|
||||
|
||||
def get_weekdates(self,lst):
|
||||
from datetime import date, timedelta
|
||||
|
||||
d = dt = self.make_date(lst)
|
||||
date_lst = [[1,cstr(d.strftime("%d/%m/%y"))]]
|
||||
week=flag =1
|
||||
j=1
|
||||
last_day = sql("select last_day('%s')"%d)[0][0]
|
||||
lst_m = cint(lst.split(',')[0])
|
||||
for i in range(2,8):
|
||||
f=0
|
||||
if(dt < last_day):
|
||||
#if(d.weekday()>4):
|
||||
#d = d+timedelta(7-d.weekday())
|
||||
#else:
|
||||
d = d - timedelta(d.weekday()-1)
|
||||
dlt = timedelta(days = (week-1)*7)
|
||||
dt = d + dlt + timedelta(days=6)
|
||||
|
||||
if(cint(sql("select month('%s')"%dt)[0][0]) == lst_m and dt!=last_day):
|
||||
for k in date_lst:
|
||||
if(cstr(dt.strftime("%d/%m/%y")) == k[1]):
|
||||
f = 1
|
||||
if f == 0:
|
||||
date_lst.append([i,cstr(dt.strftime("%d/%m/%y"))])
|
||||
|
||||
elif(dt==last_day and flag ==1):
|
||||
date_lst.append([i,cstr(last_day.strftime("%d/%m/%y"))])
|
||||
flag = 0
|
||||
|
||||
elif(flag == 1):
|
||||
date_lst.append([i,cstr(last_day.strftime("%d/%m/%y"))])
|
||||
week += 1
|
||||
|
||||
return date_lst and date_lst or ''
|
||||
|
||||
|
||||
def make_date(self,lst):
|
||||
|
||||
from datetime import date, timedelta
|
||||
lst = lst.split(',')
|
||||
year = lst[1].split('-')
|
||||
if(len(lst[0])==1): month = '0'+lst[0]
|
||||
else: month = lst[0]
|
||||
if(1<=cint(month)<=3): year = year[1]
|
||||
elif(4<=cint(month)<=12): year = year[0]
|
||||
|
||||
d = date(cint(year),cint(month),1)
|
||||
|
||||
return d
|
||||
|
||||
def get_item_groups(self):
|
||||
ret = convert_to_lists(sql("select name from `tabItem Group` where docstatus != 2 and is_group = 'No'"))
|
||||
#ret = convert_to_lists(sql("select item_group from `tabItem` where is_sales_item='Yes' and (ifnull(end_of_life,'')='' or end_of_life = '0000-00-00' or end_of_life > now()) and item_group !=''"))
|
||||
return ret and ret or ''
|
||||
|
||||
def get_fiscal_year(self):
|
||||
ret = convert_to_lists(sql("select name from `tabFiscal Year` where docstatus =0"))
|
||||
return ret and ret or ''
|
||||
30
selling/doctype/plot_control/plot_control.txt
Normal file
30
selling/doctype/plot_control/plot_control.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
# DocType, Plot Control
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:12',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:12',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'harshada@webnotestech.com'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'issingle': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'version': 215
|
||||
},
|
||||
|
||||
# DocType, Plot Control
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Plot Control'
|
||||
}
|
||||
]
|
||||
1
selling/doctype/quotation/__init__.py
Normal file
1
selling/doctype/quotation/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
340
selling/doctype/quotation/quotation.js
Normal file
340
selling/doctype/quotation/quotation.js
Normal file
@@ -0,0 +1,340 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Module CRM
|
||||
cur_frm.cscript.tname = "Quotation Item";
|
||||
cur_frm.cscript.fname = "quotation_details";
|
||||
cur_frm.cscript.other_fname = "other_charges";
|
||||
cur_frm.cscript.sales_team_fname = "sales_team";
|
||||
|
||||
// =====================================================================================
|
||||
wn.require('erpnext/selling/doctype/sales_common/sales_common.js');
|
||||
wn.require('erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js');
|
||||
wn.require('erpnext/utilities/doctype/sms_control/sms_control.js');
|
||||
wn.require('erpnext/setup/doctype/notification_control/notification_control.js');
|
||||
wn.require('erpnext/support/doctype/communication/communication.js');
|
||||
|
||||
// ONLOAD
|
||||
// ===================================================================================
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
if(!doc.quotation_to) hide_field(['customer','customer_address','contact_person','customer_name','lead', 'lead_name', 'address_display', 'contact_display', 'contact_mobile', 'contact_email', 'territory', 'customer_group']);
|
||||
if(!doc.price_list_name) set_multiple(cdt,cdn,{price_list_name:sys_defaults.price_list_name});
|
||||
if(!doc.status) set_multiple(cdt,cdn,{status:'Draft'});
|
||||
if(!doc.transaction_date) set_multiple(cdt,cdn,{transaction_date:get_today()});
|
||||
if(!doc.conversion_rate) set_multiple(cdt,cdn,{conversion_rate:'1.00'});
|
||||
if(!doc.currency && sys_defaults.currency) set_multiple(cdt,cdn,{currency:sys_defaults.currency});
|
||||
if(!doc.price_list_currency) set_multiple(cdt, cdn, {price_list_currency: doc.currency, plc_conversion_rate: 1});
|
||||
|
||||
if(!doc.company && sys_defaults.company) set_multiple(cdt,cdn,{company:sys_defaults.company});
|
||||
if(!doc.fiscal_year && sys_defaults.fiscal_year) set_multiple(cdt,cdn,{fiscal_year:sys_defaults.fiscal_year});
|
||||
|
||||
if(doc.quotation_to) {
|
||||
if(doc.quotation_to == 'Customer') {
|
||||
hide_field(['lead', 'lead_name', 'organization']);
|
||||
}
|
||||
else if (doc.quotation_to == 'Lead') {
|
||||
hide_field(['customer','customer_address','contact_person', 'customer_name','contact_display', 'customer_group']);
|
||||
}
|
||||
}
|
||||
cur_frm.cscript.make_communication_body();
|
||||
}
|
||||
|
||||
cur_frm.cscript.onload_post_render = function(doc, dt, dn) {
|
||||
var callback = function(doc, dt, dn) {
|
||||
// defined in sales_common.js
|
||||
cur_frm.cscript.update_item_details(doc, dt, dn);
|
||||
}
|
||||
cur_frm.cscript.hide_price_list_currency(doc, dt, dn, callback);
|
||||
}
|
||||
|
||||
// hide - unhide fields based on lead or customer..
|
||||
// =======================================================================================================================
|
||||
cur_frm.cscript.lead_cust_show = function(doc,cdt,cdn){
|
||||
hide_field(['lead', 'lead_name','customer','customer_address','contact_person',
|
||||
'customer_name','address_display','contact_display','contact_mobile','contact_email',
|
||||
'territory','customer_group', 'organization']);
|
||||
if(doc.quotation_to == 'Lead') unhide_field(['lead']);
|
||||
else if(doc.quotation_to == 'Customer') unhide_field(['customer']);
|
||||
|
||||
doc.lead = doc.lead_name = doc.customer = doc.customer_name = doc.customer_address = doc.contact_person = doc.address_display = doc.contact_display = doc.contact_mobile = doc.contact_email = doc.territory = doc.customer_group = doc.organization = "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
//================ hide - unhide fields on basis of quotation to either lead or customer ===============================
|
||||
cur_frm.cscript.quotation_to = function(doc,cdt,cdn){
|
||||
cur_frm.cscript.lead_cust_show(doc,cdt,cdn);
|
||||
}
|
||||
|
||||
|
||||
// REFRESH
|
||||
// ===================================================================================
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
|
||||
cur_frm.clear_custom_buttons();
|
||||
|
||||
if (!cur_frm.cscript.is_onload) cur_frm.cscript.hide_price_list_currency(doc, cdt, cdn);
|
||||
|
||||
|
||||
if(doc.docstatus == 1 && doc.status!='Order Lost') {
|
||||
cur_frm.add_custom_button('Make Sales Order', cur_frm.cscript['Make Sales Order']);
|
||||
cur_frm.add_custom_button('Set as Lost', cur_frm.cscript['Declare Order Lost']);
|
||||
cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms);
|
||||
}
|
||||
|
||||
erpnext.hide_naming_series();
|
||||
|
||||
if(doc.customer || doc.lead) $(cur_frm.fields_dict.contact_section.row.wrapper).toggle(true);
|
||||
else $(cur_frm.fields_dict.contact_section.row.wrapper).toggle(false);
|
||||
|
||||
if (!doc.__islocal) cur_frm.cscript.render_communication_list(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
|
||||
//customer
|
||||
cur_frm.cscript.customer = function(doc,dt,dn) {
|
||||
var pl = doc.price_list_name;
|
||||
var callback = function(r,rt) {
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
cur_frm.refresh();
|
||||
if (pl != doc.price_list_name) cur_frm.cscript.price_list_name(doc, dt, dn);
|
||||
}
|
||||
|
||||
if(doc.customer) $c_obj(make_doclist(doc.doctype, doc.name),
|
||||
'get_default_customer_address', '', callback);
|
||||
if(doc.customer) unhide_field(['customer_address','contact_person','territory', 'customer_group']);
|
||||
}
|
||||
|
||||
cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
||||
if(doc.customer) get_server_fields('get_customer_address', JSON.stringify({
|
||||
customer: doc.customer,
|
||||
address: doc.customer_address,
|
||||
contact: doc.contact_person
|
||||
}),'', doc, dt, dn, 1);
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.customer_address.on_new = function(dn) {
|
||||
locals['Address'][dn].customer = locals[cur_frm.doctype][cur_frm.docname].customer;
|
||||
locals['Address'][dn].customer_name = locals[cur_frm.doctype][cur_frm.docname].customer_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.contact_person.on_new = function(dn) {
|
||||
locals['Contact'][dn].customer = locals[cur_frm.doctype][cur_frm.docname].customer;
|
||||
locals['Contact'][dn].customer_name = locals[cur_frm.doctype][cur_frm.docname].customer_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,address_line1,city FROM tabAddress WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,CONCAT(first_name," ",ifnull(last_name,"")) As FullName,department,designation FROM tabContact WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
//lead
|
||||
cur_frm.fields_dict['lead'].get_query = function(doc,cdt,cdn){
|
||||
return 'SELECT `tabLead`.name, `tabLead`.lead_name FROM `tabLead` WHERE `tabLead`.%(key)s LIKE "%s" ORDER BY `tabLead`.`name` ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.cscript.lead = function(doc, cdt, cdn) {
|
||||
if(doc.lead) {
|
||||
get_server_fields('get_lead_details', doc.lead,'', doc, cdt, cdn, 1);
|
||||
unhide_field('territory');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// =====================================================================================
|
||||
cur_frm.fields_dict['enq_no'].get_query = function(doc,cdt,cdn){
|
||||
var cond='';
|
||||
var cond1='';
|
||||
if(doc.order_type) cond = 'ifnull(`tabOpportunity`.enquiry_type, "") = "'+doc.order_type+'" AND';
|
||||
if(doc.customer) cond1 = '`tabOpportunity`.customer = "'+doc.customer+'" AND';
|
||||
else if(doc.lead) cond1 = '`tabOpportunity`.lead = "'+doc.lead+'" AND';
|
||||
|
||||
return repl('SELECT `tabOpportunity`.`name` FROM `tabOpportunity` WHERE `tabOpportunity`.`docstatus` = 1 AND `tabOpportunity`.status = "Submitted" AND %(cond)s %(cond1)s `tabOpportunity`.`name` LIKE "%s" ORDER BY `tabOpportunity`.`name` ASC LIMIT 50', {cond:cond, cond1:cond1});
|
||||
}
|
||||
|
||||
// Make Sales Order
|
||||
// =====================================================================================
|
||||
cur_frm.cscript['Make Sales Order'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
|
||||
if (doc.docstatus == 1) {
|
||||
var n = createLocal("Sales Order");
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals["Sales Order"][n]]),
|
||||
'from_doctype':'Quotation',
|
||||
'to_doctype':'Sales Order',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Quotation', 'Sales Order'], ['Quotation Item', 'Sales Order Item'],['Sales Taxes and Charges','Sales Taxes and Charges'], ['Sales Team', 'Sales Team'], ['TC Detail', 'TC Detail']]"
|
||||
}, function(r,rt) {
|
||||
loaddoc("Sales Order", n);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//pull enquiry details
|
||||
cur_frm.cscript.pull_enquiry_detail = function(doc,cdt,cdn){
|
||||
|
||||
var callback = function(r,rt){
|
||||
if(r.message){
|
||||
doc.quotation_to = r.message;
|
||||
|
||||
if(doc.quotation_to == 'Lead') {
|
||||
unhide_field('lead');
|
||||
}
|
||||
else if(doc.quotation_to == 'Customer') {
|
||||
unhide_field(['customer','customer_address','contact_person','territory','customer_group']);
|
||||
}
|
||||
refresh_many(['quotation_details','quotation_to','customer','customer_address','contact_person','lead','lead_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group','order_type']);
|
||||
}
|
||||
}
|
||||
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'pull_enq_details','',callback);
|
||||
|
||||
}
|
||||
|
||||
// declare order lost
|
||||
//-------------------------
|
||||
cur_frm.cscript['Declare Order Lost'] = function(){
|
||||
var qtn_lost_dialog;
|
||||
|
||||
set_qtn_lost_dialog = function(doc,cdt,cdn){
|
||||
qtn_lost_dialog = new Dialog(400,400,'Add Quotation Lost Reason');
|
||||
qtn_lost_dialog.make_body([
|
||||
['HTML', 'Message', '<div class="comment">Please add quotation lost reason</div>'],
|
||||
['Text', 'Quotation Lost Reason'],
|
||||
['HTML', 'Response', '<div class = "comment" id="update_quotation_dialog_response"></div>'],
|
||||
['HTML', 'Add Reason', '<div></div>']
|
||||
]);
|
||||
|
||||
var add_reason_btn1 = $a($i(qtn_lost_dialog.widgets['Add Reason']), 'button', 'button');
|
||||
add_reason_btn1.innerHTML = 'Add';
|
||||
add_reason_btn1.onclick = function(){ qtn_lost_dialog.add(); }
|
||||
|
||||
var add_reason_btn2 = $a($i(qtn_lost_dialog.widgets['Add Reason']), 'button', 'button');
|
||||
add_reason_btn2.innerHTML = 'Cancel';
|
||||
$y(add_reason_btn2,{marginLeft:'4px'});
|
||||
add_reason_btn2.onclick = function(){ qtn_lost_dialog.hide();}
|
||||
|
||||
qtn_lost_dialog.onshow = function() {
|
||||
qtn_lost_dialog.widgets['Quotation Lost Reason'].value = '';
|
||||
$i('update_quotation_dialog_response').innerHTML = '';
|
||||
}
|
||||
|
||||
qtn_lost_dialog.add = function() {
|
||||
// sending...
|
||||
$i('update_quotation_dialog_response').innerHTML = 'Processing...';
|
||||
var arg = strip(qtn_lost_dialog.widgets['Quotation Lost Reason'].value);
|
||||
var call_back = function(r,rt) {
|
||||
if(r.message == 'true'){
|
||||
$i('update_quotation_dialog_response').innerHTML = 'Done';
|
||||
qtn_lost_dialog.hide();
|
||||
}
|
||||
}
|
||||
if(arg) $c_obj(make_doclist(cur_frm.doc.doctype, cur_frm.doc.name),'declare_order_lost',arg,call_back);
|
||||
else msgprint("Please add Quotation lost reason");
|
||||
}
|
||||
}
|
||||
|
||||
if(!qtn_lost_dialog){
|
||||
set_qtn_lost_dialog(doc,cdt,cdn);
|
||||
}
|
||||
qtn_lost_dialog.show();
|
||||
}
|
||||
|
||||
//===================== Quotation to validation - either customer or lead mandatory ====================
|
||||
cur_frm.cscript.quot_to_validate = function(doc,cdt,cdn){
|
||||
|
||||
if(doc.quotation_to == 'Lead'){
|
||||
|
||||
if(!doc.lead){
|
||||
alert("Lead is mandatory.");
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
else if(doc.quotation_to == 'Customer'){
|
||||
if(!doc.customer){
|
||||
alert("Customer is mandatory.");
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===================validation function =================================
|
||||
|
||||
cur_frm.cscript.validate = function(doc,cdt,cdn){
|
||||
cur_frm.cscript.recalculate_values(doc, cdt, cdn);
|
||||
cur_frm.cscript.quot_to_validate(doc,cdt,cdn);
|
||||
}
|
||||
|
||||
//================ Last Quoted Price and Last Sold Price suggestion ======================
|
||||
cur_frm.fields_dict['quotation_details'].grid.get_field('item_code').get_query= function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
var cond = (doc.order_type == 'Maintenance') ? " and item.is_service_item = 'Yes'" : " and item.is_sales_item = 'Yes'";
|
||||
if(doc.customer) {
|
||||
var export_rate_field = wn.meta.get_docfield(cdt, 'export_rate', cdn);
|
||||
var precision = (export_rate_field && export_rate_field.fieldtype) === 'Float' ? 6 : 2;
|
||||
return repl("\
|
||||
select \
|
||||
item.name, \
|
||||
( \
|
||||
select concat('Last Quote @ ', q.currency, ' ', \
|
||||
format(q_item.export_rate, %(precision)s)) \
|
||||
from `tabQuotation` q, `tabQuotation Item` q_item \
|
||||
where \
|
||||
q.name = q_item.parent \
|
||||
and q_item.item_code = item.name \
|
||||
and q.docstatus = 1 \
|
||||
and q.customer = \"%(cust)s\" \
|
||||
order by q.transaction_date desc \
|
||||
limit 1 \
|
||||
) as quote_rate, \
|
||||
( \
|
||||
select concat('Last Sale @ ', si.currency, ' ', \
|
||||
format(si_item.basic_rate, %(precision)s)) \
|
||||
from `tabSales Invoice` si, `tabSales Invoice Item` si_item \
|
||||
where \
|
||||
si.name = si_item.parent \
|
||||
and si_item.item_code = item.name \
|
||||
and si.docstatus = 1 \
|
||||
and si.customer = \"%(cust)s\" \
|
||||
order by si.voucher_date desc \
|
||||
limit 1 \
|
||||
) as sales_rate, \
|
||||
item.item_name, item.description \
|
||||
from `tabItem` item \
|
||||
where \
|
||||
item.%(key)s like \"%s\" \
|
||||
%(cond)s \
|
||||
limit 25", {
|
||||
cust: doc.customer,
|
||||
cond: cond,
|
||||
precision: precision
|
||||
});
|
||||
} else {
|
||||
return repl("SELECT name, item_name, description FROM `tabItem` item WHERE item.%(key)s LIKE '%s' %(cond)s ORDER BY item.item_code DESC LIMIT 50", {cond:cond});
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
|
||||
var args = {
|
||||
type: 'Quotation',
|
||||
doctype: 'Quotation'
|
||||
}
|
||||
cur_frm.cscript.notify(doc, args);
|
||||
}
|
||||
355
selling/doctype/quotation/quotation.py
Normal file
355
selling/doctype/quotation/quotation.py
Normal file
@@ -0,0 +1,355 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, load_json
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
from utilities.transaction_base import TransactionBase
|
||||
|
||||
class DocType(TransactionBase):
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
self.tname = 'Quotation Item'
|
||||
self.fname = 'quotation_details'
|
||||
|
||||
# Autoname
|
||||
# ---------
|
||||
def autoname(self):
|
||||
self.doc.name = make_autoname(self.doc.naming_series+'.#####')
|
||||
|
||||
|
||||
# DOCTYPE TRIGGER FUNCTIONS
|
||||
# ==============================================================================
|
||||
|
||||
# Pull Opportunity Details
|
||||
# --------------------
|
||||
def pull_enq_details(self):
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'quotation_details')
|
||||
get_obj('DocType Mapper', 'Opportunity-Quotation').dt_map('Opportunity', 'Quotation', self.doc.enq_no, self.doc, self.doclist, "[['Opportunity', 'Quotation'],['Opportunity Item', 'Quotation Item']]")
|
||||
|
||||
self.get_adj_percent()
|
||||
|
||||
return self.doc.quotation_to
|
||||
|
||||
# Get contact person details based on customer selected
|
||||
# ------------------------------------------------------
|
||||
def get_contact_details(self):
|
||||
return get_obj('Sales Common').get_contact_details(self,0)
|
||||
|
||||
|
||||
|
||||
# QUOTATION DETAILS TRIGGER FUNCTIONS
|
||||
# ================================================================================
|
||||
|
||||
# Get Item Details
|
||||
# -----------------
|
||||
def get_item_details(self, args=None):
|
||||
import json
|
||||
args = args and json.loads(args) or {}
|
||||
if args.get('item_code'):
|
||||
return get_obj('Sales Common').get_item_details(args, self)
|
||||
else:
|
||||
obj = get_obj('Sales Common')
|
||||
for doc in self.doclist:
|
||||
if doc.fields.get('item_code'):
|
||||
arg = {
|
||||
'item_code': doc.fields.get('item_code'),
|
||||
'income_account': doc.fields.get('income_account'),
|
||||
'cost_center': doc.fields.get('cost_center'),
|
||||
'warehouse': doc.fields.get('warehouse')
|
||||
}
|
||||
res = obj.get_item_details(arg, self) or {}
|
||||
for r in res:
|
||||
if not doc.fields.get(r):
|
||||
doc.fields[r] = res[r]
|
||||
|
||||
# Re-calculates Basic Rate & amount based on Price List Selected
|
||||
# --------------------------------------------------------------
|
||||
def get_adj_percent(self, arg=''):
|
||||
get_obj('Sales Common').get_adj_percent(self)
|
||||
|
||||
|
||||
|
||||
|
||||
# OTHER CHARGES TRIGGER FUNCTIONS
|
||||
# ====================================================================================
|
||||
|
||||
# Get Tax rate if account type is TAX
|
||||
# -----------------------------------
|
||||
def get_rate(self,arg):
|
||||
return get_obj('Sales Common').get_rate(arg)
|
||||
|
||||
# Load Default Charges
|
||||
# ----------------------------------------------------------
|
||||
def load_default_taxes(self):
|
||||
self.doclist = get_obj('Sales Common').load_default_taxes(self)
|
||||
|
||||
# Pull details from other charges master (Get Sales Taxes and Charges Master)
|
||||
# ----------------------------------------------------------
|
||||
def get_other_charges(self):
|
||||
self.doclist = get_obj('Sales Common').get_other_charges(self)
|
||||
|
||||
|
||||
# GET TERMS AND CONDITIONS
|
||||
# ====================================================================================
|
||||
def get_tc_details(self):
|
||||
return get_obj('Sales Common').get_tc_details(self)
|
||||
|
||||
|
||||
# VALIDATE
|
||||
# ==============================================================================================
|
||||
|
||||
# Amendment date is necessary if document is amended
|
||||
# --------------------------------------------------
|
||||
def validate_mandatory(self):
|
||||
if self.doc.amended_from and not self.doc.amendment_date:
|
||||
msgprint("Please Enter Amendment Date")
|
||||
raise Exception
|
||||
|
||||
# Fiscal Year Validation
|
||||
# ----------------------
|
||||
def validate_fiscal_year(self):
|
||||
get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.transaction_date,'Quotation Date')
|
||||
|
||||
# Does not allow same item code to be entered twice
|
||||
# -------------------------------------------------
|
||||
def validate_for_items(self):
|
||||
chk_dupl_itm = []
|
||||
for d in getlist(self.doclist,'quotation_details'):
|
||||
if [cstr(d.item_code),cstr(d.description)] in chk_dupl_itm:
|
||||
msgprint("Item %s has been entered twice. Please change description atleast to continue" % d.item_code)
|
||||
raise Exception
|
||||
else:
|
||||
chk_dupl_itm.append([cstr(d.item_code),cstr(d.description)])
|
||||
|
||||
|
||||
#do not allow sales item in maintenance quotation and service item in sales quotation
|
||||
#-----------------------------------------------------------------------------------------------
|
||||
def validate_order_type(self):
|
||||
if self.doc.order_type in ['Maintenance', 'Service']:
|
||||
for d in getlist(self.doclist, 'quotation_details'):
|
||||
is_service_item = sql("select is_service_item from `tabItem` where name=%s", d.item_code)
|
||||
is_service_item = is_service_item and is_service_item[0][0] or 'No'
|
||||
|
||||
if is_service_item == 'No':
|
||||
msgprint("You can not select non service item "+d.item_code+" in Maintenance Quotation")
|
||||
raise Exception
|
||||
else:
|
||||
for d in getlist(self.doclist, 'quotation_details'):
|
||||
is_sales_item = sql("select is_sales_item from `tabItem` where name=%s", d.item_code)
|
||||
is_sales_item = is_sales_item and is_sales_item[0][0] or 'No'
|
||||
|
||||
if is_sales_item == 'No':
|
||||
msgprint("You can not select non sales item "+d.item_code+" in Sales Quotation")
|
||||
raise Exception
|
||||
|
||||
#--------------Validation For Last Contact Date-----------------
|
||||
# ====================================================================================================================
|
||||
def set_last_contact_date(self):
|
||||
#if not self.doc.contact_date_ref:
|
||||
#self.doc.contact_date_ref=self.doc.contact_date
|
||||
#self.doc.last_contact_date=self.doc.contact_date_ref
|
||||
if self.doc.contact_date_ref and self.doc.contact_date_ref != self.doc.contact_date:
|
||||
if getdate(self.doc.contact_date_ref) < getdate(self.doc.contact_date):
|
||||
self.doc.last_contact_date=self.doc.contact_date_ref
|
||||
else:
|
||||
msgprint("Contact Date Cannot be before Last Contact Date")
|
||||
raise Exception
|
||||
#set(self.doc, 'contact_date_ref',self.doc.contact_date)
|
||||
|
||||
|
||||
# Validate
|
||||
# --------
|
||||
def validate(self):
|
||||
self.validate_fiscal_year()
|
||||
self.validate_mandatory()
|
||||
self.set_last_contact_date()
|
||||
self.validate_order_type()
|
||||
self.validate_for_items()
|
||||
sales_com_obj = get_obj('Sales Common')
|
||||
sales_com_obj.check_active_sales_items(self)
|
||||
sales_com_obj.validate_max_discount(self,'quotation_details') #verify whether rate is not greater than max_discount
|
||||
sales_com_obj.check_conversion_rate(self)
|
||||
|
||||
# Get total in words
|
||||
dcc = TransactionBase().get_company_currency(self.doc.company)
|
||||
self.doc.in_words = sales_com_obj.get_total_in_words(dcc, self.doc.rounded_total)
|
||||
self.doc.in_words_export = sales_com_obj.get_total_in_words(self.doc.currency, self.doc.rounded_total_export)
|
||||
|
||||
def on_update(self):
|
||||
# Add to calendar
|
||||
if self.doc.contact_date and self.doc.contact_date_ref != self.doc.contact_date:
|
||||
if self.doc.contact_by:
|
||||
self.add_calendar_event()
|
||||
set(self.doc, 'contact_date_ref',self.doc.contact_date)
|
||||
|
||||
# Set Quotation Status
|
||||
set(self.doc, 'status', 'Draft')
|
||||
|
||||
# subject for follow
|
||||
self.doc.subject = '[%(status)s] To %(customer)s worth %(currency)s %(grand_total)s' % self.doc.fields
|
||||
|
||||
|
||||
# Add to Calendar
|
||||
# ====================================================================================================================
|
||||
def add_calendar_event(self):
|
||||
desc=''
|
||||
user_lst =[]
|
||||
if self.doc.customer:
|
||||
if self.doc.contact_person:
|
||||
desc = 'Contact '+cstr(self.doc.contact_person)
|
||||
else:
|
||||
desc = 'Contact customer '+cstr(self.doc.customer)
|
||||
elif self.doc.lead:
|
||||
if self.doc.lead_name:
|
||||
desc = 'Contact '+cstr(self.doc.lead_name)
|
||||
else:
|
||||
desc = 'Contact lead '+cstr(self.doc.lead)
|
||||
desc = desc+ '.By : ' + cstr(self.doc.contact_by)
|
||||
|
||||
if self.doc.to_discuss:
|
||||
desc = desc+' To Discuss : ' + cstr(self.doc.to_discuss)
|
||||
|
||||
ev = Document('Event')
|
||||
ev.description = desc
|
||||
ev.event_date = self.doc.contact_date
|
||||
ev.event_hour = '10:00'
|
||||
ev.event_type = 'Private'
|
||||
ev.ref_type = 'Opportunity'
|
||||
ev.ref_name = self.doc.name
|
||||
ev.save(1)
|
||||
|
||||
user_lst.append(self.doc.owner)
|
||||
|
||||
chk = sql("select t1.name from `tabProfile` t1, `tabSales Person` t2 where t2.email_id = t1.name and t2.name=%s",self.doc.contact_by)
|
||||
if chk:
|
||||
user_lst.append(chk[0][0])
|
||||
|
||||
for d in user_lst:
|
||||
ch = addchild(ev, 'event_individuals', 'Event User', 0)
|
||||
ch.person = d
|
||||
ch.save(1)
|
||||
|
||||
#update enquiry
|
||||
#------------------
|
||||
def update_enquiry(self, flag):
|
||||
prevdoc=''
|
||||
for d in getlist(self.doclist, 'quotation_details'):
|
||||
if d.prevdoc_docname:
|
||||
prevdoc = d.prevdoc_docname
|
||||
|
||||
if prevdoc:
|
||||
if flag == 'submit': #on submit
|
||||
sql("update `tabOpportunity` set status = 'Quotation Sent' where name = %s", prevdoc)
|
||||
elif flag == 'cancel': #on cancel
|
||||
sql("update `tabOpportunity` set status = 'Open' where name = %s", prevdoc)
|
||||
elif flag == 'order lost': #order lost
|
||||
sql("update `tabOpportunity` set status = 'Opportunity Lost' where name=%s", prevdoc)
|
||||
elif flag == 'order confirm': #order confirm
|
||||
sql("update `tabOpportunity` set status='Order Confirmed' where name=%s", prevdoc)
|
||||
|
||||
# declare as order lost
|
||||
#-------------------------
|
||||
def declare_order_lost(self,arg):
|
||||
chk = sql("select t1.name from `tabSales Order` t1, `tabSales Order Item` t2 where t2.parent = t1.name and t1.docstatus=1 and t2.prevdoc_docname = %s",self.doc.name)
|
||||
if chk:
|
||||
msgprint("Sales Order No. "+cstr(chk[0][0])+" is submitted against this Quotation. Thus 'Order Lost' can not be declared against it.")
|
||||
raise Exception
|
||||
else:
|
||||
set(self.doc, 'status', 'Order Lost')
|
||||
set(self.doc, 'order_lost_reason', arg)
|
||||
self.update_enquiry('order lost')
|
||||
return 'true'
|
||||
|
||||
#check if value entered in item table
|
||||
#--------------------------------------
|
||||
def check_item_table(self):
|
||||
if not getlist(self.doclist, 'quotation_details'):
|
||||
msgprint("Please enter item details")
|
||||
raise Exception
|
||||
|
||||
# ON SUBMIT
|
||||
# =========================================================================
|
||||
def on_submit(self):
|
||||
self.check_item_table()
|
||||
if not self.doc.amended_from:
|
||||
set(self.doc, 'message', 'Quotation: '+self.doc.name+' has been sent')
|
||||
else:
|
||||
set(self.doc, 'message', 'Quotation has been amended. New Quotation no:'+self.doc.name)
|
||||
|
||||
# Check for Approving Authority
|
||||
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total, self)
|
||||
|
||||
# Set Quotation Status
|
||||
set(self.doc, 'status', 'Submitted')
|
||||
|
||||
#update enquiry status
|
||||
self.update_enquiry('submit')
|
||||
|
||||
|
||||
# ON CANCEL
|
||||
# ==========================================================================
|
||||
def on_cancel(self):
|
||||
set(self.doc, 'message', 'Quotation: '+self.doc.name+' has been cancelled')
|
||||
|
||||
#update enquiry status
|
||||
self.update_enquiry('cancel')
|
||||
|
||||
set(self.doc,'status','Cancelled')
|
||||
|
||||
|
||||
# SEND SMS
|
||||
# =============================================================================
|
||||
def send_sms(self):
|
||||
if not self.doc.customer_mobile_no:
|
||||
msgprint("Please enter customer mobile no")
|
||||
elif not self.doc.message:
|
||||
msgprint("Please enter the message you want to send")
|
||||
else:
|
||||
msgprint(get_obj("SMS Control", "SMS Control").send_sms([self.doc.contact_mobile,], self.doc.message))
|
||||
|
||||
# Print other charges
|
||||
# ===========================================================================
|
||||
def print_other_charges(self,docname):
|
||||
print_lst = []
|
||||
for d in getlist(self.doclist,'other_charges'):
|
||||
lst1 = []
|
||||
lst1.append(d.description)
|
||||
lst1.append(d.total)
|
||||
print_lst.append(lst1)
|
||||
return print_lst
|
||||
|
||||
def update_followup_details(self):
|
||||
sql("delete from `tabCommunication Log` where parent = '%s'"%self.doc.name)
|
||||
for d in getlist(self.doclist, 'follow_up'):
|
||||
d.save()
|
||||
1275
selling/doctype/quotation/quotation.txt
Normal file
1275
selling/doctype/quotation/quotation.txt
Normal file
File diff suppressed because it is too large
Load Diff
44
selling/doctype/quotation/quotation_list.js
Normal file
44
selling/doctype/quotation/quotation_list.js
Normal file
@@ -0,0 +1,44 @@
|
||||
// render
|
||||
wn.doclistviews['Quotation'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d)
|
||||
this.fields = this.fields.concat([
|
||||
"`tabQuotation`.quotation_to",
|
||||
"`tabQuotation`.lead_name",
|
||||
"`tabQuotation`.customer_name",
|
||||
"`tabQuotation`.currency",
|
||||
"ifnull(`tabQuotation`.grand_total_export,0) as grand_total_export",
|
||||
"`tabQuotation`.transaction_date",
|
||||
]);
|
||||
this.stats = this.stats.concat(['status', 'quotation_to', 'company']);
|
||||
},
|
||||
|
||||
prepare_data: function(data) {
|
||||
this._super(data);
|
||||
if(data.quotation_to == 'Lead') {
|
||||
data.quotation_name = repl('[%(quotation_to)s] %(lead_name)s', data);
|
||||
} else {
|
||||
data.quotation_name = repl('[%(quotation_to)s] %(customer_name)s', data);
|
||||
}
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content: 'check'},
|
||||
{width: '5%', content:'avatar'},
|
||||
{width: '3%', content:'docstatus'},
|
||||
{width: '15%', content:'name'},
|
||||
{width: '44%', content:'quotation_name+tags', css: {color:'#222'}},
|
||||
{
|
||||
width: '18%',
|
||||
content: function(parent, data) {
|
||||
$(parent).html(data.currency + ' ' + fmt_money(data.grand_total_export))
|
||||
},
|
||||
css: {'text-align':'right'}
|
||||
},
|
||||
{width: '12%', content:'transaction_date',
|
||||
css: {'text-align': 'right', 'color':'#777'},
|
||||
title: "Quotation Date", type: "date"}
|
||||
]
|
||||
|
||||
});
|
||||
|
||||
1
selling/doctype/quotation_item/__init__.py
Normal file
1
selling/doctype/quotation_item/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
345
selling/doctype/quotation_item/quotation_item.txt
Normal file
345
selling/doctype/quotation_item/quotation_item.txt
Normal file
@@ -0,0 +1,345 @@
|
||||
# DocType, Quotation Item
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-06-08 16:07:57',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-07-09 11:04:47',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'autoname': u'QUOD/.#####',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'is_transaction_doc': 0,
|
||||
'istable': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Tray',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Quotation Item',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# DocType, Quotation Item
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Quotation Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_code',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Item Code',
|
||||
'oldfieldname': u'item_code',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client',
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_item_code',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u"Customer's Item Code",
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_name',
|
||||
'fieldtype': u'Data',
|
||||
'in_filter': 1,
|
||||
'label': u'Item Name',
|
||||
'oldfieldname': u'item_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'reqd': 1,
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qty',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Quantity',
|
||||
'oldfieldname': u'qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'stock_uom',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'UOM',
|
||||
'oldfieldname': u'stock_uom',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 0,
|
||||
'reqd': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'ref_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Price List Rate',
|
||||
'oldfieldname': u'ref_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'adj_rate',
|
||||
'fieldtype': u'Float',
|
||||
'label': u'Discount (%)',
|
||||
'oldfieldname': u'adj_rate',
|
||||
'oldfieldtype': u'Float',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'export_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Rate',
|
||||
'oldfieldname': u'export_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'export_amount',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Amount',
|
||||
'oldfieldname': u'export_amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 0,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'base_ref_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Price List Rate*',
|
||||
'oldfieldname': u'base_ref_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'basic_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Basic Rate*',
|
||||
'oldfieldname': u'basic_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amount',
|
||||
'fieldtype': u'Currency',
|
||||
'in_filter': 0,
|
||||
'label': u'Amount*',
|
||||
'oldfieldname': u'amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'search_index': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_group',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Item Group',
|
||||
'oldfieldname': u'item_group',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item Group',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'brand',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Brand',
|
||||
'oldfieldname': u'brand',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Brand',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 1,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_tax_rate',
|
||||
'fieldtype': u'Small Text',
|
||||
'hidden': 1,
|
||||
'label': u'Item Tax Rate',
|
||||
'oldfieldname': u'item_tax_rate',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_docname',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Against Docname',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'prevdoc_docname',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_doctype',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u'Against Doctype',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'prevdoc_doctype',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 0,
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 1,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'page_break',
|
||||
'fieldtype': u'Check',
|
||||
'hidden': 0,
|
||||
'label': u'Page Break',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'page_break',
|
||||
'oldfieldtype': u'Check',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
@@ -0,0 +1,142 @@
|
||||
# DocType, Sales and Purchase Return Item
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:14',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:14',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'wasim@webnotestech.com'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 8
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Sales and Purchase Return Item',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# DocType, Sales and Purchase Return Item
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Sales and Purchase Return Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_code',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Item Code',
|
||||
'oldfieldname': u'item_code',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item',
|
||||
'permlevel': 1,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'uom',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'UOM',
|
||||
'oldfieldname': u'uom',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'UOM',
|
||||
'permlevel': 1,
|
||||
'search_index': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Rate',
|
||||
'oldfieldname': u'rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qty',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Qty',
|
||||
'oldfieldname': u'qty',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'returned_qty',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Returned Qty',
|
||||
'oldfieldname': u'returned_qty',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'serial_no',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Serial No',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'batch_no',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Batch No',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'detail_name',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u'Detail Name',
|
||||
'oldfieldname': u'detail_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1
|
||||
}
|
||||
]
|
||||
1
selling/doctype/sales_common/__init__.py
Normal file
1
selling/doctype/sales_common/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
859
selling/doctype/sales_common/sales_common.js
Normal file
859
selling/doctype/sales_common/sales_common.js
Normal file
@@ -0,0 +1,859 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Preset
|
||||
// ------
|
||||
// cur_frm.cscript.tname - Details table name
|
||||
// cur_frm.cscript.fname - Details fieldname
|
||||
// cur_frm.cscript.other_fname - wn.require('erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js'); fieldname
|
||||
// cur_frm.cscript.sales_team_fname - Sales Team fieldname
|
||||
|
||||
// ============== Load Default Taxes ===================
|
||||
cur_frm.cscript.load_taxes = function(doc, cdt, cdn, callback) {
|
||||
// run if this is not executed from dt_map...
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
if(doc.customer || getchildren('Sales Taxes and Charges', doc.name, 'other_charges', doc.doctype).length) {
|
||||
if(callback) {
|
||||
callback(doc, cdt, cdn);
|
||||
}
|
||||
} else {
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'load_default_taxes','',function(r,rt){
|
||||
refresh_field('other_charges');
|
||||
if(callback) callback(doc, cdt, cdn);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Gets called after existing item details are update to fill in
|
||||
// remaining default values
|
||||
cur_frm.cscript.load_defaults = function(doc, dt, dn, callback) {
|
||||
if(!cur_frm.doc.__islocal) { return; }
|
||||
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
var fields_to_refresh = LocalDB.set_default_values(doc);
|
||||
if(fields_to_refresh) { refresh_many(fields_to_refresh); }
|
||||
|
||||
fields_to_refresh = null;
|
||||
var children = getchildren(cur_frm.cscript.tname, doc.name, cur_frm.cscript.fname);
|
||||
if(!children) { return; }
|
||||
for(var i=0; i<children.length; i++) {
|
||||
LocalDB.set_default_values(children[i]);
|
||||
}
|
||||
refresh_field(cur_frm.cscript.fname);
|
||||
cur_frm.cscript.load_taxes(doc, dt, dn, callback);
|
||||
}
|
||||
|
||||
|
||||
// Update existing item details
|
||||
cur_frm.cscript.update_item_details = function(doc, dt, dn, callback) {
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
if(!cur_frm.doc.__islocal) return;
|
||||
var children = getchildren(cur_frm.cscript.tname, doc.name, cur_frm.cscript.fname);
|
||||
if(children.length) {
|
||||
$c_obj(make_doclist(doc.doctype, doc.name), 'get_item_details', '',
|
||||
function(r, rt) {
|
||||
if(!r.exc) {
|
||||
refresh_field(cur_frm.cscript.fname);
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
cur_frm.cscript.load_defaults(doc, dt, dn, callback);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
cur_frm.cscript.load_taxes(doc, dt, dn, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var set_dynamic_label_par = function(doc, cdt, cdn, base_curr) {
|
||||
//parent flds
|
||||
par_cols_base = {'net_total': 'Net Total', 'other_charges_total': 'Taxes and Charges Total',
|
||||
'grand_total': 'Grand Total', 'rounded_total': 'Rounded Total', 'in_words': 'In Words'}
|
||||
par_cols_export = {'grand_total_export': 'Grand Total', 'rounded_total_export': 'Rounded Total', 'in_words_export': 'In Words'};
|
||||
|
||||
for (d in par_cols_base) cur_frm.fields_dict[d].label_span.innerHTML = par_cols_base[d]+' (' + base_curr + ')';
|
||||
for (d in par_cols_export) cur_frm.fields_dict[d].label_span.innerHTML = par_cols_export[d]+' (' + doc.currency + ')';
|
||||
cur_frm.fields_dict['conversion_rate'].label_span.innerHTML = "Conversion Rate (" + doc.currency +' -> '+ base_curr + ')';
|
||||
cur_frm.fields_dict['plc_conversion_rate'].label_span.innerHTML = 'Price List Currency Conversion Rate (' + doc.price_list_currency +' -> '+ base_curr + ')';
|
||||
|
||||
if (doc.doctype == 'Sales Invoice') {
|
||||
si_cols = {'total_advance': 'Total Advance', 'outstanding_amount': 'Outstanding Amount', 'paid_amount': 'Paid Amount', 'write_off_amount': 'Write Off Amount'}
|
||||
for (d in si_cols) cur_frm.fields_dict[d].label_span.innerHTML = si_cols[d] + ' (' + base_curr + ')';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var set_dynamic_label_child = function(doc, cdt, cdn, base_curr) {
|
||||
// item table flds
|
||||
item_cols_base = {'basic_rate': 'Basic Rate', 'base_ref_rate': 'Price List Rate', 'amount': 'Amount'};
|
||||
item_cols_export = {'export_rate': 'Basic Rate', 'ref_rate': 'Price List Rate', 'export_amount': 'Amount'};
|
||||
|
||||
for (d in item_cols_base) $('[data-grid-fieldname="'+cur_frm.cscript.tname+'-'+d+'"]').html(item_cols_base[d]+' ('+base_curr+')');
|
||||
for (d in item_cols_export) $('[data-grid-fieldname="'+cur_frm.cscript.tname+'-'+d+'"]').html(item_cols_export[d]+' ('+doc.currency+')');
|
||||
|
||||
var hide = (doc.currency == sys_defaults['currency']) ? false : true;
|
||||
for (f in item_cols_base) {
|
||||
cur_frm.fields_dict[cur_frm.cscript.fname].grid.set_column_disp(f, hide);
|
||||
}
|
||||
|
||||
//tax table flds
|
||||
tax_cols = {'tax_amount': 'Amount', 'total': 'Total'};
|
||||
for (d in tax_cols) $('[data-grid-fieldname="Sales Taxes and Charges-'+d+'"]').html(tax_cols[d]+' ('+base_curr+')');
|
||||
|
||||
if (doc.doctype == 'Sales Invoice') {
|
||||
// advance table flds
|
||||
adv_cols = {'advance_amount': 'Advance Amount', 'allocated_amount': 'Allocated Amount'}
|
||||
for (d in adv_cols) $('[data-grid-fieldname="Sales Invoice Advance-'+d+'"]').html(adv_cols[d]+' ('+base_curr+')');
|
||||
}
|
||||
}
|
||||
|
||||
// Change label dynamically based on currency
|
||||
//------------------------------------------------------------------
|
||||
|
||||
cur_frm.cscript.dynamic_label = function(doc, cdt, cdn, base_curr, callback) {
|
||||
cur_frm.cscript.base_currency = base_curr;
|
||||
set_dynamic_label_par(doc, cdt, cdn, base_curr);
|
||||
set_dynamic_label_child(doc, cdt, cdn, base_curr);
|
||||
set_sales_bom_help(doc);
|
||||
|
||||
if (callback) callback(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
// Help for Sales BOM items
|
||||
var set_sales_bom_help = function(doc) {
|
||||
if(!cur_frm.fields_dict.packing_list) return;
|
||||
if (getchildren('Delivery Note Packing Item', doc.name, 'packing_details').length) {
|
||||
$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(true);
|
||||
|
||||
if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||
help_msg = "<div class='help-box'> \
|
||||
For 'Sales BOM' items, warehouse, serial no and batch no \
|
||||
will be considered from the 'Packing List' table. \
|
||||
If warehouse and batch no are same for all packing items for any 'Sales BOM' item, \
|
||||
those values can be entered in the main item table, values will be copied to 'Packing List' table. \
|
||||
</div>";
|
||||
wn.meta.get_docfield(doc.doctype, 'sales_bom_help', doc.name).options = help_msg;
|
||||
}
|
||||
} else {
|
||||
$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(false);
|
||||
if (inList(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||
wn.meta.get_docfield(doc.doctype, 'sales_bom_help', doc.name).options = '';
|
||||
}
|
||||
}
|
||||
refresh_field('sales_bom_help');
|
||||
}
|
||||
|
||||
|
||||
// hide / unhide price list currency based on availability of price list in customer's currency
|
||||
//---------------------------------------------------------------------------------------------------
|
||||
|
||||
cur_frm.cscript.hide_price_list_currency = function(doc, cdt, cdn, callback1) {
|
||||
if (doc.price_list_name && doc.currency) {
|
||||
wn.call({
|
||||
method: 'selling.doctype.sales_common.sales_common.get_price_list_currency',
|
||||
args: {'price_list':doc.price_list_name, 'company': doc.company},
|
||||
callback: function(r, rt) {
|
||||
pl_currency = r.message[0]?r.message[0]:[];
|
||||
unhide_field(['price_list_currency', 'plc_conversion_rate']);
|
||||
|
||||
if (pl_currency.length==1) {
|
||||
if (doc.price_list_currency != pl_currency[0]) set_multiple(cdt, cdn, {price_list_currency:pl_currency[0]});
|
||||
if (pl_currency[0] == doc.currency) {
|
||||
if(doc.plc_conversion_rate != doc.conversion_rate) set_multiple(cdt, cdn, {plc_conversion_rate:doc.conversion_rate});
|
||||
hide_field(['price_list_currency', 'plc_conversion_rate']);
|
||||
} else if (pl_currency[0] == r.message[1]) {
|
||||
if (doc.plc_conversion_rate != 1) set_multiple(cdt, cdn, {plc_conversion_rate:1})
|
||||
hide_field(['price_list_currency', 'plc_conversion_rate']);
|
||||
}
|
||||
}
|
||||
|
||||
if (r.message[1] == doc.currency) {
|
||||
if (doc.conversion_rate != 1) set_multiple(cdt, cdn, {conversion_rate:1});
|
||||
hide_field(['conversion_rate', 'grand_total_export', 'in_words_export', 'rounded_total_export']);
|
||||
} else unhide_field(['conversion_rate', 'grand_total_export', 'in_words_export', 'rounded_total_export']);
|
||||
|
||||
if (r.message[1] == doc.price_list_currency) {
|
||||
if (doc.plc_conversion_rate != 1) set_multiple(cdt, cdn, {plc_conversion_rate:1});
|
||||
hide_field('plc_conversion_rate');
|
||||
} else unhide_field('plc_conversion_rate');
|
||||
|
||||
cur_frm.cscript.dynamic_label(doc, cdt, cdn, r.message[1], callback1);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TRIGGERS FOR CALCULATIONS
|
||||
// =====================================================================================================
|
||||
|
||||
// ********************* CURRENCY ******************************
|
||||
cur_frm.cscript.currency = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.price_list_name(doc, cdt, cdn);
|
||||
}
|
||||
|
||||
cur_frm.cscript.price_list_currency = cur_frm.cscript.currency;
|
||||
cur_frm.cscript.conversion_rate = cur_frm.cscript.currency;
|
||||
cur_frm.cscript.plc_conversion_rate = cur_frm.cscript.currency;
|
||||
|
||||
cur_frm.cscript.company = function(doc, cdt, cdn) {
|
||||
wn.call({
|
||||
method: 'selling.doctype.sales_common.sales_common.get_comp_base_currency',
|
||||
args: {company:doc.company},
|
||||
callback: function(r, rt) {
|
||||
var doc = locals[cdt][cdn];
|
||||
set_multiple(doc.doctype, doc.name, {
|
||||
currency:r.message,
|
||||
price_list_currency:r.message
|
||||
});
|
||||
cur_frm.cscript.currency(doc, cdt, cdn);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ******************** PRICE LIST ******************************
|
||||
cur_frm.cscript.price_list_name = function(doc, cdt, cdn) {
|
||||
var callback = function() {
|
||||
var fname = cur_frm.cscript.fname;
|
||||
var cl = getchildren(cur_frm.cscript.tname, doc.name, cur_frm.cscript.fname);
|
||||
if(doc.price_list_name && doc.currency && doc.price_list_currency && doc.conversion_rate && doc.plc_conversion_rate) {
|
||||
$c_obj(make_doclist(doc.doctype, doc.name), 'get_adj_percent', '',
|
||||
function(r, rt) {
|
||||
refresh_field(fname);
|
||||
var doc = locals[cdt][cdn];
|
||||
cur_frm.cscript.recalc(doc,3); //this is to re-calculate BASIC RATE and AMOUNT on basis of changed REF RATE
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
cur_frm.cscript.hide_price_list_currency(doc, cdt, cdn, callback);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ******************** ITEM CODE ********************************
|
||||
cur_frm.fields_dict[cur_frm.cscript.fname].grid.get_field("item_code").get_query = function(doc, cdt, cdn) {
|
||||
if (inList(['Maintenance', 'Service'], doc.order_type))
|
||||
return 'SELECT tabItem.name,tabItem.item_name,tabItem.description \
|
||||
FROM tabItem WHERE tabItem.is_service_item="Yes" \
|
||||
AND tabItem.docstatus != 2 \
|
||||
AND (ifnull(`tabItem`.`end_of_life`,"") = "" \
|
||||
OR `tabItem`.`end_of_life` > NOW() \
|
||||
OR `tabItem`.`end_of_life`="0000-00-00") \
|
||||
AND tabItem.%(key)s LIKE "%s" LIMIT 50';
|
||||
else
|
||||
return 'SELECT tabItem.name,tabItem.item_name,tabItem.description FROM tabItem \
|
||||
WHERE tabItem.is_sales_item="Yes" AND tabItem.docstatus != 2 \
|
||||
AND (ifnull(`tabItem`.`end_of_life`,"") = "" \
|
||||
OR `tabItem`.`end_of_life` > NOW() \
|
||||
OR `tabItem`.`end_of_life`="0000-00-00") \
|
||||
AND tabItem.%(key)s LIKE "%s" LIMIT 50';
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.item_code = function(doc, cdt, cdn) {
|
||||
var fname = cur_frm.cscript.fname;
|
||||
var d = locals[cdt][cdn];
|
||||
if (d.item_code) {
|
||||
if (!doc.company) {
|
||||
msgprint("Please select company to proceed");
|
||||
d.item_code = '';
|
||||
refresh_field('item_code', d.name, fname);
|
||||
} else {
|
||||
var callback = function(r, rt){
|
||||
cur_frm.cscript.recalc(doc, 1);
|
||||
}
|
||||
var args = {
|
||||
'item_code':d.item_code,
|
||||
'income_account':d.income_account,
|
||||
'cost_center': d.cost_center,
|
||||
'warehouse': d.warehouse
|
||||
};
|
||||
get_server_fields('get_item_details',JSON.stringify(args),
|
||||
fname,doc,cdt,cdn,1,callback);
|
||||
}
|
||||
}
|
||||
if(cur_frm.cscript.custom_item_code){
|
||||
cur_frm.cscript.custom_item_code(doc, cdt, cdn);
|
||||
}
|
||||
}
|
||||
|
||||
//Barcode
|
||||
//
|
||||
cur_frm.cscript.barcode = function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
var callback = function(r, rt) {
|
||||
cur_frm.cscript.item_code(doc, cdt, cdn);
|
||||
}
|
||||
get_server_fields('get_barcode_details', d.barcode, cur_frm.cscript.fname, doc, cdt, cdn, 1, callback);
|
||||
}
|
||||
|
||||
|
||||
// *********************** QUANTITY ***************************
|
||||
cur_frm.cscript.qty = function(doc, cdt, cdn) { cur_frm.cscript.recalc(doc, 1); }
|
||||
|
||||
// ************************ DISCOUNT (%) ***********************
|
||||
cur_frm.cscript.adj_rate = function(doc, cdt, cdn) { cur_frm.cscript.recalc(doc, 1); }
|
||||
|
||||
// ************************ REF RATE ****************************
|
||||
cur_frm.cscript.ref_rate = function(doc, cdt, cdn){
|
||||
var d = locals[cdt][cdn];
|
||||
var consider_incl_rate = cur_frm.cscript.consider_incl_rate(doc, cur_frm.cscript.other_fname);
|
||||
if(!consider_incl_rate) {
|
||||
set_multiple(cur_frm.cscript.tname, d.name, {'export_rate': flt(d.ref_rate) * (100 - flt(d.adj_rate)) / 100}, cur_frm.cscript.fname);
|
||||
}
|
||||
cur_frm.cscript.recalc(doc, 1);
|
||||
}
|
||||
|
||||
// *********************** BASIC RATE **************************
|
||||
cur_frm.cscript.basic_rate = function(doc, cdt, cdn) {
|
||||
var fname = cur_frm.cscript.fname;
|
||||
var d = locals[cdt][cdn];
|
||||
if(!d.qty) {
|
||||
d.qty = 1;
|
||||
refresh_field('qty', d.name, fname);
|
||||
}
|
||||
var consider_incl_rate = cur_frm.cscript.consider_incl_rate(doc, cur_frm.cscript.other_fname);
|
||||
if(!consider_incl_rate) {
|
||||
cur_frm.cscript.recalc(doc, 2);
|
||||
} else {
|
||||
var basic_rate = cur_frm.cscript.back_calc_basic_rate(
|
||||
doc, cur_frm.cscript.tname, fname, d, cur_frm.cscript.other_fname
|
||||
);
|
||||
// TODO: remove roundNumber for basic_rate comparison
|
||||
if (d.basic_rate != roundNumber(basic_rate, 2)) {
|
||||
d.basic_rate = basic_rate;
|
||||
refresh_field('basic_rate', d.name, fname);
|
||||
msgprint("You cannot change Basic Rate* (Base Currency) when \
|
||||
considering rates inclusive of taxes.<br /> \
|
||||
Please either <br /> \
|
||||
* Specify Basic Rate (i.e. Rate which will be displayed in print) <br /> \
|
||||
-- or -- <br />\
|
||||
* Uncheck 'Is this Tax included in Basic Rate?' in the tax entries of Taxes section.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ************************ EXPORT RATE *************************
|
||||
cur_frm.cscript.export_rate = function(doc,cdt,cdn) {
|
||||
var cur_rec = locals[cdt][cdn];
|
||||
var fname = cur_frm.cscript.fname;
|
||||
var tname = cur_frm.cscript.tname;
|
||||
if(flt(cur_rec.ref_rate)>0 && flt(cur_rec.export_rate)>0) {
|
||||
var adj_rate = 100 * (1 - (flt(cur_rec.export_rate) / flt(cur_rec.ref_rate)));
|
||||
set_multiple(tname, cur_rec.name, { 'adj_rate': adj_rate }, fname);
|
||||
}
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
cur_frm.cscript.recalc(doc, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ************* GET OTHER CHARGES BASED ON COMPANY *************
|
||||
cur_frm.fields_dict.charge.get_query = function(doc) {
|
||||
return 'SELECT DISTINCT `tabSales Taxes and Charges Master`.name FROM \
|
||||
`tabSales Taxes and Charges Master` WHERE `tabSales Taxes and Charges Master`.company = "'
|
||||
+doc.company+'" AND `tabSales Taxes and Charges Master`.company is not NULL \
|
||||
AND `tabSales Taxes and Charges Master`.docstatus != 2 \
|
||||
AND `tabSales Taxes and Charges Master`.%(key)s LIKE "%s" \
|
||||
ORDER BY `tabSales Taxes and Charges Master`.name LIMIT 50';
|
||||
}
|
||||
|
||||
// ********************* Get Charges ****************************
|
||||
cur_frm.cscript.get_charges = function(doc, cdt, cdn) {
|
||||
$c_obj(make_doclist(doc.doctype,doc.name),
|
||||
'get_other_charges',
|
||||
'',
|
||||
function(r, rt) { cur_frm.cscript.calculate_charges(doc, cdt, cdn);}
|
||||
,null,null,cur_frm.fields_dict.get_charges.input);
|
||||
}
|
||||
|
||||
|
||||
// CALCULATION OF TOTAL AMOUNTS
|
||||
// ========================================================================================================
|
||||
cur_frm.cscript.recalc = function(doc, n) {
|
||||
if(!n)n=0;
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
var tname = cur_frm.cscript.tname;
|
||||
var fname = cur_frm.cscript.fname;
|
||||
var sales_team = cur_frm.cscript.sales_team_fname;
|
||||
var other_fname = cur_frm.cscript.other_fname;
|
||||
|
||||
if(!flt(doc.conversion_rate)) {
|
||||
doc.conversion_rate = 1;
|
||||
refresh_field('conversion_rate');
|
||||
}
|
||||
if(!flt(doc.plc_conversion_rate)) {
|
||||
doc.plc_conversion_rate = 1;
|
||||
refresh_field('plc_conversion_rate');
|
||||
}
|
||||
|
||||
if(n > 0) cur_frm.cscript.update_fname_table(doc , tname , fname , n, other_fname); // updates all values in table (i.e. amount, export amount, net total etc.)
|
||||
|
||||
if(flt(doc.net_total) > 0) {
|
||||
var cl = getchildren('Sales Taxes and Charges', doc.name, other_fname,doc.doctype);
|
||||
for(var i = 0; i<cl.length; i++){
|
||||
cl[i].total_tax_amount = 0;
|
||||
cl[i].total_amount = 0;
|
||||
cl[i].tax_amount = 0; // this is done to calculate other charges
|
||||
cl[i].total = 0;
|
||||
cl[i].item_wise_tax_detail = "";
|
||||
if(in_list(['On Previous Row Amount','On Previous Row Total'],cl[i].charge_type) && !cl[i].row_id){
|
||||
alert("Please Enter Row on which amount needs to be calculated for row : "+cl[i].idx);
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
cur_frm.cscript.calc_other_charges(doc , tname , fname , other_fname); // calculate other charges
|
||||
}
|
||||
cur_frm.cscript.calc_doc_values(doc, null, null, tname, fname, other_fname); // calculates total amounts
|
||||
|
||||
// ******************* calculate allocated amount of sales person ************************
|
||||
cl = getchildren('Sales Team', doc.name, sales_team);
|
||||
for(var i=0;i<cl.length;i++) {
|
||||
if (cl[i].allocated_percentage) {
|
||||
cl[i].allocated_amount = flt(flt(doc.net_total)*flt(cl[i].allocated_percentage)/100);
|
||||
refresh_field('allocated_amount', cl[i].name, sales_team);
|
||||
}
|
||||
}
|
||||
doc.in_words = '';
|
||||
doc.in_words_export = '';
|
||||
refresh_many(['total_discount_rate','total_discount','net_total','total_commission','grand_total','rounded_total','grand_total_export','rounded_total_export','in_words','in_words_export','other_charges','other_charges_total']);
|
||||
if(cur_frm.cscript.custom_recalc)cur_frm.cscript.custom_recalc(doc);
|
||||
}
|
||||
|
||||
// ******* Calculation of total amounts of document (item amount + other charges)****************
|
||||
cur_frm.cscript.calc_doc_values = function(doc, cdt, cdn, tname, fname, other_fname) {
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
var net_total = 0; var other_charges_total = 0;
|
||||
var net_total_incl = 0
|
||||
var cl = getchildren(tname, doc.name, fname);
|
||||
for(var i = 0; i<cl.length; i++){
|
||||
//net_total += flt(cl[i].basic_rate) * flt(cl[i].qty);
|
||||
net_total += flt(cl[i].amount);
|
||||
net_total_incl += flt(cl[i].export_amount);
|
||||
}
|
||||
|
||||
var inclusive_rate = 0
|
||||
var d = getchildren('Sales Taxes and Charges', doc.name, other_fname,doc.doctype);
|
||||
for(var j = 0; j<d.length; j++){
|
||||
other_charges_total += flt(d[j].tax_amount);
|
||||
if(d[j].included_in_print_rate) {
|
||||
inclusive_rate = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(flt(doc.conversion_rate)>1) {
|
||||
net_total_incl *= flt(doc.conversion_rate);
|
||||
}
|
||||
|
||||
doc.net_total = inclusive_rate ? flt(net_total_incl) : flt(net_total);
|
||||
doc.other_charges_total = roundNumber(flt(other_charges_total), 2);
|
||||
doc.grand_total = roundNumber((flt(net_total) + flt(other_charges_total)), 2);
|
||||
doc.rounded_total = Math.round(doc.grand_total);
|
||||
doc.grand_total_export = roundNumber((flt(doc.grand_total) / flt(doc.conversion_rate)), 2);
|
||||
doc.rounded_total_export = Math.round(doc.grand_total_export);
|
||||
doc.total_commission = flt(flt(net_total) * flt(doc.commission_rate) / 100);
|
||||
}
|
||||
|
||||
// ******************************* OTHER CHARGES *************************************
|
||||
cur_frm.cscript.calc_other_charges = function(doc , tname , fname , other_fname) {
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
|
||||
// Make Display Area
|
||||
cur_frm.fields_dict['other_charges_calculation'].disp_area.innerHTML =
|
||||
'<b style="padding: 8px 0px;">Calculation Details for Taxes and Charges:</b>';
|
||||
|
||||
var cl = getchildren(tname, doc.name, fname);
|
||||
var tax = getchildren('Sales Taxes and Charges', doc.name, other_fname,doc.doctype);
|
||||
|
||||
// Make display table
|
||||
var otc = make_table(cur_frm.fields_dict['other_charges_calculation'].disp_area,
|
||||
cl.length + 1, tax.length + 1, '90%', [], { border:'1px solid #AAA', padding:'2px' });
|
||||
$y(otc,{marginTop:'8px'});
|
||||
|
||||
var tax_desc = {}; var tax_desc_rates = []; var net_total = 0;
|
||||
|
||||
for(var i=0;i<cl.length;i++) {
|
||||
net_total += flt(flt(cl[i].qty) * flt(cl[i].basic_rate));
|
||||
var prev_total = flt(cl[i].amount);
|
||||
if(cl[i].item_tax_rate) {
|
||||
try {
|
||||
var check_tax = JSON.parse(cl[i].item_tax_rate); //to get in dictionary
|
||||
} catch(exception) {
|
||||
var check_tax = eval('var a='+cl[i].item_tax_rate+';a'); //to get in dictionary
|
||||
}
|
||||
}
|
||||
|
||||
// Add Item Code in new Row
|
||||
$td(otc,i+1,0).innerHTML = cl[i].item_code ? cl[i].item_code : cl[i].description;
|
||||
|
||||
//var tax = getchildren('Sales Taxes and Charges', doc.name, other_fname,doc.doctype);
|
||||
var total = net_total;
|
||||
|
||||
|
||||
for(var t=0;t<tax.length;t++){
|
||||
var account = tax[t].account_head;
|
||||
$td(otc,0,t+1).innerHTML = account?account:'';
|
||||
//Check For Rate
|
||||
if(cl[i].item_tax_rate && check_tax[account]!=null) {
|
||||
var rate = flt(check_tax[account]);
|
||||
} else {
|
||||
// if particular item doesn't have particular rate it will take other charges rate
|
||||
var rate = flt(tax[t].rate);
|
||||
}
|
||||
|
||||
//Check For Rate and get tax amount
|
||||
var tax_amount = cur_frm.cscript.check_charge_type_and_get_tax_amount(doc,tax,t, cl[i], rate);
|
||||
|
||||
//enter item_wise_tax_detail i.e. tax rate on each item
|
||||
var item_wise_tax_detail = cur_frm.cscript.get_item_wise_tax_detail(doc, rate, cl, i, tax, t);
|
||||
if(tax[t].charge_type != "Actual") tax[t].item_wise_tax_detail += item_wise_tax_detail;
|
||||
tax[t].total_amount = flt(tax_amount); //stores actual tax amount in virtual field
|
||||
tax[t].total_tax_amount = flt(prev_total); //stores total amount in virtual field
|
||||
tax[t].tax_amount += flt(tax_amount);
|
||||
var total_amount = flt(tax[t].tax_amount);
|
||||
total_tax_amount = flt(tax[t].total_tax_amount) + flt(total_amount);
|
||||
set_multiple('Sales Taxes and Charges', tax[t].name, { 'item_wise_tax_detail':tax[t].item_wise_tax_detail, 'amount':roundNumber(flt(total_amount), 2), 'total':roundNumber(flt(total)+flt(tax[t].tax_amount), 2)}, other_fname);
|
||||
prev_total += flt(tax[t].total_amount); // for previous row total
|
||||
total += flt(tax[t].tax_amount); // for adding total to previous amount
|
||||
|
||||
if(tax[t].charge_type == 'Actual')
|
||||
$td(otc,i+1,t+1).innerHTML = fmt_money(tax[t].total_amount);
|
||||
else
|
||||
$td(otc,i+1,t+1).innerHTML = '('+fmt_money(rate) + '%) ' +fmt_money(tax[t].total_amount);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for(var t=0;t<tax.length;t++){
|
||||
tax[t].tax_amount = roundNumber(tax[t].tax_amount, 2);
|
||||
}
|
||||
}
|
||||
cur_frm.cscript.check_charge_type_and_get_tax_amount = function( doc, tax, t, cl, rate, print_amt) {
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
if (! print_amt) print_amt = 0;
|
||||
var tax_amount = 0;
|
||||
if(tax[t].charge_type == 'Actual') {
|
||||
var value = flt(tax[t].rate) / flt(doc.net_total); // this give the ratio in which all items are divided
|
||||
return tax_amount = flt(value) * flt(cl.amount);
|
||||
}
|
||||
else if(tax[t].charge_type == 'On Net Total') {
|
||||
if (flt(print_amt) == 1) {
|
||||
doc.excise_rate = flt(rate);
|
||||
doc.total_excise_rate += flt(rate);
|
||||
refresh_field('excise_rate');
|
||||
refresh_field('total_excise_rate');
|
||||
return
|
||||
}
|
||||
return tax_amount = (flt(rate) * flt(cl.amount) / 100);
|
||||
}
|
||||
else if(tax[t].charge_type == 'On Previous Row Amount'){
|
||||
if(flt(print_amt) == 1) {
|
||||
doc.total_excise_rate += flt(flt(doc.excise_rate) * 0.01 * flt(rate));
|
||||
refresh_field('total_excise_rate');
|
||||
return
|
||||
}
|
||||
var row_no = (tax[t].row_id).toString();
|
||||
var row = (row_no).split("+"); // splits the values and stores in an array
|
||||
for(var r = 0;r<row.length;r++){
|
||||
var id = cint(row[r].replace(/^\s+|\s+$/g,""));
|
||||
tax_amount += (flt(rate) * flt(tax[id-1].total_amount) / 100);
|
||||
}
|
||||
var row_id = row_no.indexOf("/");
|
||||
if(row_id != -1) {
|
||||
rate = '';
|
||||
var row = (row_no).split("/"); // splits the values and stores in an array
|
||||
if(row.length>2) alert("You cannot enter more than 2 nos. for division");
|
||||
var id1 = cint(row[0].replace(/^\s+|\s+$/g,""));
|
||||
var id2 = cint(row[1].replace(/^\s+|\s+$/g,""));
|
||||
tax_amount = flt(tax[id1-1].total_amount) / flt(tax[id2-1].total_amount);
|
||||
}
|
||||
return tax_amount
|
||||
}
|
||||
else if(tax[t].charge_type == 'On Previous Row Total') {
|
||||
if(flt(print_amt) == 1) {
|
||||
doc.sales_tax_rate += flt(rate);
|
||||
refresh_field('sales_tax_rate');
|
||||
return
|
||||
}
|
||||
var row = cint(tax[t].row_id);
|
||||
return tax_amount = flt(rate) * (flt(tax[row-1].total_tax_amount)+flt(tax[row-1].total_amount)) / 100;
|
||||
}
|
||||
}
|
||||
|
||||
// ********************** Functions for inclusive value calc ******************************
|
||||
cur_frm.cscript.consider_incl_rate = function(doc, other_fname) {
|
||||
var tax_list = getchildren('Sales Taxes and Charges', doc.name, other_fname, doc.doctype);
|
||||
for(var i=0; i<tax_list.length; i++) {
|
||||
if(tax_list[i].included_in_print_rate) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
cur_frm.cscript.back_calc_basic_rate = function(doc, tname, fname, child, other_fname) {
|
||||
var get_item_tax_rate = function(item, tax) {
|
||||
if(item.item_tax_rate) {
|
||||
try {
|
||||
var item_tax = JSON.parse(item.item_tax_rate);
|
||||
} catch(exception) {
|
||||
var item_tax = eval('var a='+item.item_tax_rate+';a');
|
||||
}
|
||||
if(item_tax[tax.account_head]!=null) {
|
||||
return flt(item_tax[tax.account_head]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var tax_list = getchildren('Sales Taxes and Charges', doc.name, other_fname, doc.doctype);
|
||||
var total = 1;
|
||||
var temp_tax_list = [];
|
||||
var amt = 0;
|
||||
var item_tax_rate = 0;
|
||||
var rate = 0;
|
||||
for(var i=0; i<tax_list.length; i++) {
|
||||
amt = 0;
|
||||
item_tax_rate = get_item_tax_rate(child, tax_list[i]);
|
||||
rate = item_tax_rate ? item_tax_rate : flt(tax_list[i].rate);
|
||||
if(tax_list[i].included_in_print_rate) {
|
||||
if(tax_list[i].charge_type=='On Net Total') {
|
||||
amt = flt(rate / 100);
|
||||
} else if(tax_list[i].charge_type=='On Previous Row Total') {
|
||||
amt = flt((rate * temp_tax_list[tax_list[i].row_id-1]['total']) / 100);
|
||||
} else if(tax_list[i].charge_type=='On Previous Row Amount') {
|
||||
amt = flt((rate * temp_tax_list[tax_list[i].row_id-1]['amt']) / 100);
|
||||
}
|
||||
}
|
||||
total += flt(amt);
|
||||
temp_tax_list[i] = {
|
||||
amt: amt,
|
||||
total: total
|
||||
};
|
||||
}
|
||||
var basic_rate = (child.export_rate * flt(doc.conversion_rate)) / total;
|
||||
//console.log(temp_tax_list);
|
||||
//console.log('in basic rate back calc');
|
||||
//console.log(basic_rate);
|
||||
return basic_rate;
|
||||
}
|
||||
|
||||
cur_frm.cscript.included_in_print_rate = function(doc, cdt, cdn) {
|
||||
var tax = locals[cdt][cdn];
|
||||
if(tax.included_in_print_rate==1) {
|
||||
if(!inList(['On Net Total', 'On Previous Row Total', 'On Previous Row Amount'], tax.charge_type)) {
|
||||
msgprint("'Is this Tax included in Basic Rate?' (i.e. Inclusive Price) is only valid for charges of type: <br /> \
|
||||
* On Net Total <br /> \
|
||||
* On Previous Row Amount <br /> \
|
||||
* On Previous Row Total");
|
||||
tax.included_in_print_rate = 0;
|
||||
refresh_field('included_in_print_rate', tax.name, cur_frm.cscript.other_fname);
|
||||
}
|
||||
var tax_list = getchildren('Sales Taxes and Charges', doc.name, cur_frm.cscript.other_fname, doc.doctype);
|
||||
cur_frm.cscript.validate_print_rate_option(doc, tax_list, tax.idx-1);
|
||||
}
|
||||
}
|
||||
|
||||
// ********************** Update values in table ******************************
|
||||
cur_frm.cscript.update_fname_table = function(doc , tname , fname , n, other_fname) {
|
||||
doc = locals[doc.doctype][doc.name]
|
||||
var net_total = 0
|
||||
var cl = getchildren(tname, doc.name, fname);
|
||||
var consider_incl_rate = cur_frm.cscript.consider_incl_rate(doc, other_fname);
|
||||
for(var i=0;i<cl.length;i++) {
|
||||
if(n == 1){
|
||||
if(!consider_incl_rate) {
|
||||
if(flt(cl[i].ref_rate) > 0) {
|
||||
set_multiple(tname, cl[i].name, {
|
||||
'export_rate': flt(flt(cl[i].ref_rate) * (100 - flt(cl[i].adj_rate)) / 100)
|
||||
}, fname);
|
||||
}
|
||||
set_multiple(tname, cl[i].name, {
|
||||
'export_amount': flt(flt(cl[i].qty) * flt(cl[i].export_rate)),
|
||||
'basic_rate': flt(flt(cl[i].export_rate) * flt(doc.conversion_rate)),
|
||||
'amount': roundNumber(flt((flt(cl[i].export_rate) * flt(doc.conversion_rate)) * flt(cl[i].qty)), 2)
|
||||
}, fname);
|
||||
//var base_ref_rate = flt(cl[i].basic_rate) + flt(flt(cl[i].basic_rate) * flt(cl[i].adj_rate) / 100);
|
||||
//set_multiple(tname, cl[i].name, {
|
||||
// 'base_ref_rate': flt(base_ref_rate)
|
||||
//}, fname);
|
||||
|
||||
} else if(consider_incl_rate) {
|
||||
if(flt(cl[i].export_rate) > 0) {
|
||||
// calculate basic rate based on taxes
|
||||
// then calculate and set basic_rate, base_ref_rate, ref_rate, amount, export_amount
|
||||
var ref_rate = flt(cl[i].adj_rate)!=flt(100) ?
|
||||
flt((100 * flt(cl[i].export_rate))/flt(100 - flt(cl[i].adj_rate))) :
|
||||
flt(0)
|
||||
set_multiple(tname, cl[i].name, { 'ref_rate': ref_rate }, fname);
|
||||
} else if((flt(cl[i].ref_rate) > 0) && (flt(cl[i].adj_rate) > 0)) {
|
||||
var export_rate = flt(cl[i].ref_rate) * flt(1 - flt(cl[i].adj_rate / 100));
|
||||
set_multiple(tname, cl[i].name, { 'export_rate': flt(export_rate) }, fname);
|
||||
}
|
||||
//console.log("export_rate: " + cl[i].export_rate);
|
||||
|
||||
var basic_rate = cur_frm.cscript.back_calc_basic_rate(doc, tname, fname, cl[i], other_fname);
|
||||
var base_ref_rate = basic_rate + flt(basic_rate * flt(cl[i].adj_rate) / 100);
|
||||
set_multiple(tname, cl[i].name, {
|
||||
'basic_rate': flt(basic_rate),
|
||||
'amount': roundNumber(flt(basic_rate * flt(cl[i].qty)), 2),
|
||||
'export_amount': flt(flt(cl[i].qty) * flt(cl[i].export_rate)),
|
||||
'base_ref_rate': flt(base_ref_rate)
|
||||
}, fname);
|
||||
}
|
||||
}
|
||||
else if(n == 2){
|
||||
if(flt(cl[i].ref_rate) > 0)
|
||||
set_multiple(tname, cl[i].name, {'adj_rate': 100 - flt(flt(cl[i].basic_rate) * 100 / (flt(cl[i].ref_rate) * flt(doc.conversion_rate)))}, fname);
|
||||
set_multiple(tname, cl[i].name, {'amount': flt(flt(cl[i].qty) * flt(cl[i].basic_rate)), 'export_rate': flt(flt(cl[i].basic_rate) / flt(doc.conversion_rate)), 'export_amount': flt((flt(cl[i].basic_rate) / flt(doc.conversion_rate)) * flt(cl[i].qty)) }, fname);
|
||||
}
|
||||
/*else if(n == 3){
|
||||
set_multiple(tname, cl[i].name, {'basic_rate': flt(flt(cl[i].export_rate) * flt(doc.conversion_rate))}, fname);
|
||||
set_multiple(tname, cl[i].name, {'amount' : flt(flt(cl[i].basic_rate) * flt(cl[i].qty)), 'export_amount': flt(flt(cl[i].export_rate) * flt(cl[i].qty))}, fname);
|
||||
if(cl[i].ref_rate > 0)
|
||||
set_multiple(tname, cl[i].name, {'adj_rate': 100 - flt(flt(cl[i].export_rate) * 100 / flt(cl[i].ref_rate)), 'base_ref_rate': flt(flt(cl[i].ref_rate) * flt(doc.conversion_rate)) }, fname);
|
||||
}*/
|
||||
net_total += flt(flt(cl[i].qty) * flt(cl[i].basic_rate));
|
||||
}
|
||||
doc.net_total = net_total;
|
||||
refresh_field('net_total');
|
||||
}
|
||||
|
||||
cur_frm.cscript.get_item_wise_tax_detail = function( doc, rate, cl, i, tax, t) {
|
||||
doc = locals[doc.doctype][doc.name];
|
||||
var detail = '';
|
||||
detail = cl[i].item_code + " : " + cstr(rate) + NEWLINE;
|
||||
return detail;
|
||||
}
|
||||
|
||||
// **************** RE-CALCULATE VALUES ***************************
|
||||
|
||||
cur_frm.cscript.recalculate_values = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.calculate_charges(doc,cdt,cdn);
|
||||
}
|
||||
|
||||
cur_frm.cscript.validate_print_rate_option = function(doc, taxes, i) {
|
||||
if(in_list(['On Previous Row Amount','On Previous Row Total'], taxes[i].charge_type)) {
|
||||
if(!taxes[i].row_id){
|
||||
alert("Please Enter Row on which amount needs to be calculated for row : "+taxes[i].idx);
|
||||
validated = false;
|
||||
} else if(taxes[i].included_in_print_rate && taxes[taxes[i].row_id-1].charge_type=='Actual') {
|
||||
msgprint("Row of type 'Actual' cannot be depended on for type '" + taxes[i].charge_type + "'\
|
||||
when using tax inclusive prices.<br />\
|
||||
This will lead to incorrect values.<br /><br /> \
|
||||
<b>Please specify correct value in 'Enter Row' column of <span style='color:red'>Row: "
|
||||
+ taxes[i].idx + "</span> in Taxes table</b>");
|
||||
validated = false;
|
||||
taxes[i].included_in_print_rate = 0;
|
||||
refresh_field('included_in_print_rate', taxes[i].name, other_fname);
|
||||
} else if ((taxes[i].included_in_print_rate && !taxes[taxes[i].row_id-1].included_in_print_rate) ||
|
||||
(!taxes[i].included_in_print_rate && taxes[taxes[i].row_id-1].included_in_print_rate)) {
|
||||
msgprint("If any row in the tax table depends on 'Previous Row Amount/Total', <br />\
|
||||
'Is this Tax included in Basic Rate?' column should be same for both row <br />\
|
||||
i.e for that row and the previous row. <br /><br />\
|
||||
The same is violated for row #"+(i+1)+" and row #"+taxes[i].row_id
|
||||
);
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.calculate_charges = function(doc, cdt, cdn) {
|
||||
var other_fname = cur_frm.cscript.other_fname;
|
||||
|
||||
var cl = getchildren('Sales Taxes and Charges', doc.name, other_fname, doc.doctype);
|
||||
for(var i = 0; i<cl.length; i++){
|
||||
cl[i].total_tax_amount = 0;
|
||||
cl[i].total_amount = 0;
|
||||
cl[i].tax_amount = 0; // this is done to calculate other charges
|
||||
cl[i].total = 0;
|
||||
cur_frm.cscript.validate_print_rate_option(doc, cl, i);
|
||||
}
|
||||
cur_frm.cscript.recalc(doc, 1);
|
||||
}
|
||||
|
||||
// Get Sales Partner Commission
|
||||
// =================================================================================
|
||||
cur_frm.cscript.sales_partner = function(doc, cdt, cdn){
|
||||
if(doc.sales_partner){
|
||||
|
||||
get_server_fields('get_comm_rate', doc.sales_partner, '', doc, cdt, cdn, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// *******Commission Rate Trigger (calculates total commission amount)*********
|
||||
cur_frm.cscript.commission_rate = function(doc, cdt, cdn) {
|
||||
if(doc.commission_rate > 100){
|
||||
alert("Commision rate cannot be greater than 100.");
|
||||
doc.total_commission = 0;
|
||||
doc.commission_rate = 0;
|
||||
}
|
||||
else
|
||||
doc.total_commission = doc.net_total * doc.commission_rate / 100;
|
||||
refresh_many(['total_commission','commission_rate']);
|
||||
|
||||
}
|
||||
|
||||
// *******Total Commission Trigger (calculates commission rate)*********
|
||||
cur_frm.cscript.total_commission = function(doc, cdt, cdn) {
|
||||
if(doc.net_total){
|
||||
if(doc.net_total < doc.total_commission){
|
||||
alert("Total commission cannot be greater than net total.");
|
||||
doc.total_commission = 0;
|
||||
doc.commission_rate = 0;
|
||||
}
|
||||
else
|
||||
doc.commission_rate = doc.total_commission * 100 / doc.net_total;
|
||||
refresh_many(['total_commission','commission_rate']);
|
||||
}
|
||||
}
|
||||
// Sales Person Allocated % trigger
|
||||
// ==============================================================================
|
||||
cur_frm.cscript.allocated_percentage = function(doc, cdt, cdn) {
|
||||
var fname = cur_frm.cscript.sales_team_fname;
|
||||
var d = locals[cdt][cdn];
|
||||
if (d.allocated_percentage) {
|
||||
d.allocated_amount = flt(flt(doc.net_total)*flt(d.allocated_percentage)/100);
|
||||
refresh_field('allocated_amount', d.name, fname);
|
||||
}
|
||||
}
|
||||
|
||||
// Client Side Validation
|
||||
// =================================================================================
|
||||
cur_frm.cscript.validate = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.validate_items(doc);
|
||||
var cl = getchildren('Sales Taxes and Charges Master', doc.name, 'other_charges');
|
||||
for(var i =0;i<cl.length;i++) {
|
||||
if(!cl[i].amount) {
|
||||
alert("Please Enter Amount in Row no. "+cl[i].idx+" in Taxes and Charges table");
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
cur_frm.cscript.calculate_charges (doc, cdt, cdn);
|
||||
|
||||
if (cur_frm.cscript.calc_adjustment_amount) cur_frm.cscript.calc_adjustment_amount(doc);
|
||||
}
|
||||
|
||||
|
||||
// ************** Atleast one item in document ****************
|
||||
cur_frm.cscript.validate_items = function(doc) {
|
||||
var cl = getchildren(cur_frm.cscript.tname, doc.name, cur_frm.cscript.fname);
|
||||
if(!cl.length){
|
||||
alert("Please enter Items for " + doc.doctype);
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
904
selling/doctype/sales_common/sales_common.py
Normal file
904
selling/doctype/sales_common/sales_common.py
Normal file
@@ -0,0 +1,904 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
from utilities.transaction_base import TransactionBase
|
||||
|
||||
|
||||
@webnotes.whitelist()
|
||||
def get_comp_base_currency(arg=None):
|
||||
""" get default currency of company"""
|
||||
res = webnotes.conn.sql("""select default_currency from `tabCompany`
|
||||
where name = %s""", webnotes.form_dict.get('company'))
|
||||
return res and res[0][0] or None
|
||||
|
||||
@webnotes.whitelist()
|
||||
def get_price_list_currency(arg=None):
|
||||
""" Get all currency in which price list is maintained"""
|
||||
plc = webnotes.conn.sql("select distinct ref_currency from `tabItem Price` where price_list_name = %s", webnotes.form_dict['price_list'])
|
||||
plc = [d[0] for d in plc]
|
||||
base_currency = get_comp_base_currency(webnotes.form_dict['company'])
|
||||
return plc, base_currency
|
||||
|
||||
|
||||
class DocType(TransactionBase):
|
||||
def __init__(self,d,dl):
|
||||
self.doc, self.doclist = d,dl
|
||||
|
||||
self.doctype_dict = {
|
||||
'Sales Order' : 'Sales Order Item',
|
||||
'Delivery Note' : 'Delivery Note Item',
|
||||
'Sales Invoice':'Sales Invoice Item',
|
||||
'Installation Note' : 'Installation Note Item'
|
||||
}
|
||||
|
||||
self.ref_doctype_dict= {}
|
||||
|
||||
self.next_dt_detail = {
|
||||
'delivered_qty' : 'Delivery Note Item',
|
||||
'billed_qty' : 'Sales Invoice Item',
|
||||
'installed_qty' : 'Installation Note Item'}
|
||||
|
||||
self.msg = []
|
||||
|
||||
|
||||
# Get Sales Person Details
|
||||
# ==========================
|
||||
|
||||
# TODO: To be deprecated if not in use
|
||||
def get_sales_person_details(self, obj):
|
||||
if obj.doc.doctype != 'Quotation':
|
||||
obj.doclist = obj.doc.clear_table(obj.doclist,'sales_team')
|
||||
idx = 0
|
||||
for d in webnotes.conn.sql("select sales_person, allocated_percentage, allocated_amount, incentives from `tabSales Team` where parent = '%s'" % obj.doc.customer):
|
||||
ch = addchild(obj.doc, 'sales_team', 'Sales Team', 1, obj.doclist)
|
||||
ch.sales_person = d and cstr(d[0]) or ''
|
||||
ch.allocated_percentage = d and flt(d[1]) or 0
|
||||
ch.allocated_amount = d and flt(d[2]) or 0
|
||||
ch.incentives = d and flt(d[3]) or 0
|
||||
ch.idx = idx
|
||||
idx += 1
|
||||
return obj.doclist
|
||||
|
||||
|
||||
# Get customer's contact person details
|
||||
# ==============================================================
|
||||
def get_contact_details(self, obj = '', primary = 0):
|
||||
cond = " and contact_name = '"+cstr(obj.doc.contact_person)+"'"
|
||||
if primary: cond = " and is_primary_contact = 'Yes'"
|
||||
contact = webnotes.conn.sql("select contact_name, contact_no, email_id, contact_address from `tabContact` where customer = '%s' and docstatus != 2 %s" %(obj.doc.customer, cond), as_dict = 1)
|
||||
if not contact:
|
||||
return
|
||||
c = contact[0]
|
||||
obj.doc.contact_person = c['contact_name'] or ''
|
||||
obj.doc.contact_no = c['contact_no'] or ''
|
||||
obj.doc.email_id = c['email_id'] or ''
|
||||
obj.doc.customer_mobile_no = c['contact_no'] or ''
|
||||
if c['contact_address']:
|
||||
obj.doc.customer_address = c['contact_address']
|
||||
|
||||
|
||||
# Get customer's primary shipping details
|
||||
# ==============================================================
|
||||
def get_shipping_details(self, obj = ''):
|
||||
det = webnotes.conn.sql("select name, ship_to, shipping_address from `tabShipping Address` where customer = '%s' and docstatus != 2 and ifnull(is_primary_address, 'Yes') = 'Yes'" %(obj.doc.customer), as_dict = 1)
|
||||
obj.doc.ship_det_no = det and det[0]['name'] or ''
|
||||
obj.doc.ship_to = det and det[0]['ship_to'] or ''
|
||||
obj.doc.shipping_address = det and det[0]['shipping_address'] or ''
|
||||
|
||||
|
||||
# get invoice details
|
||||
# ====================
|
||||
def get_invoice_details(self, obj = ''):
|
||||
if obj.doc.company:
|
||||
acc_head = webnotes.conn.sql("select name from `tabAccount` where name = '%s' and docstatus != 2" % (cstr(obj.doc.customer) + " - " + get_value('Company', obj.doc.company, 'abbr')))
|
||||
obj.doc.debit_to = acc_head and acc_head[0][0] or ''
|
||||
|
||||
|
||||
|
||||
# Get Item Details
|
||||
# ===============================================================
|
||||
def get_item_details(self, args, obj):
|
||||
import json
|
||||
if not obj.doc.price_list_name:
|
||||
msgprint("Please Select Price List before selecting Items")
|
||||
raise Exception
|
||||
item = webnotes.conn.sql("select description, item_name, brand, item_group, stock_uom, default_warehouse, default_income_account, default_sales_cost_center, description_html, barcode from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or end_of_life > now() or end_of_life = '0000-00-00') and (is_sales_item = 'Yes' or is_service_item = 'Yes')" % (args['item_code']), as_dict=1)
|
||||
tax = webnotes.conn.sql("select tax_type, tax_rate from `tabItem Tax` where parent = %s" , args['item_code'])
|
||||
t = {}
|
||||
for x in tax: t[x[0]] = flt(x[1])
|
||||
ret = {
|
||||
'description' : item and item[0]['description_html'] or item[0]['description'],
|
||||
'barcode' : item and item[0]['barcode'] or '',
|
||||
'item_group' : item and item[0]['item_group'] or '',
|
||||
'item_name' : item and item[0]['item_name'] or '',
|
||||
'brand' : item and item[0]['brand'] or '',
|
||||
'stock_uom' : item and item[0]['stock_uom'] or '',
|
||||
'reserved_warehouse' : item and item[0]['default_warehouse'] or '',
|
||||
'warehouse' : item and item[0]['default_warehouse'] or args.get('warehouse'),
|
||||
'income_account' : item and item[0]['default_income_account'] or args.get('income_account'),
|
||||
'cost_center' : item and item[0]['default_sales_cost_center'] or args.get('cost_center'),
|
||||
'qty' : 1.00, # this is done coz if item once fetched is fetched again thn its qty shld be reset to 1
|
||||
'adj_rate' : 0,
|
||||
'amount' : 0,
|
||||
'export_amount' : 0,
|
||||
'item_tax_rate' : json.dumps(t),
|
||||
'batch_no' : ''
|
||||
}
|
||||
if(obj.doc.price_list_name and item): #this is done to fetch the changed BASIC RATE and REF RATE based on PRICE LIST
|
||||
base_ref_rate = self.get_ref_rate(args['item_code'], obj.doc.price_list_name, obj.doc.price_list_currency, obj.doc.plc_conversion_rate)
|
||||
ret['ref_rate'] = flt(base_ref_rate)/flt(obj.doc.conversion_rate)
|
||||
ret['export_rate'] = flt(base_ref_rate)/flt(obj.doc.conversion_rate)
|
||||
ret['base_ref_rate'] = flt(base_ref_rate)
|
||||
ret['basic_rate'] = flt(base_ref_rate)
|
||||
|
||||
if ret['warehouse'] or ret['reserved_warehouse']:
|
||||
av_qty = self.get_available_qty({'item_code': args['item_code'], 'warehouse': ret['warehouse'] or ret['reserved_warehouse']})
|
||||
ret.update(av_qty)
|
||||
|
||||
# get customer code for given item from Item Customer Detail
|
||||
customer_item_code_row = webnotes.conn.sql("""\
|
||||
select ref_code from `tabItem Customer Detail`
|
||||
where parent = %s and customer_name = %s""",
|
||||
(args['item_code'], obj.doc.customer))
|
||||
if customer_item_code_row and customer_item_code_row[0][0]:
|
||||
ret['customer_item_code'] = customer_item_code_row[0][0]
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def get_item_defaults(self, args):
|
||||
item = webnotes.conn.sql("""select default_warehouse, default_income_account, default_sales_cost_center from `tabItem`
|
||||
where name = '%s' and (ifnull(end_of_life,'') = '' or end_of_life > now() or end_of_life = '0000-00-00')
|
||||
and (is_sales_item = 'Yes' or is_service_item = 'Yes') """ % (args['item_code']), as_dict=1)
|
||||
ret = {
|
||||
'reserved_warehouse' : item and item[0]['default_warehouse'] or '',
|
||||
'warehouse' : item and item[0]['default_warehouse'] or args.get('warehouse'),
|
||||
'income_account' : item and item[0]['default_income_account'] or args.get('income_account'),
|
||||
'cost_center' : item and item[0]['default_sales_cost_center'] or args.get('cost_center')
|
||||
}
|
||||
|
||||
return ret
|
||||
|
||||
def get_available_qty(self,args):
|
||||
tot_avail_qty = webnotes.conn.sql("select projected_qty, actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1)
|
||||
ret = {
|
||||
'projected_qty' : tot_avail_qty and flt(tot_avail_qty[0]['projected_qty']) or 0,
|
||||
'actual_qty' : tot_avail_qty and flt(tot_avail_qty[0]['actual_qty']) or 0
|
||||
}
|
||||
return ret
|
||||
|
||||
|
||||
# ***************** Get Ref rate as entered in Item Master ********************
|
||||
def get_ref_rate(self, item_code, price_list_name, price_list_currency, plc_conv_rate):
|
||||
ref_rate = webnotes.conn.sql("select ref_rate from `tabItem Price` where parent = %s and price_list_name = %s and ref_currency = %s", (item_code, price_list_name, price_list_currency))
|
||||
base_ref_rate = ref_rate and flt(ref_rate[0][0]) * flt(plc_conv_rate) or 0
|
||||
return base_ref_rate
|
||||
|
||||
def get_barcode_details(self, barcode):
|
||||
item = webnotes.conn.sql("select name, end_of_life, is_sales_item, is_service_item \
|
||||
from `tabItem` where barcode = %s", barcode, as_dict=1)
|
||||
ret = {}
|
||||
if not item:
|
||||
msgprint("""No item found for this barcode: %s.
|
||||
May be barcode not updated in item master. Please check""" % barcode)
|
||||
elif item[0]['end_of_life'] and getdate(cstr(item[0]['end_of_life'])) < nowdate():
|
||||
msgprint("Item: %s has been expired. Please check 'End of Life' field in item master" % item[0]['name'])
|
||||
elif item[0]['is_sales_item'] == 'No' and item[0]['is_service_item'] == 'No':
|
||||
msgprint("Item: %s is not a sales or service item" % item[0]['name'])
|
||||
elif len(item) > 1:
|
||||
msgprint("There are multiple item for this barcode. \nPlease select item code manually")
|
||||
else:
|
||||
ret = {'item_code': item and item[0]['name'] or ''}
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
# ****** Re-cancellculates Basic Rate & amount based on Price List Selected ******
|
||||
def get_adj_percent(self, obj):
|
||||
for d in getlist(obj.doclist, obj.fname):
|
||||
base_ref_rate = self.get_ref_rate(d.item_code, obj.doc.price_list_name, obj.doc.price_list_currency, obj.doc.plc_conversion_rate)
|
||||
d.adj_rate = 0
|
||||
d.ref_rate = flt(base_ref_rate)/flt(obj.doc.conversion_rate)
|
||||
d.basic_rate = flt(base_ref_rate)
|
||||
d.base_ref_rate = flt(base_ref_rate)
|
||||
d.export_rate = flt(base_ref_rate)/flt(obj.doc.conversion_rate)
|
||||
d.amount = flt(d.qty)*flt(base_ref_rate)
|
||||
d.export_amount = flt(d.qty)*flt(base_ref_rate)/flt(obj.doc.conversion_rate)
|
||||
|
||||
|
||||
# Load Default Taxes
|
||||
# ====================
|
||||
def load_default_taxes(self, obj):
|
||||
if cstr(obj.doc.charge):
|
||||
return self.get_other_charges(obj)
|
||||
else:
|
||||
return self.get_other_charges(obj, 1)
|
||||
|
||||
|
||||
# Get other charges from Master
|
||||
# =================================================================================
|
||||
def get_other_charges(self,obj, default=0):
|
||||
obj.doclist = obj.doc.clear_table(obj.doclist, 'other_charges')
|
||||
if not getlist(obj.doclist, 'other_charges'):
|
||||
if default: add_cond = 'ifnull(t2.is_default,0) = 1'
|
||||
else: add_cond = 't1.parent = "'+cstr(obj.doc.charge)+'"'
|
||||
idx = 0
|
||||
other_charge = webnotes.conn.sql("""\
|
||||
select t1.*
|
||||
from
|
||||
`tabSales Taxes and Charges` t1,
|
||||
`tabSales Taxes and Charges Master` t2
|
||||
where
|
||||
t1.parent = t2.name and
|
||||
t2.company = '%s' and
|
||||
%s
|
||||
order by t1.idx""" % (obj.doc.company, add_cond), as_dict=1)
|
||||
from webnotes.model import default_fields
|
||||
for other in other_charge:
|
||||
# remove default fields like parent, parenttype etc.
|
||||
# from query results
|
||||
for field in default_fields:
|
||||
if field in other: del other[field]
|
||||
|
||||
d = addchild(obj.doc, 'other_charges', 'Sales Taxes and Charges', 1,
|
||||
obj.doclist)
|
||||
d.fields.update(other)
|
||||
d.rate = flt(d.rate)
|
||||
d.tax_amount = flt(d.tax_rate)
|
||||
d.included_in_print_rate = cint(d.included_in_print_rate)
|
||||
d.idx = idx
|
||||
idx += 1
|
||||
return obj.doclist
|
||||
|
||||
# Get TERMS AND CONDITIONS
|
||||
# =======================================================================================
|
||||
def get_tc_details(self,obj):
|
||||
r = webnotes.conn.sql("select terms from `tabTerms and Conditions` where name = %s", obj.doc.tc_name)
|
||||
if r: obj.doc.terms = r[0][0]
|
||||
|
||||
#---------------------------------------- Get Tax Details -------------------------------#
|
||||
def get_tax_details(self, item_code, obj):
|
||||
import json
|
||||
tax = webnotes.conn.sql("select tax_type, tax_rate from `tabItem Tax` where parent = %s" , item_code)
|
||||
t = {}
|
||||
for x in tax: t[x[0]] = flt(x[1])
|
||||
ret = {
|
||||
'item_tax_rate' : tax and json.dumps(t) or ''
|
||||
}
|
||||
return ret
|
||||
|
||||
# Get Serial No Details
|
||||
# ==========================================================================
|
||||
def get_serial_details(self, serial_no, obj):
|
||||
import json
|
||||
item = webnotes.conn.sql("select item_code, make, label,brand, description from `tabSerial No` where name = '%s' and docstatus != 2" %(serial_no), as_dict=1)
|
||||
tax = webnotes.conn.sql("select tax_type, tax_rate from `tabItem Tax` where parent = %s" , item[0]['item_code'])
|
||||
t = {}
|
||||
for x in tax: t[x[0]] = flt(x[1])
|
||||
ret = {
|
||||
'item_code' : item and item[0]['item_code'] or '',
|
||||
'make' : item and item[0]['make'] or '',
|
||||
'label' : item and item[0]['label'] or '',
|
||||
'brand' : item and item[0]['brand'] or '',
|
||||
'description' : item and item[0]['description'] or '',
|
||||
'item_tax_rate' : json.dumps(t)
|
||||
}
|
||||
return ret
|
||||
|
||||
# Get Commission rate
|
||||
# =======================================================================
|
||||
def get_comm_rate(self, sales_partner, obj):
|
||||
|
||||
comm_rate = webnotes.conn.sql("select commission_rate from `tabSales Partner` where name = '%s' and docstatus != 2" %(sales_partner), as_dict=1)
|
||||
if comm_rate:
|
||||
total_comm = flt(comm_rate[0]['commission_rate']) * flt(obj.doc.net_total) / 100
|
||||
ret = {
|
||||
'commission_rate' : comm_rate and flt(comm_rate[0]['commission_rate']) or 0,
|
||||
'total_commission' : flt(total_comm)
|
||||
}
|
||||
return ret
|
||||
else:
|
||||
msgprint("Business Associate : %s does not exist in the system." % (sales_partner))
|
||||
raise Exception
|
||||
|
||||
|
||||
# To verify whether rate entered in details table does not exceed max discount %
|
||||
# =======================================================================================
|
||||
def validate_max_discount(self,obj, detail_table):
|
||||
for d in getlist(obj.doclist, detail_table):
|
||||
discount = webnotes.conn.sql("select max_discount from tabItem where name = '%s'" %(d.item_code),as_dict = 1)
|
||||
if discount and discount[0]['max_discount'] and (flt(d.adj_rate)>flt(discount[0]['max_discount'])):
|
||||
msgprint("You cannot give more than " + cstr(discount[0]['max_discount']) + " % discount on Item Code : "+cstr(d.item_code))
|
||||
raise Exception
|
||||
|
||||
|
||||
# Get sum of allocated % of sales person (it should be 100%)
|
||||
# ========================================================================
|
||||
# it indicates % contribution of sales person in sales
|
||||
def get_allocated_sum(self,obj):
|
||||
sum = 0
|
||||
for d in getlist(obj.doclist,'sales_team'):
|
||||
sum += flt(d.allocated_percentage)
|
||||
if (flt(sum) != 100) and getlist(obj.doclist,'sales_team'):
|
||||
msgprint("Total Allocated % of Sales Persons should be 100%")
|
||||
raise Exception
|
||||
|
||||
# Check Conversion Rate (i.e. it will not allow conversion rate to be 1 for Currency other than default currency set in Global Defaults)
|
||||
# ===========================================================================
|
||||
def check_conversion_rate(self, obj):
|
||||
default_currency = TransactionBase().get_company_currency(obj.doc.company)
|
||||
if not default_currency:
|
||||
msgprint('Message: Please enter default currency in Company Master')
|
||||
raise Exception
|
||||
if (obj.doc.currency == default_currency and flt(obj.doc.conversion_rate) != 1.00) or not obj.doc.conversion_rate or (obj.doc.currency != default_currency and flt(obj.doc.conversion_rate) == 1.00):
|
||||
msgprint("Please Enter Appropriate Conversion Rate for Customer's Currency to Base Currency (%s --> %s)" % (obj.doc.currency, default_currency), raise_exception = 1)
|
||||
|
||||
if (obj.doc.price_list_currency == default_currency and flt(obj.doc.plc_conversion_rate) != 1.00) or not obj.doc.plc_conversion_rate or (obj.doc.price_list_currency != default_currency and flt(obj.doc.plc_conversion_rate) == 1.00):
|
||||
msgprint("Please Enter Appropriate Conversion Rate for Price List Currency to Base Currency ( (%s --> %s)" % (obj.doc.price_list_currency, default_currency), raise_exception = 1)
|
||||
|
||||
|
||||
|
||||
# Get Tax rate if account type is TAX
|
||||
# =========================================================================
|
||||
def get_rate(self, arg):
|
||||
arg = eval(arg)
|
||||
rate = webnotes.conn.sql("select account_type, tax_rate from `tabAccount` where name = '%s' and docstatus != 2" %(arg['account_head']), as_dict=1)
|
||||
ret = {'rate' : 0}
|
||||
if arg['charge_type'] == 'Actual' and rate[0]['account_type'] == 'Tax':
|
||||
msgprint("You cannot select ACCOUNT HEAD of type TAX as your CHARGE TYPE is 'ACTUAL'")
|
||||
ret = {
|
||||
'account_head' : ''
|
||||
}
|
||||
elif rate[0]['account_type'] in ['Tax', 'Chargeable'] and not arg['charge_type'] == 'Actual':
|
||||
ret = {
|
||||
'rate' : rate and flt(rate[0]['tax_rate']) or 0
|
||||
}
|
||||
return ret
|
||||
|
||||
|
||||
def get_item_list(self, obj, is_stopped=0):
|
||||
"""get item list"""
|
||||
il = []
|
||||
for d in getlist(obj.doclist,obj.fname):
|
||||
reserved_wh, reserved_qty = '', 0 # used for delivery note
|
||||
qty = flt(d.qty)
|
||||
if is_stopped:
|
||||
qty = flt(d.qty) > flt(d.delivered_qty) and flt(flt(d.qty) - flt(d.delivered_qty)) or 0
|
||||
|
||||
if d.prevdoc_doctype == 'Sales Order':
|
||||
# used in delivery note to reduce reserved_qty
|
||||
# Eg.: if SO qty is 10 and there is tolerance of 20%, then it will allow DN of 12.
|
||||
# But in this case reserved qty should only be reduced by 10 and not 12.
|
||||
|
||||
tot_qty, max_qty, tot_amt, max_amt, reserved_wh = self.get_curr_and_ref_doc_details(d.doctype, 'prevdoc_detail_docname', d.prevdoc_detail_docname, obj.doc.name, obj.doc.doctype)
|
||||
if((flt(tot_qty) + flt(qty) > flt(max_qty))):
|
||||
reserved_qty = -(flt(max_qty)-flt(tot_qty))
|
||||
else:
|
||||
reserved_qty = - flt(qty)
|
||||
|
||||
if obj.doc.doctype == 'Sales Order':
|
||||
reserved_wh = d.reserved_warehouse
|
||||
|
||||
if self.has_sales_bom(d.item_code):
|
||||
for p in getlist(obj.doclist, 'packing_details'):
|
||||
if p.parent_detail_docname == d.name and p.parent_item == d.item_code:
|
||||
# the packing details table's qty is already multiplied with parent's qty
|
||||
il.append({
|
||||
'warehouse': p.warehouse,
|
||||
'reserved_warehouse': reserved_wh,
|
||||
'item_code': p.item_code,
|
||||
'qty': flt(p.qty),
|
||||
'reserved_qty': (flt(p.qty)/qty)*(reserved_qty),
|
||||
'uom': p.uom,
|
||||
'batch_no': p.batch_no,
|
||||
'serial_no': p.serial_no,
|
||||
'name': d.name
|
||||
})
|
||||
else:
|
||||
il.append({
|
||||
'warehouse': d.warehouse,
|
||||
'reserved_warehouse': reserved_wh,
|
||||
'item_code': d.item_code,
|
||||
'qty': qty,
|
||||
'reserved_qty': reserved_qty,
|
||||
'uom': d.stock_uom,
|
||||
'batch_no': d.batch_no,
|
||||
'serial_no': d.serial_no,
|
||||
'name': d.name
|
||||
})
|
||||
return il
|
||||
|
||||
|
||||
def get_curr_and_ref_doc_details(self, curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name, curr_parent_doctype):
|
||||
""" Get qty, amount already billed or delivered against curr line item for current doctype
|
||||
For Eg: SO-RV get total qty, amount from SO and also total qty, amount against that SO in RV
|
||||
"""
|
||||
#Get total qty, amt of current doctype (eg RV) except for qty, amt of this transaction
|
||||
if curr_parent_doctype == 'Installation Note':
|
||||
curr_det = webnotes.conn.sql("select sum(qty) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% (curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name))
|
||||
qty, amt = curr_det and flt(curr_det[0][0]) or 0, 0
|
||||
else:
|
||||
curr_det = webnotes.conn.sql("select sum(qty), sum(amount) from `tab%s` where %s = '%s' and docstatus = 1 and parent != '%s'"% (curr_doctype, ref_tab_fname, ref_tab_dn, curr_parent_name))
|
||||
qty, amt = curr_det and flt(curr_det[0][0]) or 0, curr_det and flt(curr_det[0][1]) or 0
|
||||
|
||||
# get total qty of ref doctype
|
||||
so_det = webnotes.conn.sql("select qty, amount, reserved_warehouse from `tabSales Order Item` where name = '%s' and docstatus = 1"% ref_tab_dn)
|
||||
max_qty, max_amt, res_wh = so_det and flt(so_det[0][0]) or 0, so_det and flt(so_det[0][1]) or 0, so_det and cstr(so_det[0][2]) or ''
|
||||
return qty, max_qty, amt, max_amt, res_wh
|
||||
|
||||
|
||||
# Make Packing List from Sales BOM
|
||||
# =======================================================================
|
||||
def has_sales_bom(self, item_code):
|
||||
return webnotes.conn.sql("select name from `tabSales BOM` where new_item_code=%s and docstatus != 2", item_code)
|
||||
|
||||
def get_sales_bom_items(self, item_code):
|
||||
return webnotes.conn.sql("""select t1.item_code, t1.qty, t1.uom
|
||||
from `tabSales BOM Item` t1, `tabSales BOM` t2
|
||||
where t2.new_item_code=%s and t1.parent = t2.name""", item_code, as_dict=1)
|
||||
|
||||
def get_packing_item_details(self, item):
|
||||
return webnotes.conn.sql("select item_name, description, stock_uom from `tabItem` where name = %s", item, as_dict = 1)[0]
|
||||
|
||||
def get_bin_qty(self, item, warehouse):
|
||||
det = webnotes.conn.sql("select actual_qty, projected_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (item, warehouse), as_dict = 1)
|
||||
return det and det[0] or ''
|
||||
|
||||
def update_packing_list_item(self,obj, packing_item_code, qty, warehouse, line):
|
||||
bin = self.get_bin_qty(packing_item_code, warehouse)
|
||||
item = self.get_packing_item_details(packing_item_code)
|
||||
|
||||
# check if exists
|
||||
exists = 0
|
||||
for d in getlist(obj.doclist, 'packing_details'):
|
||||
if d.parent_item == line.item_code and d.item_code == packing_item_code and d.parent_detail_docname == line.name:
|
||||
pi, exists = d, 1
|
||||
break
|
||||
|
||||
if not exists:
|
||||
pi = addchild(obj.doc, 'packing_details', 'Delivery Note Packing Item', 1, obj.doclist)
|
||||
|
||||
pi.parent_item = line.item_code
|
||||
pi.item_code = packing_item_code
|
||||
pi.item_name = item['item_name']
|
||||
pi.parent_detail_docname = line.name
|
||||
pi.description = item['description']
|
||||
pi.uom = item['stock_uom']
|
||||
pi.qty = flt(qty)
|
||||
pi.actual_qty = bin and flt(bin['actual_qty']) or 0
|
||||
pi.projected_qty = bin and flt(bin['projected_qty']) or 0
|
||||
pi.prevdoc_doctype = line.prevdoc_doctype
|
||||
if not pi.warehouse:
|
||||
pi.warehouse = warehouse
|
||||
if not pi.batch_no:
|
||||
pi.batch_no = cstr(line.batch_no)
|
||||
pi.idx = self.packing_list_idx
|
||||
|
||||
# saved, since this function is called on_update of delivery note
|
||||
pi.save()
|
||||
|
||||
self.packing_list_idx += 1
|
||||
|
||||
|
||||
def make_packing_list(self, obj, fname):
|
||||
"""make packing list for sales bom item"""
|
||||
self.packing_list_idx = 0
|
||||
parent_items = []
|
||||
for d in getlist(obj.doclist, fname):
|
||||
warehouse = fname == "sales_order_details" and d.reserved_warehouse or d.warehouse
|
||||
if self.has_sales_bom(d.item_code):
|
||||
for i in self.get_sales_bom_items(d.item_code):
|
||||
self.update_packing_list_item(obj, i['item_code'], flt(i['qty'])*flt(d.qty), warehouse, d)
|
||||
|
||||
if [d.item_code, d.name] not in parent_items:
|
||||
parent_items.append([d.item_code, d.name])
|
||||
|
||||
obj.doclist = self.cleanup_packing_list(obj, parent_items)
|
||||
|
||||
return obj.doclist
|
||||
|
||||
def cleanup_packing_list(self, obj, parent_items):
|
||||
"""Remove all those child items which are no longer present in main item table"""
|
||||
delete_list = []
|
||||
for d in getlist(obj.doclist, 'packing_details'):
|
||||
if [d.parent_item, d.parent_detail_docname] not in parent_items:
|
||||
# mark for deletion from doclist
|
||||
delete_list.append(d.name)
|
||||
|
||||
if not delete_list:
|
||||
return obj.doclist
|
||||
|
||||
# delete from doclist
|
||||
obj.doclist = filter(lambda d: d.name not in delete_list, obj.doclist)
|
||||
|
||||
# delete from db
|
||||
webnotes.conn.sql("""\
|
||||
delete from `tabDelivery Note Packing Item`
|
||||
where name in (%s)"""
|
||||
% (", ".join(["%s"] * len(delete_list))),
|
||||
tuple(delete_list))
|
||||
|
||||
return obj.doclist
|
||||
|
||||
# Get total in words
|
||||
# ==================================================================
|
||||
def get_total_in_words(self, currency, amount):
|
||||
from webnotes.utils import money_in_words
|
||||
return money_in_words(amount, currency)
|
||||
|
||||
|
||||
# Get month based on date (required in sales person and sales partner)
|
||||
# ========================================================================
|
||||
def get_month(self,date):
|
||||
month_list = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
|
||||
month_idx = cint(cstr(date).split('-')[1])-1
|
||||
return month_list[month_idx]
|
||||
|
||||
|
||||
# **** Check for Stop SO as no transactions can be made against Stopped SO. Need to unstop it. ***
|
||||
def check_stop_sales_order(self,obj):
|
||||
for d in getlist(obj.doclist,obj.fname):
|
||||
ref_doc_name = ''
|
||||
if d.fields.has_key('prevdoc_docname') and d.prevdoc_docname and d.prevdoc_doctype == 'Sales Order':
|
||||
ref_doc_name = d.prevdoc_docname
|
||||
elif d.fields.has_key('sales_order') and d.sales_order and not d.delivery_note:
|
||||
ref_doc_name = d.sales_order
|
||||
if ref_doc_name:
|
||||
so_status = webnotes.conn.sql("select status from `tabSales Order` where name = %s",ref_doc_name)
|
||||
so_status = so_status and so_status[0][0] or ''
|
||||
if so_status == 'Stopped':
|
||||
msgprint("You cannot do any transaction against Sales Order : '%s' as it is Stopped." %(ref_doc_name))
|
||||
raise Exception
|
||||
|
||||
|
||||
# ****** Check for Item.is_sales_item = 'Yes' and Item.docstatus != 2 *******
|
||||
def check_active_sales_items(self,obj):
|
||||
for d in getlist(obj.doclist, obj.fname):
|
||||
if d.item_code: # extra condn coz item_code is not mandatory in RV
|
||||
valid_item = webnotes.conn.sql("select docstatus,is_sales_item, is_service_item from tabItem where name = %s",d.item_code)
|
||||
if valid_item and valid_item[0][0] == 2:
|
||||
msgprint("Item : '%s' does not exist in system." %(d.item_code))
|
||||
raise Exception
|
||||
sales_item = valid_item and valid_item[0][1] or 'No'
|
||||
service_item = valid_item and valid_item[0][2] or 'No'
|
||||
if sales_item == 'No' and service_item == 'No':
|
||||
msgprint("Item : '%s' is neither Sales nor Service Item"%(d.item_code))
|
||||
raise Exception
|
||||
|
||||
|
||||
# **************************************************************************************************************************************************
|
||||
|
||||
def check_credit(self,obj,grand_total):
|
||||
acc_head = webnotes.conn.sql("select name from `tabAccount` where company = '%s' and master_name = '%s'"%(obj.doc.company, obj.doc.customer))
|
||||
if acc_head:
|
||||
tot_outstanding = 0
|
||||
dbcr = webnotes.conn.sql("select sum(debit), sum(credit) from `tabGL Entry` where account = '%s' and ifnull(is_cancelled, 'No')='No'" % acc_head[0][0])
|
||||
if dbcr:
|
||||
tot_outstanding = flt(dbcr[0][0])-flt(dbcr[0][1])
|
||||
|
||||
exact_outstanding = flt(tot_outstanding) + flt(grand_total)
|
||||
get_obj('Account',acc_head[0][0]).check_credit_limit(acc_head[0][0], obj.doc.company, exact_outstanding)
|
||||
|
||||
def validate_fiscal_year(self,fiscal_year,transaction_date,dn):
|
||||
fy=webnotes.conn.sql("select year_start_date from `tabFiscal Year` where name='%s'"%fiscal_year)
|
||||
ysd=fy and fy[0][0] or ""
|
||||
yed=add_days(str(ysd),365)
|
||||
if str(transaction_date) < str(ysd) or str(transaction_date) > str(yed):
|
||||
msgprint("%s not within the fiscal year"%(dn))
|
||||
raise Exception
|
||||
|
||||
|
||||
# get against document date self.prevdoc_date_field
|
||||
#-----------------------------
|
||||
def get_prevdoc_date(self, obj):
|
||||
import datetime
|
||||
for d in getlist(obj.doclist, obj.fname):
|
||||
if d.prevdoc_doctype and d.prevdoc_docname:
|
||||
if d.prevdoc_doctype == 'Sales Invoice':
|
||||
dt = webnotes.conn.sql("select posting_date from `tab%s` where name = '%s'" % (d.prevdoc_doctype, d.prevdoc_docname))
|
||||
else:
|
||||
dt = webnotes.conn.sql("select transaction_date from `tab%s` where name = '%s'" % (d.prevdoc_doctype, d.prevdoc_docname))
|
||||
d.prevdoc_date = (dt and dt[0][0]) and dt[0][0].strftime('%Y-%m-%d') or ''
|
||||
|
||||
def update_prevdoc_detail(self, is_submit, obj):
|
||||
StatusUpdater(obj, is_submit).update()
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
# make item code readonly if (detail no is set)
|
||||
#
|
||||
|
||||
|
||||
class StatusUpdater:
|
||||
"""
|
||||
Updates the status of the calling records
|
||||
|
||||
From Delivery Note
|
||||
- Update Delivered Qty
|
||||
- Update Percent
|
||||
- Validate over delivery
|
||||
|
||||
From Sales Invoice
|
||||
- Update Billed Amt
|
||||
- Update Percent
|
||||
- Validate over billing
|
||||
|
||||
From Installation Note
|
||||
- Update Installed Qty
|
||||
- Update Percent Qty
|
||||
- Validate over installation
|
||||
"""
|
||||
def __init__(self, obj, is_submit):
|
||||
self.obj = obj # caller object
|
||||
self.is_submit = is_submit
|
||||
self.tolerance = {}
|
||||
self.global_tolerance = None
|
||||
|
||||
def update(self):
|
||||
self.update_all_qty()
|
||||
self.validate_all_qty()
|
||||
|
||||
def validate_all_qty(self):
|
||||
"""
|
||||
Validates over-billing / delivery / installation in Delivery Note, Sales Invoice, Installation Note
|
||||
To called after update_all_qty
|
||||
"""
|
||||
if self.obj.doc.doctype=='Delivery Note':
|
||||
self.validate_qty({
|
||||
'source_dt' :'Delivery Note Item',
|
||||
'compare_field' :'delivered_qty',
|
||||
'compare_ref_field' :'qty',
|
||||
'target_dt' :'Sales Order Item',
|
||||
'join_field' :'prevdoc_detail_docname'
|
||||
})
|
||||
elif self.obj.doc.doctype=='Sales Invoice':
|
||||
self.validate_qty({
|
||||
'source_dt' :'Sales Invoice Item',
|
||||
'compare_field' :'billed_amt',
|
||||
'compare_ref_field' :'export_amount',
|
||||
'target_dt' :'Sales Order Item',
|
||||
'join_field' :'so_detail'
|
||||
})
|
||||
self.validate_qty({
|
||||
'source_dt' :'Sales Invoice Item',
|
||||
'compare_field' :'billed_amt',
|
||||
'compare_ref_field' :'export_amount',
|
||||
'target_dt' :'Delivery Note Item',
|
||||
'join_field' :'dn_detail'
|
||||
}, no_tolerance =1)
|
||||
elif self.obj.doc.doctype=='Installation Note':
|
||||
self.validate_qty({
|
||||
'source_dt' :'Installation Item Details',
|
||||
'compare_field' :'installed_qty',
|
||||
'compare_ref_field' :'qty',
|
||||
'target_dt' :'Delivery Note Item',
|
||||
'join_field' :'dn_detail'
|
||||
}, no_tolerance =1)
|
||||
|
||||
|
||||
def get_tolerance_for(self, item_code):
|
||||
"""
|
||||
Returns the tolerance for the item, if not set, returns global tolerance
|
||||
"""
|
||||
if self.tolerance.get(item_code):
|
||||
return self.tolerance[item_code]
|
||||
|
||||
tolerance = flt(get_value('Item',item_code,'tolerance') or 0)
|
||||
|
||||
if not(tolerance):
|
||||
if self.global_tolerance == None:
|
||||
self.global_tolerance = flt(get_value('Global Defaults',None,'tolerance') or 0)
|
||||
tolerance = self.global_tolerance
|
||||
|
||||
self.tolerance[item_code] = tolerance
|
||||
return tolerance
|
||||
|
||||
def check_overflow_with_tolerance(self, item, args):
|
||||
"""
|
||||
Checks if there is overflow condering a relaxation tolerance
|
||||
"""
|
||||
|
||||
# check if overflow is within tolerance
|
||||
tolerance = self.get_tolerance_for(item['item_code'])
|
||||
overflow_percent = ((item[args['compare_field']] - item[args['compare_ref_field']]) / item[args['compare_ref_field']] * 100)
|
||||
|
||||
if overflow_percent - tolerance > 0.01:
|
||||
item['max_allowed'] = flt(item[args['compare_ref_field']] * (100+tolerance)/100)
|
||||
item['reduce_by'] = item[args['compare_field']] - item['max_allowed']
|
||||
|
||||
msgprint("""
|
||||
Row #%(idx)s: Max %(compare_ref_field)s allowed for <b>Item %(item_code)s</b> against <b>%(parenttype)s %(parent)s</b> is <b>%(max_allowed)s</b>.
|
||||
|
||||
If you want to increase your overflow tolerance, please increase tolerance %% in Global Defaults or Item master.
|
||||
|
||||
Or, you must reduce the %(compare_ref_field)s by %(reduce_by)s
|
||||
|
||||
Also, please check if the order item has already been billed in the Sales Order""" % item, raise_exception=1)
|
||||
|
||||
def validate_qty(self, args, no_tolerance=None):
|
||||
"""
|
||||
Validates qty at row level
|
||||
"""
|
||||
# get unique transactions to update
|
||||
for d in self.obj.doclist:
|
||||
if d.doctype == args['source_dt']:
|
||||
args['name'] = d.fields[args['join_field']]
|
||||
|
||||
# get all qty where qty > compare_field
|
||||
item = webnotes.conn.sql("""
|
||||
select item_code, `%(compare_ref_field)s`, `%(compare_field)s`, parenttype, parent from `tab%(target_dt)s`
|
||||
where `%(compare_ref_field)s` < `%(compare_field)s` and name="%(name)s" and docstatus=1
|
||||
""" % args, as_dict=1)
|
||||
if item:
|
||||
item = item[0]
|
||||
item['idx'] = d.idx
|
||||
item['compare_ref_field'] = args['compare_ref_field'].replace('_', ' ')
|
||||
|
||||
if not item[args['compare_ref_field']]:
|
||||
msgprint("As %(compare_ref_field)s for item: %(item_code)s in %(parenttype)s: %(parent)s is zero, system will not check over-delivery or over-billed" % item)
|
||||
elif no_tolerance:
|
||||
item['reduce_by'] = item[args['compare_field']] - item[args['compare_ref_field']]
|
||||
if item['reduce_by'] > .01:
|
||||
msgprint("""
|
||||
Row #%(idx)s: Max %(compare_ref_field)s allowed for <b>Item %(item_code)s</b> against
|
||||
<b>%(parenttype)s %(parent)s</b> is <b>""" % item
|
||||
+ cstr(item[args['compare_ref_field']]) + """</b>.
|
||||
|
||||
You must reduce the %(compare_ref_field)s by %(reduce_by)s""" % item, raise_exception=1)
|
||||
|
||||
else:
|
||||
self.check_overflow_with_tolerance(item, args)
|
||||
|
||||
|
||||
def update_all_qty(self):
|
||||
"""
|
||||
Updates delivered / billed / installed qty in Sales Order & Delivery Note
|
||||
"""
|
||||
if self.obj.doc.doctype=='Delivery Note':
|
||||
self.update_qty({
|
||||
'target_field' :'delivered_qty',
|
||||
'target_dt' :'Sales Order Item',
|
||||
'target_parent_dt' :'Sales Order',
|
||||
'target_parent_field' :'per_delivered',
|
||||
'target_ref_field' :'qty',
|
||||
'source_dt' :'Delivery Note Item',
|
||||
'source_field' :'qty',
|
||||
'join_field' :'prevdoc_detail_docname',
|
||||
'percent_join_field' :'prevdoc_docname',
|
||||
'status_field' :'delivery_status',
|
||||
'keyword' :'Delivered'
|
||||
})
|
||||
|
||||
elif self.obj.doc.doctype=='Sales Invoice':
|
||||
self.update_qty({
|
||||
'target_field' :'billed_amt',
|
||||
'target_dt' :'Sales Order Item',
|
||||
'target_parent_dt' :'Sales Order',
|
||||
'target_parent_field' :'per_billed',
|
||||
'target_ref_field' :'export_amount',
|
||||
'source_dt' :'Sales Invoice Item',
|
||||
'source_field' :'export_amount',
|
||||
'join_field' :'so_detail',
|
||||
'percent_join_field' :'sales_order',
|
||||
'status_field' :'billing_status',
|
||||
'keyword' :'Billed'
|
||||
})
|
||||
|
||||
self.update_qty({
|
||||
'target_field' :'billed_amt',
|
||||
'target_dt' :'Delivery Note Item',
|
||||
'target_parent_dt' :'Delivery Note',
|
||||
'target_parent_field' :'per_billed',
|
||||
'target_ref_field' :'export_amount',
|
||||
'source_dt' :'Sales Invoice Item',
|
||||
'source_field' :'export_amount',
|
||||
'join_field' :'dn_detail',
|
||||
'percent_join_field' :'delivery_note',
|
||||
'status_field' :'billing_status',
|
||||
'keyword' :'Billed'
|
||||
})
|
||||
|
||||
if self.obj.doc.doctype=='Installation Note':
|
||||
self.update_qty({
|
||||
'target_field' :'installed_qty',
|
||||
'target_dt' :'Delivery Note Item',
|
||||
'target_parent_dt' :'Delivery Note',
|
||||
'target_parent_field' :'per_installed',
|
||||
'target_ref_field' :'qty',
|
||||
'source_dt' :'Installation Note Item',
|
||||
'source_field' :'qty',
|
||||
'join_field' :'prevdoc_detail_docname',
|
||||
'percent_join_field' :'prevdoc_docname',
|
||||
'status_field' :'installation_status',
|
||||
'keyword' :'Installed'
|
||||
})
|
||||
|
||||
|
||||
def update_qty(self, args):
|
||||
"""
|
||||
Updates qty at row level
|
||||
"""
|
||||
# condition to include current record (if submit or no if cancel)
|
||||
if self.is_submit:
|
||||
args['cond'] = ' or parent="%s"' % self.obj.doc.name
|
||||
else:
|
||||
args['cond'] = ' and parent!="%s"' % self.obj.doc.name
|
||||
|
||||
# update quantities in child table
|
||||
for d in self.obj.doclist:
|
||||
if d.doctype == args['source_dt']:
|
||||
# updates qty in the child table
|
||||
args['detail_id'] = d.fields.get(args['join_field'])
|
||||
|
||||
if args['detail_id']:
|
||||
webnotes.conn.sql("""
|
||||
update
|
||||
`tab%(target_dt)s`
|
||||
set
|
||||
%(target_field)s = (select sum(%(source_field)s) from `tab%(source_dt)s` where `%(join_field)s`="%(detail_id)s" and (docstatus=1 %(cond)s))
|
||||
where
|
||||
name="%(detail_id)s"
|
||||
""" % args)
|
||||
|
||||
# get unique transactions to update
|
||||
for name in set([d.fields.get(args['percent_join_field']) for d in self.obj.doclist if d.doctype == args['source_dt']]):
|
||||
if name:
|
||||
args['name'] = name
|
||||
|
||||
# update percent complete in the parent table
|
||||
webnotes.conn.sql("""
|
||||
update
|
||||
`tab%(target_parent_dt)s`
|
||||
set
|
||||
%(target_parent_field)s =
|
||||
(select sum(if(%(target_ref_field)s > ifnull(%(target_field)s, 0), %(target_field)s, %(target_ref_field)s))/sum(%(target_ref_field)s)*100 from `tab%(target_dt)s` where parent="%(name)s"),
|
||||
modified = now()
|
||||
where
|
||||
name="%(name)s"
|
||||
""" % args)
|
||||
|
||||
# update field
|
||||
if args['status_field']:
|
||||
webnotes.conn.sql("""
|
||||
update
|
||||
`tab%(target_parent_dt)s`
|
||||
set
|
||||
%(status_field)s = if(ifnull(%(target_parent_field)s,0)<0.001, 'Not %(keyword)s',
|
||||
if(%(target_parent_field)s>=99.99, 'Fully %(keyword)s', 'Partly %(keyword)s')
|
||||
)
|
||||
where
|
||||
name="%(name)s"
|
||||
""" % args)
|
||||
|
||||
31
selling/doctype/sales_common/sales_common.txt
Normal file
31
selling/doctype/sales_common/sales_common.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
# DocType, Sales Common
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:14',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:14',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'issingle': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 290
|
||||
},
|
||||
|
||||
# DocType, Sales Common
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Sales Common'
|
||||
}
|
||||
]
|
||||
1
selling/doctype/sales_order/__init__.py
Normal file
1
selling/doctype/sales_order/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
365
selling/doctype/sales_order/sales_order.js
Normal file
365
selling/doctype/sales_order/sales_order.js
Normal file
@@ -0,0 +1,365 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Module CRM
|
||||
|
||||
cur_frm.cscript.tname = "Sales Order Item";
|
||||
cur_frm.cscript.fname = "sales_order_details";
|
||||
cur_frm.cscript.other_fname = "other_charges";
|
||||
cur_frm.cscript.sales_team_fname = "sales_team";
|
||||
|
||||
|
||||
wn.require('erpnext/selling/doctype/sales_common/sales_common.js');
|
||||
wn.require('erpnext/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js');
|
||||
wn.require('erpnext/utilities/doctype/sms_control/sms_control.js');
|
||||
wn.require('erpnext/setup/doctype/notification_control/notification_control.js');
|
||||
|
||||
|
||||
// ONLOAD
|
||||
// ================================================================================================
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
if(!doc.status) set_multiple(cdt,cdn,{status:'Draft'});
|
||||
if(!doc.transaction_date) set_multiple(cdt,cdn,{transaction_date:get_today()});
|
||||
if(!doc.price_list_currency) set_multiple(cdt, cdn, {price_list_currency: doc.currency, plc_conversion_rate: 1});
|
||||
// load default charges
|
||||
|
||||
if(doc.__islocal && !doc.customer){
|
||||
hide_field(['customer_address','contact_person','customer_name','address_display','contact_display','contact_mobile','contact_email','territory','customer_group','shipping_address']);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {
|
||||
var callback = function(doc, cdt, cdn) {
|
||||
if(doc.__islocal) {
|
||||
// defined in sales_common.js
|
||||
cur_frm.cscript.update_item_details(doc, cdt, cdn);
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.hide_price_list_currency(doc, cdt, cdn, callback);
|
||||
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
|
||||
cur_frm.clear_custom_buttons();
|
||||
erpnext.hide_naming_series();
|
||||
|
||||
if (!cur_frm.cscript.is_onload) cur_frm.cscript.hide_price_list_currency(doc, cdt, cdn);
|
||||
|
||||
if(doc.customer) $(cur_frm.fields_dict.contact_info.row.wrapper).toggle(true);
|
||||
else $(cur_frm.fields_dict.contact_info.row.wrapper).toggle(false);
|
||||
|
||||
if(doc.docstatus==1) {
|
||||
if(doc.status != 'Stopped') {
|
||||
cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms);
|
||||
// delivery note
|
||||
if(doc.per_delivered < 100 && doc.order_type=='Sales')
|
||||
cur_frm.add_custom_button('Make Delivery', cur_frm.cscript['Make Delivery Note']);
|
||||
|
||||
// maintenance
|
||||
if(doc.per_delivered < 100 && (doc.order_type !='Sales')) {
|
||||
cur_frm.add_custom_button('Make Maint. Visit', cur_frm.cscript.make_maintenance_visit);
|
||||
cur_frm.add_custom_button('Make Maint. Schedule', cur_frm.cscript['Make Maintenance Schedule']);
|
||||
}
|
||||
|
||||
// indent
|
||||
if(!doc.order_type || (doc.order_type == 'Sales'))
|
||||
cur_frm.add_custom_button('Make ' + get_doctype_label('Purchase Request'), cur_frm.cscript['Make Purchase Request']);
|
||||
|
||||
// sales invoice
|
||||
if(doc.per_billed < 100)
|
||||
cur_frm.add_custom_button('Make Invoice', cur_frm.cscript['Make Sales Invoice']);
|
||||
|
||||
// stop
|
||||
if(doc.per_delivered < 100 || doc.per_billed < 100)
|
||||
cur_frm.add_custom_button('Stop!', cur_frm.cscript['Stop Sales Order']);
|
||||
} else {
|
||||
// un-stop
|
||||
cur_frm.add_custom_button('Unstop', cur_frm.cscript['Unstop Sales Order']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//customer
|
||||
cur_frm.cscript.customer = function(doc,dt,dn) {
|
||||
var pl = doc.price_list_name;
|
||||
var callback = function(r,rt) {
|
||||
var callback2 = function(r, rt) {
|
||||
|
||||
if(doc.customer) unhide_field(['customer_address', 'contact_person', 'territory','customer_group','shipping_address']);
|
||||
cur_frm.refresh();
|
||||
|
||||
if(!onload && (pl != doc.price_list_name)) cur_frm.cscript.price_list_name(doc, dt, dn);
|
||||
|
||||
}
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
get_server_fields('get_shipping_address',doc.customer,'',doc, dt, dn, 0, callback2);
|
||||
|
||||
}
|
||||
if(doc.customer) $c_obj(make_doclist(doc.doctype, doc.name), 'get_default_customer_address', '', callback);
|
||||
}
|
||||
|
||||
cur_frm.cscript.customer_address = cur_frm.cscript.contact_person = function(doc,dt,dn) {
|
||||
if(doc.customer) get_server_fields('get_customer_address', JSON.stringify({customer: doc.customer, address: doc.customer_address, contact: doc.contact_person}),'', doc, dt, dn, 1);
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.customer_address.on_new = function(dn) {
|
||||
locals['Address'][dn].customer = locals[cur_frm.doctype][cur_frm.docname].customer;
|
||||
locals['Address'][dn].customer_name = locals[cur_frm.doctype][cur_frm.docname].customer_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.contact_person.on_new = function(dn) {
|
||||
locals['Contact'][dn].customer = locals[cur_frm.doctype][cur_frm.docname].customer;
|
||||
locals['Contact'][dn].customer_name = locals[cur_frm.doctype][cur_frm.docname].customer_name;
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['customer_address'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,address_line1,city FROM tabAddress WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.fields_dict['contact_person'].get_query = function(doc, cdt, cdn) {
|
||||
return 'SELECT name,CONCAT(first_name," ",ifnull(last_name,"")) As FullName,department,designation FROM tabContact WHERE customer = "'+ doc.customer +'" AND docstatus != 2 AND name LIKE "%s" ORDER BY name ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.cscript.pull_quotation_details = function(doc,dt,dn) {
|
||||
var callback = function(r,rt){
|
||||
var doc = locals[cur_frm.doctype][cur_frm.docname];
|
||||
if(r.message){
|
||||
doc.quotation_no = r.message;
|
||||
if(doc.quotation_no) {
|
||||
unhide_field(['quotation_date','customer_address','contact_person','territory','customer_group','shipping_address']);
|
||||
if(doc.customer) get_server_fields('get_shipping_address',doc.customer,'',doc, dt, dn, 0);
|
||||
}
|
||||
cur_frm.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'pull_quotation_details','',callback);
|
||||
}
|
||||
|
||||
|
||||
//================ create new contact ============================================================================
|
||||
cur_frm.cscript.new_contact = function(){
|
||||
tn = createLocal('Contact');
|
||||
locals['Contact'][tn].is_customer = 1;
|
||||
if(doc.customer) locals['Contact'][tn].customer = doc.customer;
|
||||
loaddoc('Contact', tn);
|
||||
}
|
||||
|
||||
// DOCTYPE TRIGGERS
|
||||
// ================================================================================================
|
||||
|
||||
|
||||
// ***************** Get project name *****************
|
||||
cur_frm.fields_dict['project_name'].get_query = function(doc, cdt, cdn) {
|
||||
var cond = '';
|
||||
if(doc.customer) cond = '(`tabProject`.customer = "'+doc.customer+'" OR IFNULL(`tabProject`.customer,"")="") AND';
|
||||
return repl('SELECT `tabProject`.name FROM `tabProject` WHERE `tabProject`.status = "Open" AND %(cond)s `tabProject`.name LIKE "%s" ORDER BY `tabProject`.name ASC LIMIT 50', {cond:cond});
|
||||
}
|
||||
|
||||
//---- get customer details ----------------------------
|
||||
cur_frm.cscript.project_name = function(doc,cdt,cdn){
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'pull_project_customer','', function(r,rt){
|
||||
refresh_many(['customer','customer_name', 'customer_address', 'contact_person', 'territory', 'contact_no', 'email_id', 'customer_group']);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// *************** Customized link query for QUOTATION *****************************
|
||||
cur_frm.fields_dict['quotation_no'].get_query = function(doc) {
|
||||
var cond='';
|
||||
if(doc.order_type) cond = ' ifnull(`tabQuotation`.order_type, "") = "'+doc.order_type+'" and';
|
||||
if(doc.customer) cond += ' ifnull(`tabQuotation`.customer, "") = "'+doc.customer+'" and';
|
||||
|
||||
return repl('SELECT DISTINCT name, customer, transaction_date FROM `tabQuotation` WHERE `tabQuotation`.company = "' + doc.company + '" and `tabQuotation`.`docstatus` = 1 and `tabQuotation`.status != "Order Lost" and %(cond)s `tabQuotation`.%(key)s LIKE "%s" ORDER BY `tabQuotation`.`name` DESC LIMIT 50', {cond:cond});
|
||||
}
|
||||
|
||||
|
||||
// SALES ORDER DETAILS TRIGGERS
|
||||
// ================================================================================================
|
||||
|
||||
// ***************** Get available qty in warehouse of item selected ****************
|
||||
cur_frm.cscript.reserved_warehouse = function(doc, cdt , cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if (d.reserved_warehouse) {
|
||||
arg = "{'item_code':'" + d.item_code + "','warehouse':'" + d.reserved_warehouse +"'}";
|
||||
get_server_fields('get_available_qty',arg,'sales_order_details',doc,cdt,cdn,1);
|
||||
}
|
||||
}
|
||||
|
||||
//----------- make maintenance schedule----------
|
||||
cur_frm.cscript['Make Maintenance Schedule'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
|
||||
if (doc.docstatus == 1) {
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'check_maintenance_schedule','',
|
||||
function(r,rt){
|
||||
if(r.message == 'No'){
|
||||
n = createLocal("Maintenance Schedule");
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals["Maintenance Schedule"][n]]),
|
||||
'from_doctype':'Sales Order',
|
||||
'to_doctype':'Maintenance Schedule',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Sales Order', 'Maintenance Schedule'], ['Sales Order Item', 'Maintenance Schedule Item']]"
|
||||
}
|
||||
, function(r,rt) {
|
||||
loaddoc("Maintenance Schedule", n);
|
||||
}
|
||||
);
|
||||
}
|
||||
else{
|
||||
msgprint("You have already created Maintenance Schedule against this Sales Order");
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//------------ make maintenance visit ------------
|
||||
cur_frm.cscript.make_maintenance_visit = function() {
|
||||
var doc = cur_frm.doc;
|
||||
|
||||
if (doc.docstatus == 1) {
|
||||
$c_obj(make_doclist(doc.doctype, doc.name),'check_maintenance_visit','',
|
||||
function(r,rt){
|
||||
if(r.message == 'No'){
|
||||
n = createLocal("Maintenance Visit");
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals["Maintenance Visit"][n]]),
|
||||
'from_doctype':'Sales Order',
|
||||
'to_doctype':'Maintenance Visit',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Sales Order', 'Maintenance Visit'], ['Sales Order Item', 'Maintenance Visit Purpose']]"
|
||||
}
|
||||
, function(r,rt) {
|
||||
loaddoc("Maintenance Visit", n);
|
||||
}
|
||||
);
|
||||
}
|
||||
else{
|
||||
msgprint("You have already completed maintenance against this Sales Order");
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// make indent
|
||||
// ================================================================================================
|
||||
cur_frm.cscript['Make Purchase Request'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
if (doc.docstatus == 1) {
|
||||
n = createLocal("Purchase Request");
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals["Purchase Request"][n]]),
|
||||
'from_doctype':'Sales Order',
|
||||
'to_doctype':'Purchase Request',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Sales Order', 'Purchase Request'], ['Sales Order Item', 'Purchase Request Item']]"
|
||||
}
|
||||
, function(r,rt) {
|
||||
loaddoc("Purchase Request", n);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MAKE DELIVERY NOTE
|
||||
// ================================================================================================
|
||||
cur_frm.cscript['Make Delivery Note'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
if (doc.docstatus == 1) {
|
||||
n = createLocal("Delivery Note");
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals["Delivery Note"][n]]),
|
||||
'from_doctype':'Sales Order',
|
||||
'to_doctype':'Delivery Note',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Sales Order', 'Delivery Note'], ['Sales Order Item', 'Delivery Note Item'],['Sales Taxes and Charges','Sales Taxes and Charges'],['Sales Team','Sales Team']]"
|
||||
}
|
||||
, function(r,rt) {
|
||||
loaddoc("Delivery Note", n);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MAKE SALES INVOICE
|
||||
// ================================================================================================
|
||||
cur_frm.cscript['Make Sales Invoice'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
|
||||
n = createLocal('Sales Invoice');
|
||||
$c('dt_map', args={
|
||||
'docs':compress_doclist([locals['Sales Invoice'][n]]),
|
||||
'from_doctype':doc.doctype,
|
||||
'to_doctype':'Sales Invoice',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Sales Order','Sales Invoice'],['Sales Order Item','Sales Invoice Item'],['Sales Taxes and Charges','Sales Taxes and Charges'],['Sales Team','Sales Team']]"
|
||||
}, function(r,rt) {
|
||||
loaddoc('Sales Invoice', n);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// STOP SALES ORDER
|
||||
// ==================================================================================================
|
||||
cur_frm.cscript['Stop Sales Order'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
|
||||
var check = confirm("Are you sure you want to STOP " + doc.name);
|
||||
|
||||
if (check) {
|
||||
$c('runserverobj', args={'method':'stop_sales_order', 'docs': compress_doclist(make_doclist(doc.doctype, doc.name))}, function(r,rt) {
|
||||
cur_frm.refresh();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// UNSTOP SALES ORDER
|
||||
// ==================================================================================================
|
||||
cur_frm.cscript['Unstop Sales Order'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
|
||||
var check = confirm("Are you sure you want to UNSTOP " + doc.name);
|
||||
|
||||
if (check) {
|
||||
$c('runserverobj', args={'method':'unstop_sales_order', 'docs': compress_doclist(make_doclist(doc.doctype, doc.name))}, function(r,rt) {
|
||||
cur_frm.refresh();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//get query select Territory
|
||||
//=======================================================================================================================
|
||||
cur_frm.fields_dict['territory'].get_query = function(doc,cdt,cdn) {
|
||||
return 'SELECT `tabTerritory`.`name`,`tabTerritory`.`parent_territory` FROM `tabTerritory` WHERE `tabTerritory`.`is_group` = "No" AND `tabTerritory`.`docstatus`!= 2 AND `tabTerritory`.%(key)s LIKE "%s" ORDER BY `tabTerritory`.`name` ASC LIMIT 50';
|
||||
}
|
||||
|
||||
cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
|
||||
var args = {
|
||||
type: 'Sales Order',
|
||||
doctype: 'Sales Order'
|
||||
}
|
||||
cur_frm.cscript.notify(doc, args);
|
||||
}
|
||||
479
selling/doctype/sales_order/sales_order.py
Normal file
479
selling/doctype/sales_order/sales_order.py
Normal file
@@ -0,0 +1,479 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
|
||||
from utilities.transaction_base import TransactionBase
|
||||
|
||||
class DocType(TransactionBase):
|
||||
def __init__(self, doc, doclist=None):
|
||||
self.doc = doc
|
||||
if not doclist: doclist = []
|
||||
self.doclist = doclist
|
||||
self.tname = 'Sales Order Item'
|
||||
self.fname = 'sales_order_details'
|
||||
self.person_tname = 'Target Detail'
|
||||
self.partner_tname = 'Partner Target Detail'
|
||||
self.territory_tname = 'Territory Target Detail'
|
||||
|
||||
# Autoname
|
||||
# ===============
|
||||
def autoname(self):
|
||||
self.doc.name = make_autoname(self.doc.naming_series+'.#####')
|
||||
|
||||
|
||||
# DOCTYPE TRIGGER FUNCTIONS
|
||||
# =============================
|
||||
# Pull Quotation Items
|
||||
# -----------------------
|
||||
def pull_quotation_details(self):
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'other_charges')
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'sales_order_details')
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'sales_team')
|
||||
self.doclist = self.doc.clear_table(self.doclist, 'tc_details')
|
||||
if self.doc.quotation_no:
|
||||
get_obj('DocType Mapper', 'Quotation-Sales Order').dt_map('Quotation', 'Sales Order', self.doc.quotation_no, self.doc, self.doclist, "[['Quotation', 'Sales Order'],['Quotation Item', 'Sales Order Item'],['Sales Taxes and Charges','Sales Taxes and Charges'],['Sales Team','Sales Team'],['TC Detail','TC Detail']]")
|
||||
else:
|
||||
msgprint("Please select Quotation whose details need to pull")
|
||||
|
||||
return cstr(self.doc.quotation_no)
|
||||
|
||||
#pull project customer
|
||||
#-------------------------
|
||||
def pull_project_customer(self):
|
||||
res = sql("select customer from `tabProject` where name = '%s'"%self.doc.project_name)
|
||||
if res:
|
||||
get_obj('DocType Mapper', 'Project-Sales Order').dt_map('Project', 'Sales Order', self.doc.project_name, self.doc, self.doclist, "[['Project', 'Sales Order']]")
|
||||
|
||||
|
||||
# Get contact person details based on customer selected
|
||||
# ------------------------------------------------------
|
||||
def get_contact_details(self):
|
||||
get_obj('Sales Common').get_contact_details(self,0)
|
||||
|
||||
# Get Commission rate of Sales Partner
|
||||
# -------------------------------------
|
||||
def get_comm_rate(self, sales_partner):
|
||||
return get_obj('Sales Common').get_comm_rate(sales_partner, self)
|
||||
|
||||
|
||||
# SALES ORDER DETAILS TRIGGER FUNCTIONS
|
||||
# ================================================================================
|
||||
# Get Item Details
|
||||
# ----------------
|
||||
def get_item_details(self, args=None):
|
||||
import json
|
||||
args = args and json.loads(args) or {}
|
||||
if args.get('item_code'):
|
||||
return get_obj('Sales Common').get_item_details(args, self)
|
||||
else:
|
||||
obj = get_obj('Sales Common')
|
||||
for doc in self.doclist:
|
||||
if doc.fields.get('item_code'):
|
||||
arg = {'item_code':doc.fields.get('item_code'), 'income_account':doc.fields.get('income_account'),
|
||||
'cost_center': doc.fields.get('cost_center'), 'warehouse': doc.fields.get('warehouse')};
|
||||
ret = obj.get_item_defaults(arg)
|
||||
for r in ret:
|
||||
if not doc.fields.get(r):
|
||||
doc.fields[r] = ret[r]
|
||||
|
||||
|
||||
# Re-calculates Basic Rate & amount based on Price List Selected
|
||||
# --------------------------------------------------------------
|
||||
def get_adj_percent(self, arg=''):
|
||||
get_obj('Sales Common').get_adj_percent(self)
|
||||
|
||||
|
||||
|
||||
# Get projected qty of item based on warehouse selected
|
||||
# -----------------------------------------------------
|
||||
def get_available_qty(self,args):
|
||||
return get_obj('Sales Common').get_available_qty(eval(args))
|
||||
|
||||
# OTHER CHARGES TRIGGER FUNCTIONS
|
||||
# ====================================================================================
|
||||
|
||||
# Get Tax rate if account type is TAX
|
||||
# ------------------------------------
|
||||
def get_rate(self,arg):
|
||||
return get_obj('Sales Common').get_rate(arg)
|
||||
|
||||
# Load Default Charges
|
||||
# ----------------------------------------------------------
|
||||
def load_default_taxes(self):
|
||||
self.doclist = get_obj('Sales Common').load_default_taxes(self)
|
||||
|
||||
# Pull details from other charges master (Get Sales Taxes and Charges Master)
|
||||
# ----------------------------------------------------------
|
||||
def get_other_charges(self):
|
||||
self.doclist = get_obj('Sales Common').get_other_charges(self)
|
||||
|
||||
|
||||
# GET TERMS & CONDITIONS
|
||||
# =====================================================================================
|
||||
def get_tc_details(self):
|
||||
return get_obj('Sales Common').get_tc_details(self)
|
||||
|
||||
#check if maintenance schedule already generated
|
||||
#============================================
|
||||
def check_maintenance_schedule(self):
|
||||
nm = sql("select t1.name from `tabMaintenance Schedule` t1, `tabMaintenance Schedule Item` t2 where t2.parent=t1.name and t2.prevdoc_docname=%s and t1.docstatus=1", self.doc.name)
|
||||
nm = nm and nm[0][0] or ''
|
||||
|
||||
if not nm:
|
||||
return 'No'
|
||||
|
||||
#check if maintenance visit already generated
|
||||
#============================================
|
||||
def check_maintenance_visit(self):
|
||||
nm = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent=t1.name and t2.prevdoc_docname=%s and t1.docstatus=1 and t1.completion_status='Fully Completed'", self.doc.name)
|
||||
nm = nm and nm[0][0] or ''
|
||||
|
||||
if not nm:
|
||||
return 'No'
|
||||
|
||||
# VALIDATE
|
||||
# =====================================================================================
|
||||
# Fiscal Year Validation
|
||||
# ----------------------
|
||||
def validate_fiscal_year(self):
|
||||
get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year,self.doc.transaction_date,'Sales Order Date')
|
||||
|
||||
# Validate values with reference document
|
||||
#----------------------------------------
|
||||
def validate_reference_value(self):
|
||||
get_obj('DocType Mapper', 'Quotation-Sales Order', with_children = 1).validate_reference_value(self, self.doc.name)
|
||||
|
||||
# Validate Mandatory
|
||||
# -------------------
|
||||
def validate_mandatory(self):
|
||||
# validate transaction date v/s delivery date
|
||||
if self.doc.delivery_date:
|
||||
if getdate(self.doc.transaction_date) > getdate(self.doc.delivery_date):
|
||||
msgprint("Expected Delivery Date cannot be before Sales Order Date")
|
||||
raise Exception
|
||||
# amendment date is necessary if document is amended
|
||||
if self.doc.amended_from and not self.doc.amendment_date:
|
||||
msgprint("Please Enter Amendment Date")
|
||||
raise Exception
|
||||
|
||||
|
||||
# Validate P.O Date
|
||||
# ------------------
|
||||
def validate_po(self):
|
||||
# validate p.o date v/s delivery date
|
||||
if self.doc.po_date and self.doc.delivery_date and getdate(self.doc.po_date) > getdate(self.doc.delivery_date):
|
||||
msgprint("Expected Delivery Date cannot be before Purchase Order Date")
|
||||
raise Exception
|
||||
|
||||
if self.doc.po_no and self.doc.customer:
|
||||
so = webnotes.conn.sql("select name from `tabSales Order` \
|
||||
where ifnull(po_no, '') = %s and name != %s and docstatus < 2\
|
||||
and customer = %s", (self.doc.po_no, self.doc.name, self.doc.customer))
|
||||
if so and so[0][0]:
|
||||
msgprint("""Another Sales Order (%s) exists against same PO No and Customer.
|
||||
Please be sure, you are not making duplicate entry.""" % so[0][0])
|
||||
|
||||
# Validations of Details Table
|
||||
# -----------------------------
|
||||
def validate_for_items(self):
|
||||
check_list,flag = [],0
|
||||
chk_dupl_itm = []
|
||||
# Sales Order Items Validations
|
||||
for d in getlist(self.doclist, 'sales_order_details'):
|
||||
if cstr(self.doc.quotation_no) == cstr(d.prevdoc_docname):
|
||||
flag = 1
|
||||
if d.prevdoc_docname:
|
||||
if self.doc.quotation_date and getdate(self.doc.quotation_date) > getdate(self.doc.transaction_date):
|
||||
msgprint("Sales Order Date cannot be before Quotation Date")
|
||||
raise Exception
|
||||
# validates whether quotation no in doctype and in table is same
|
||||
if not cstr(d.prevdoc_docname) == cstr(self.doc.quotation_no):
|
||||
msgprint("Items in table does not belong to the Quotation No mentioned.")
|
||||
raise Exception
|
||||
|
||||
# validates whether item is not entered twice
|
||||
e = [d.item_code, d.description, d.reserved_warehouse, d.prevdoc_docname or '']
|
||||
f = [d.item_code, d.description]
|
||||
|
||||
#check item is stock item
|
||||
st_itm = sql("select is_stock_item from `tabItem` where name = '%s'"%d.item_code)
|
||||
|
||||
if st_itm and st_itm[0][0] == 'Yes':
|
||||
if e in check_list:
|
||||
msgprint("Item %s has been entered twice." % d.item_code)
|
||||
else:
|
||||
check_list.append(e)
|
||||
elif st_itm and st_itm[0][0]== 'No':
|
||||
if f in chk_dupl_itm:
|
||||
msgprint("Item %s has been entered twice." % d.item_code)
|
||||
else:
|
||||
chk_dupl_itm.append(f)
|
||||
|
||||
# used for production plan
|
||||
d.transaction_date = self.doc.transaction_date
|
||||
d.delivery_date = self.doc.delivery_date
|
||||
|
||||
# gets total projected qty of item in warehouse selected (this case arises when warehouse is selected b4 item)
|
||||
tot_avail_qty = sql("select projected_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (d.item_code,d.reserved_warehouse))
|
||||
d.projected_qty = tot_avail_qty and flt(tot_avail_qty[0][0]) or 0
|
||||
|
||||
if flag == 0:
|
||||
msgprint("There are no items of the quotation selected.")
|
||||
raise Exception
|
||||
|
||||
# validate sales/ maintenance quotation against order type
|
||||
#------------------------------------------------------------------
|
||||
def validate_sales_mntc_quotation(self):
|
||||
for d in getlist(self.doclist, 'sales_order_details'):
|
||||
if d.prevdoc_docname:
|
||||
res = sql("select name from `tabQuotation` where name=%s and order_type = %s", (d.prevdoc_docname, self.doc.order_type))
|
||||
if not res:
|
||||
msgprint("""Order Type (%s) should be same in Quotation: %s \
|
||||
and current Sales Order""" % (self.doc.order_type, d.prevdoc_docname))
|
||||
|
||||
def validate_order_type(self):
|
||||
#validate delivery date
|
||||
if self.doc.order_type == 'Sales' and not self.doc.delivery_date:
|
||||
msgprint("Please enter 'Expected Delivery Date'")
|
||||
raise Exception
|
||||
|
||||
self.validate_sales_mntc_quotation()
|
||||
|
||||
#check for does customer belong to same project as entered..
|
||||
#-------------------------------------------------------------------------------------------------
|
||||
def validate_proj_cust(self):
|
||||
if self.doc.project_name and self.doc.customer_name:
|
||||
res = sql("select name from `tabProject` where name = '%s' and (customer = '%s' or ifnull(customer,'')='')"%(self.doc.project_name, self.doc.customer))
|
||||
if not res:
|
||||
msgprint("Customer - %s does not belong to project - %s. \n\nIf you want to use project for multiple customers then please make customer details blank in project - %s."%(self.doc.customer,self.doc.project_name,self.doc.project_name))
|
||||
raise Exception
|
||||
|
||||
|
||||
# Validate
|
||||
# ---------
|
||||
def validate(self):
|
||||
self.validate_fiscal_year()
|
||||
self.validate_order_type()
|
||||
self.validate_mandatory()
|
||||
self.validate_proj_cust()
|
||||
self.validate_po()
|
||||
#self.validate_reference_value()
|
||||
self.validate_for_items()
|
||||
sales_com_obj = get_obj(dt = 'Sales Common')
|
||||
sales_com_obj.check_active_sales_items(self)
|
||||
sales_com_obj.check_conversion_rate(self)
|
||||
|
||||
# verify whether rate is not greater than max_discount
|
||||
sales_com_obj.validate_max_discount(self,'sales_order_details')
|
||||
# this is to verify that the allocated % of sales persons is 100%
|
||||
sales_com_obj.get_allocated_sum(self)
|
||||
self.doclist = sales_com_obj.make_packing_list(self,'sales_order_details')
|
||||
|
||||
# get total in words
|
||||
dcc = TransactionBase().get_company_currency(self.doc.company)
|
||||
self.doc.in_words = sales_com_obj.get_total_in_words(dcc, self.doc.rounded_total)
|
||||
self.doc.in_words_export = sales_com_obj.get_total_in_words(self.doc.currency, self.doc.rounded_total_export)
|
||||
|
||||
# set SO status
|
||||
self.doc.status='Draft'
|
||||
if not self.doc.billing_status: self.doc.billing_status = 'Not Billed'
|
||||
if not self.doc.delivery_status: self.doc.delivery_status = 'Not Delivered'
|
||||
|
||||
|
||||
# ON SUBMIT
|
||||
# ===============================================================================================
|
||||
# Checks Quotation Status
|
||||
# ------------------------
|
||||
def check_prev_docstatus(self):
|
||||
for d in getlist(self.doclist, 'sales_order_details'):
|
||||
cancel_quo = sql("select name from `tabQuotation` where docstatus = 2 and name = '%s'" % d.prevdoc_docname)
|
||||
if cancel_quo:
|
||||
msgprint("Quotation :" + cstr(cancel_quo[0][0]) + " is already cancelled !")
|
||||
raise Exception , "Validation Error. "
|
||||
|
||||
def update_enquiry_status(self, prevdoc, flag):
|
||||
enq = sql("select t2.prevdoc_docname from `tabQuotation` t1, `tabQuotation Item` t2 where t2.parent = t1.name and t1.name=%s", prevdoc)
|
||||
if enq:
|
||||
sql("update `tabOpportunity` set status = %s where name=%s",(flag,enq[0][0]))
|
||||
|
||||
#update status of quotation, enquiry
|
||||
#----------------------------------------
|
||||
def update_prevdoc_status(self, flag):
|
||||
for d in getlist(self.doclist, 'sales_order_details'):
|
||||
if d.prevdoc_docname:
|
||||
if flag=='submit':
|
||||
sql("update `tabQuotation` set status = 'Order Confirmed' where name=%s",d.prevdoc_docname)
|
||||
|
||||
#update enquiry
|
||||
self.update_enquiry_status(d.prevdoc_docname, 'Order Confirmed')
|
||||
elif flag == 'cancel':
|
||||
chk = sql("select t1.name from `tabSales Order` t1, `tabSales Order Item` t2 where t2.parent = t1.name and t2.prevdoc_docname=%s and t1.name!=%s and t1.docstatus=1", (d.prevdoc_docname,self.doc.name))
|
||||
if not chk:
|
||||
sql("update `tabQuotation` set status = 'Submitted' where name=%s",d.prevdoc_docname)
|
||||
|
||||
#update enquiry
|
||||
self.update_enquiry_status(d.prevdoc_docname, 'Quotation Sent')
|
||||
|
||||
# Submit
|
||||
# -------
|
||||
def on_submit(self):
|
||||
self.check_prev_docstatus()
|
||||
self.update_stock_ledger(update_stock = 1)
|
||||
self.set_sms_msg(1)
|
||||
# update customer's last sales order no.
|
||||
update_customer = sql("update `tabCustomer` set last_sales_order = '%s', modified = '%s' where name = '%s'" %(self.doc.name, self.doc.modified, self.doc.customer))
|
||||
get_obj('Sales Common').check_credit(self,self.doc.grand_total)
|
||||
|
||||
# Check for Approving Authority
|
||||
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.grand_total, self)
|
||||
|
||||
#update prevdoc status
|
||||
self.update_prevdoc_status('submit')
|
||||
# set SO status
|
||||
set(self.doc, 'status', 'Submitted')
|
||||
|
||||
|
||||
# ON CANCEL
|
||||
# ===============================================================================================
|
||||
def on_cancel(self):
|
||||
# Cannot cancel stopped SO
|
||||
if self.doc.status == 'Stopped':
|
||||
msgprint("Sales Order : '%s' cannot be cancelled as it is Stopped. Unstop it for any further transactions" %(self.doc.name))
|
||||
raise Exception
|
||||
self.check_nextdoc_docstatus()
|
||||
self.update_stock_ledger(update_stock = -1)
|
||||
self.set_sms_msg()
|
||||
|
||||
#update prevdoc status
|
||||
self.update_prevdoc_status('cancel')
|
||||
|
||||
# ::::::::: SET SO STATUS ::::::::::
|
||||
set(self.doc, 'status', 'Cancelled')
|
||||
|
||||
# CHECK NEXT DOCSTATUS
|
||||
# does not allow to cancel document if DN or RV made against it is SUBMITTED
|
||||
# ----------------------------------------------------------------------------
|
||||
def check_nextdoc_docstatus(self):
|
||||
# Checks Delivery Note
|
||||
submit_dn = sql("select t1.name from `tabDelivery Note` t1,`tabDelivery Note Item` t2 where t1.name = t2.parent and t2.prevdoc_docname = '%s' and t1.docstatus = 1" % (self.doc.name))
|
||||
if submit_dn:
|
||||
msgprint("Delivery Note : " + cstr(submit_dn[0][0]) + " has been submitted against " + cstr(self.doc.doctype) + ". Please cancel Delivery Note : " + cstr(submit_dn[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
|
||||
# Checks Sales Invoice
|
||||
submit_rv = sql("select t1.name from `tabSales Invoice` t1,`tabSales Invoice Item` t2 where t1.name = t2.parent and t2.sales_order = '%s' and t1.docstatus = 1" % (self.doc.name))
|
||||
if submit_rv:
|
||||
msgprint("Sales Invoice : " + cstr(submit_rv[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Sales Invoice : "+ cstr(submit_rv[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
|
||||
#check maintenance schedule
|
||||
submit_ms = sql("select t1.name from `tabMaintenance Schedule` t1, `tabMaintenance Schedule Item` t2 where t2.parent=t1.name and t2.prevdoc_docname = %s and t1.docstatus = 1",self.doc.name)
|
||||
if submit_ms:
|
||||
msgprint("Maintenance Schedule : " + cstr(submit_ms[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Maintenance Schedule : "+ cstr(submit_ms[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
|
||||
submit_mv = sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent=t1.name and t2.prevdoc_docname = %s and t1.docstatus = 1",self.doc.name)
|
||||
if submit_mv:
|
||||
msgprint("Maintenance Visit : " + cstr(submit_mv[0][0]) + " has already been submitted against " +cstr(self.doc.doctype)+ ". Please cancel Maintenance Visit : " + cstr(submit_mv[0][0]) + " first and then cancel "+ cstr(self.doc.doctype), raise_exception = 1)
|
||||
|
||||
|
||||
def check_modified_date(self):
|
||||
mod_db = sql("select modified from `tabSales Order` where name = '%s'" % self.doc.name)
|
||||
date_diff = 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. ")
|
||||
raise Exception
|
||||
|
||||
# STOP SALES ORDER
|
||||
# ==============================================================================================
|
||||
# Stops Sales Order & no more transactions will be created against this Sales Order
|
||||
def stop_sales_order(self):
|
||||
self.check_modified_date()
|
||||
self.update_stock_ledger(update_stock = -1,clear = 1)
|
||||
# ::::::::: SET SO STATUS ::::::::::
|
||||
set(self.doc, 'status', 'Stopped')
|
||||
msgprint(self.doc.doctype + ": " + self.doc.name + " has been Stopped. To make transactions against this Sales Order you need to Unstop it.")
|
||||
|
||||
# UNSTOP SALES ORDER
|
||||
# ==============================================================================================
|
||||
# Unstops Sales Order & now transactions can be continued against this Sales Order
|
||||
def unstop_sales_order(self):
|
||||
self.check_modified_date()
|
||||
self.update_stock_ledger(update_stock = 1,clear = 1)
|
||||
# ::::::::: SET SO STATUS ::::::::::
|
||||
set(self.doc, 'status', 'Submitted')
|
||||
msgprint(self.doc.doctype + ": " + self.doc.name + " has been Unstopped.")
|
||||
|
||||
# UPDATE STOCK LEDGER
|
||||
# ===============================================================================================
|
||||
def update_stock_ledger(self, update_stock, clear = 0):
|
||||
for d in self.get_item_list(clear):
|
||||
stock_item = sql("SELECT is_stock_item FROM tabItem where name = '%s'"%(d['item_code']),as_dict = 1)
|
||||
# stock ledger will be updated only if it is a stock item
|
||||
if stock_item and stock_item[0]['is_stock_item'] == "Yes":
|
||||
if not d['reserved_warehouse']:
|
||||
msgprint("Message: Please enter Reserved Warehouse for item %s as it is stock item."% d['item_code'])
|
||||
raise Exception
|
||||
bin = get_obj('Warehouse', d['reserved_warehouse']).update_bin( 0, flt(update_stock) * flt(d['qty']), \
|
||||
0, 0, 0, d['item_code'], self.doc.transaction_date,doc_type=self.doc.doctype,\
|
||||
doc_name=self.doc.name, is_amended = (self.doc.amended_from and 'Yes' or 'No'))
|
||||
|
||||
# Gets Items from packing list
|
||||
#=================================
|
||||
def get_item_list(self, clear):
|
||||
return get_obj('Sales Common').get_item_list( self, clear)
|
||||
|
||||
# SET MESSAGE FOR SMS
|
||||
#======================
|
||||
def set_sms_msg(self, is_submitted = 0):
|
||||
if is_submitted:
|
||||
if not self.doc.amended_from:
|
||||
msg = 'Sales Order: '+self.doc.name+' has been made against PO no: '+cstr(self.doc.po_no)
|
||||
set(self.doc, 'message', msg)
|
||||
else:
|
||||
msg = 'Sales Order has been amended. New SO no:'+self.doc.name
|
||||
set(self.doc, 'message', msg)
|
||||
else:
|
||||
msg = 'Sales Order: '+self.doc.name+' has been cancelled.'
|
||||
set(self.doc, 'message', msg)
|
||||
|
||||
# SEND SMS
|
||||
# =========
|
||||
def send_sms(self):
|
||||
if not self.doc.customer_mobile_no:
|
||||
msgprint("Please enter customer mobile no")
|
||||
elif not self.doc.message:
|
||||
msgprint("Please enter the message you want to send")
|
||||
else:
|
||||
msgprint(get_obj("SMS Control", "SMS Control").send_sms([self.doc.customer_mobile_no,], self.doc.message))
|
||||
|
||||
# on update
|
||||
def on_update(self):
|
||||
pass
|
||||
|
||||
1375
selling/doctype/sales_order/sales_order.txt
Normal file
1375
selling/doctype/sales_order/sales_order.txt
Normal file
File diff suppressed because it is too large
Load Diff
50
selling/doctype/sales_order/sales_order_list.js
Normal file
50
selling/doctype/sales_order/sales_order_list.js
Normal file
@@ -0,0 +1,50 @@
|
||||
// render
|
||||
wn.doclistviews['Sales Order'] = wn.views.ListView.extend({
|
||||
init: function(d) {
|
||||
this._super(d)
|
||||
this.fields = this.fields.concat([
|
||||
"`tabSales Order`.customer_name",
|
||||
"`tabSales Order`.status",
|
||||
"`tabSales Order`.order_type",
|
||||
"ifnull(`tabSales Order`.per_delivered,0) as per_delivered",
|
||||
"ifnull(`tabSales Order`.per_billed,0) as per_billed",
|
||||
"`tabSales Order`.currency",
|
||||
"ifnull(`tabSales Order`.grand_total_export,0) as grand_total_export",
|
||||
"`tabSales Order`.transaction_date",
|
||||
]);
|
||||
this.stats = this.stats.concat(['status', 'order_type', 'company']);
|
||||
},
|
||||
|
||||
columns: [
|
||||
{width: '3%', content: 'check'},
|
||||
{width: '5%', content: 'avatar'},
|
||||
{width: '3%', content: 'docstatus'},
|
||||
{width: '15%', content: 'name'},
|
||||
{width: '29%', content: 'customer_name+tags', css: {color:'#222'}},
|
||||
{
|
||||
width: '18%',
|
||||
content: function(parent, data) {
|
||||
$(parent).html(data.currency + ' ' + fmt_money(data.grand_total_export))
|
||||
},
|
||||
css: {'text-align':'right'}
|
||||
},
|
||||
{
|
||||
width: '11%',
|
||||
content: function(parent, data, me) {
|
||||
var order_type = data.order_type.toLowerCase();
|
||||
|
||||
if (order_type === 'sales') {
|
||||
me.render_icon(parent, 'icon-tag', data.order_type);
|
||||
me.render_bar_graph(parent, data, 'per_delivered', 'Delivered');
|
||||
} else if (order_type === 'maintenance') {
|
||||
me.render_icon(parent, 'icon-wrench', data.order_type);
|
||||
}
|
||||
},
|
||||
},
|
||||
{width: '8%', content: 'per_billed', type:'bar-graph', label:'Billed'},
|
||||
{width: '12%', content:'transaction_date',
|
||||
css: {'text-align': 'right', 'color':'#777'},
|
||||
title: "Sales Order Date", type: "date"}
|
||||
]
|
||||
|
||||
});
|
||||
1
selling/doctype/sales_order_item/__init__.py
Normal file
1
selling/doctype/sales_order_item/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
444
selling/doctype/sales_order_item/sales_order_item.txt
Normal file
444
selling/doctype/sales_order_item/sales_order_item.txt
Normal file
@@ -0,0 +1,444 @@
|
||||
# DocType, Sales Order Item
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-06-08 16:07:58',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-07-09 11:05:16',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'autoname': u'SOD/.#####',
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Tray',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 1
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Sales Order Item',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# DocType, Sales Order Item
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Sales Order Item'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_code',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Item Code',
|
||||
'oldfieldname': u'item_code',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'trigger': u'Client',
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_item_code',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u"Customer's Item Code",
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_name',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Item Name',
|
||||
'oldfieldname': u'item_name',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 1,
|
||||
'width': u'150'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'description',
|
||||
'fieldtype': u'Small Text',
|
||||
'in_filter': 1,
|
||||
'label': u'Description',
|
||||
'oldfieldname': u'description',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'width': u'300px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Quantity',
|
||||
'oldfieldname': u'qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'reqd': 1,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'stock_uom',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 0,
|
||||
'label': u'UOM',
|
||||
'oldfieldname': u'stock_uom',
|
||||
'oldfieldtype': u'Data',
|
||||
'permlevel': 1,
|
||||
'reqd': 0,
|
||||
'width': u'70px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'ref_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Price List Rate',
|
||||
'oldfieldname': u'ref_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'70px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'adj_rate',
|
||||
'fieldtype': u'Float',
|
||||
'label': u'Discount(%)',
|
||||
'oldfieldname': u'adj_rate',
|
||||
'oldfieldtype': u'Float',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'trigger': u'Client',
|
||||
'width': u'70px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'export_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Rate',
|
||||
'oldfieldname': u'export_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'reqd': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'export_amount',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Amount',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'export_amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'reqd': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'base_ref_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Price List Rate*',
|
||||
'oldfieldname': u'base_ref_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'basic_rate',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Basic Rate*',
|
||||
'oldfieldname': u'basic_rate',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'amount',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Amount*',
|
||||
'no_copy': 0,
|
||||
'oldfieldname': u'amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'reserved_warehouse',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Reserved Warehouse',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'reserved_warehouse',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Warehouse',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'reqd': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'150px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'projected_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 1,
|
||||
'label': u'Projected Qty',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'projected_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'70px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'actual_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Actual Qty',
|
||||
'no_copy': 1,
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'width': u'70px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'default': u'0.00',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'delivered_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 0,
|
||||
'in_filter': 0,
|
||||
'label': u'Delivered Qty',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'delivered_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 0,
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'billed_amt',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Billed Amt',
|
||||
'no_copy': 1,
|
||||
'permlevel': 1,
|
||||
'print_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'For Production',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'planned_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 1,
|
||||
'label': u'Planned Quantity',
|
||||
'no_copy': 1,
|
||||
'oldfieldname': u'planned_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1,
|
||||
'width': u'50px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'For Production',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'produced_qty',
|
||||
'fieldtype': u'Currency',
|
||||
'hidden': 1,
|
||||
'label': u'Produced Quantity',
|
||||
'oldfieldname': u'produced_qty',
|
||||
'oldfieldtype': u'Currency',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1,
|
||||
'width': u'50px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'brand',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Brand Name',
|
||||
'oldfieldname': u'brand',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Brand',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_group',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Item Group',
|
||||
'oldfieldname': u'item_group',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Item Group',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'prevdoc_docname',
|
||||
'fieldtype': u'Link',
|
||||
'hidden': 0,
|
||||
'in_filter': 1,
|
||||
'label': u'Quotation No.',
|
||||
'oldfieldname': u'prevdoc_docname',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Quotation',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'allow_on_submit': 1,
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'page_break',
|
||||
'fieldtype': u'Check',
|
||||
'label': u'Page Break',
|
||||
'oldfieldname': u'page_break',
|
||||
'oldfieldtype': u'Check',
|
||||
'permlevel': 0,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'item_tax_rate',
|
||||
'fieldtype': u'Small Text',
|
||||
'hidden': 1,
|
||||
'label': u'Item Tax Rate',
|
||||
'oldfieldname': u'item_tax_rate',
|
||||
'oldfieldtype': u'Small Text',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'description': u'The date at which current entry is made in system.',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'transaction_date',
|
||||
'fieldtype': u'Date',
|
||||
'hidden': 1,
|
||||
'in_filter': 0,
|
||||
'label': u'Sales Order Date',
|
||||
'oldfieldname': u'transaction_date',
|
||||
'oldfieldtype': u'Date',
|
||||
'permlevel': 1,
|
||||
'print_hide': 1,
|
||||
'report_hide': 1,
|
||||
'search_index': 0
|
||||
}
|
||||
]
|
||||
1
selling/doctype/sales_team/__init__.py
Normal file
1
selling/doctype/sales_team/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
128
selling/doctype/sales_team/sales_team.txt
Normal file
128
selling/doctype/sales_team/sales_team.txt
Normal file
@@ -0,0 +1,128 @@
|
||||
# DocType, Sales Team
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:17',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:17',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'istable': 1,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'section_style': u'Tray',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 0,
|
||||
'version': 5
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Sales Team',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocType, Sales Team
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Sales Team'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'sales_person',
|
||||
'fieldtype': u'Link',
|
||||
'in_filter': 1,
|
||||
'label': u'Sales Person',
|
||||
'oldfieldname': u'sales_person',
|
||||
'oldfieldtype': u'Link',
|
||||
'options': u'Sales Person',
|
||||
'reqd': 1,
|
||||
'search_index': 1,
|
||||
'width': u'200px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'sales_designation',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Designation',
|
||||
'oldfieldname': u'sales_designation',
|
||||
'oldfieldtype': u'Data',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'contact_no',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'label': u'Contact No.',
|
||||
'oldfieldname': u'contact_no',
|
||||
'oldfieldtype': u'Data',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'allocated_percentage',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Allocated (%)',
|
||||
'oldfieldname': u'allocated_percentage',
|
||||
'oldfieldtype': u'Currency',
|
||||
'reqd': 0,
|
||||
'trigger': u'Client',
|
||||
'width': u'100px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'allocated_amount',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Allocated Amount',
|
||||
'oldfieldname': u'allocated_amount',
|
||||
'oldfieldtype': u'Currency',
|
||||
'reqd': 0,
|
||||
'width': u'120px'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'parenttype',
|
||||
'fieldtype': u'Data',
|
||||
'hidden': 1,
|
||||
'in_filter': 1,
|
||||
'label': u'Parenttype',
|
||||
'oldfieldname': u'parenttype',
|
||||
'oldfieldtype': u'Data',
|
||||
'print_hide': 1,
|
||||
'search_index': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'incentives',
|
||||
'fieldtype': u'Currency',
|
||||
'label': u'Incentives',
|
||||
'oldfieldname': u'incentives',
|
||||
'oldfieldtype': u'Currency'
|
||||
}
|
||||
]
|
||||
1
selling/doctype/shipping_address/__init__.py
Executable file
1
selling/doctype/shipping_address/__init__.py
Executable file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
20
selling/doctype/shipping_address/shipping_address.js
Executable file
20
selling/doctype/shipping_address/shipping_address.js
Executable file
@@ -0,0 +1,20 @@
|
||||
// ERPNext - web based ERP (http://erpnext.com)
|
||||
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Get Customer Details
|
||||
// =====================================================================
|
||||
cur_frm.add_fetch('customer','customer_name','customer_name');
|
||||
cur_frm.add_fetch('customer','address','customer_address');
|
||||
42
selling/doctype/shipping_address/shipping_address.py
Executable file
42
selling/doctype/shipping_address/shipping_address.py
Executable file
@@ -0,0 +1,42 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
sql = webnotes.conn.sql
|
||||
|
||||
class DocType:
|
||||
def __init__(self, d, dl):
|
||||
self.doc, self.doclist = d, dl
|
||||
|
||||
# on update
|
||||
# ----------
|
||||
def on_update(self):
|
||||
self.update_primary_shipping_address()
|
||||
self.get_customer_details()
|
||||
|
||||
# set is_primary_address for other shipping addresses belonging to same customer
|
||||
# -------------------------------------------------------------------------------
|
||||
def update_primary_shipping_address(self):
|
||||
if self.doc.is_primary_address == 'Yes':
|
||||
sql("update `tabShipping Address` set is_primary_address = 'No' where customer = %s and is_primary_address = 'Yes' and name != %s",(self.doc.customer, self.doc.name))
|
||||
|
||||
# Get Customer Details
|
||||
# ---------------------
|
||||
def get_customer_details(self):
|
||||
det = sql("select customer_name, address from tabCustomer where name = '%s'" % (self.doc.customer))
|
||||
self.doc.customer_name = det and det[0][0] or ''
|
||||
self.doc.customer_address = det and det[0][1] or ''
|
||||
181
selling/doctype/shipping_address/shipping_address.txt
Executable file
181
selling/doctype/shipping_address/shipping_address.txt
Executable file
@@ -0,0 +1,181 @@
|
||||
# DocType, Shipping Address
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:17',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:17',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'allow_trash': 1,
|
||||
'autoname': u'SA.#####',
|
||||
'colour': u'White:FFF',
|
||||
'doctype': 'DocType',
|
||||
'document_type': u'Master',
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'search_fields': u'customer, ship_to, shipping_address',
|
||||
'section_style': u'Simple',
|
||||
'show_in_menu': 0,
|
||||
'version': 8
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'Shipping Address',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType'
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'Shipping Address',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1
|
||||
},
|
||||
|
||||
# DocType, Shipping Address
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'Shipping Address'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Master Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales Master Manager'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'cancel': 1,
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'role': u'Sales Manager',
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'role': u'Sales Manager'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break0',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Customer',
|
||||
'options': u'Customer',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_name',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Customer Name',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer_address',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Customer Address',
|
||||
'permlevel': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'ship_to',
|
||||
'fieldtype': u'Data',
|
||||
'label': u'Ship To',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'shipping_address',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Shipping Address',
|
||||
'permlevel': 0,
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break1',
|
||||
'fieldtype': u'Column Break',
|
||||
'permlevel': 0,
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'is_primary_address',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Is Primary Address',
|
||||
'options': u'Yes\nNo',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'shipping_details',
|
||||
'fieldtype': u'Text Editor',
|
||||
'label': u'Shipping Details',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'trash_reason',
|
||||
'fieldtype': u'Small Text',
|
||||
'label': u'Trash Reason',
|
||||
'permlevel': 1
|
||||
}
|
||||
]
|
||||
1
selling/doctype/sms_center/__init__.py
Normal file
1
selling/doctype/sms_center/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
82
selling/doctype/sms_center/sms_center.py
Normal file
82
selling/doctype/sms_center/sms_center.py
Normal file
@@ -0,0 +1,82 @@
|
||||
# ERPNext - web based ERP (http://erpnext.com)
|
||||
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Please edit this list and import only required elements
|
||||
from __future__ import unicode_literals
|
||||
import webnotes
|
||||
|
||||
from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add
|
||||
from webnotes.model import db_exists
|
||||
from webnotes.model.doc import Document, addchild, getchildren, make_autoname
|
||||
from webnotes.model.doclist import getlist, copy_doclist
|
||||
from webnotes.model.code import get_obj, get_server_obj, run_server_obj, updatedb, check_syntax
|
||||
from webnotes import session, form, is_testing, msgprint, errprint
|
||||
|
||||
set = webnotes.conn.set
|
||||
sql = webnotes.conn.sql
|
||||
get_value = webnotes.conn.get_value
|
||||
in_transaction = webnotes.conn.in_transaction
|
||||
convert_to_lists = webnotes.conn.convert_to_lists
|
||||
|
||||
# -----------------------------------------------------------------------------------------
|
||||
# ----------
|
||||
|
||||
class DocType:
|
||||
def __init__(self, doc, doclist=[]):
|
||||
self.doc = doc
|
||||
self.doclist = doclist
|
||||
|
||||
def create_receiver_list(self):
|
||||
rec, where_clause = '', ''
|
||||
if self.doc.send_to == 'All Customer Contact':
|
||||
where_clause = self.doc.customer and " and customer = '%s'" % self.doc.customer or " and ifnull(is_customer, 0) = 1"
|
||||
if self.doc.send_to == 'All Supplier Contact':
|
||||
where_clause = self.doc.supplier and " and ifnull(is_supplier, 0) = 1 and supplier = '%s'" % self.doc.supplier or " and ifnull(is_supplier, 0) = 1"
|
||||
if self.doc.send_to == 'All Sales Partner Contact':
|
||||
where_clause = self.doc.sales_partner and " and ifnull(is_sales_partner, 0) = 1 and sales_aprtner = '%s'" % self.doc.sales_partner or " and ifnull(is_sales_partner, 0) = 1"
|
||||
if self.doc.send_to in ['All Contact', 'All Customer Contact', 'All Supplier Contact', 'All Sales Partner Contact']:
|
||||
rec = sql("select CONCAT(ifnull(first_name,''),'',ifnull(last_name,'')), mobile_no from `tabContact` where ifnull(mobile_no,'')!='' and docstatus != 2 %s" % where_clause)
|
||||
elif self.doc.send_to == 'All Lead (Open)':
|
||||
rec = sql("select lead_name, mobile_no from tabLead where ifnull(mobile_no,'')!='' and docstatus != 2 and status = 'Open'")
|
||||
elif self.doc.send_to == 'All Employee (Active)':
|
||||
where_clause = self.doc.department and " and t1.department = '%s'" % self.doc.department or ""
|
||||
where_clause += self.doc.branch and " and t1.branch = '%s'" % self.doc.branch or ""
|
||||
rec = sql("select t1.employee_name, t2.cell_number from `tabEmployee` t1, `tabEmployee Profile` t2 where t2.employee = t1.name and t1.status = 'Active' and t1.docstatus != 2 and ifnull(t2.cell_number,'')!='' %s" % where_clause)
|
||||
elif self.doc.send_to == 'All Sales Person':
|
||||
rec = sql("select sales_person_name, mobile_no from `tabSales Person` where docstatus != 2 and ifnull(mobile_no,'')!=''")
|
||||
|
||||
rec_list = ''
|
||||
for d in rec:
|
||||
rec_list += d[0] + ' - ' + d[1] + '\n'
|
||||
self.doc.receiver_list = rec_list
|
||||
|
||||
def get_receiver_nos(self):
|
||||
receiver_nos = []
|
||||
for d in self.doc.receiver_list.split('\n'):
|
||||
receiver_no = d
|
||||
if '-' in d:
|
||||
receiver_no = receiver_no.split('-')[1]
|
||||
if receiver_no.strip():
|
||||
receiver_nos.append(cstr(receiver_no).strip())
|
||||
return receiver_nos
|
||||
|
||||
def send_sms(self):
|
||||
if not self.doc.message:
|
||||
msgprint("Please enter message before sending")
|
||||
else:
|
||||
receiver_list = self.get_receiver_nos()
|
||||
if receiver_list:
|
||||
msgprint(get_obj('SMS Control', 'SMS Control').send_sms(receiver_list, cstr(self.doc.message)))
|
||||
185
selling/doctype/sms_center/sms_center.txt
Normal file
185
selling/doctype/sms_center/sms_center.txt
Normal file
@@ -0,0 +1,185 @@
|
||||
# DocType, SMS Center
|
||||
[
|
||||
|
||||
# These values are common in all dictionaries
|
||||
{
|
||||
'creation': '2012-03-27 14:36:17',
|
||||
'docstatus': 0,
|
||||
'modified': '2012-03-27 14:36:17',
|
||||
'modified_by': u'Administrator',
|
||||
'owner': u'Administrator'
|
||||
},
|
||||
|
||||
# These values are common for all DocType
|
||||
{
|
||||
'_last_update': u'1322549700',
|
||||
'allow_attach': 0,
|
||||
'allow_copy': 1,
|
||||
'allow_email': 1,
|
||||
'allow_print': 1,
|
||||
'colour': u'White:FFF',
|
||||
'default_print_format': u'Standard',
|
||||
'doctype': 'DocType',
|
||||
'hide_heading': 0,
|
||||
'hide_toolbar': 0,
|
||||
'in_create': 0,
|
||||
'issingle': 1,
|
||||
'menu_index': 4,
|
||||
'module': u'Selling',
|
||||
'name': '__common__',
|
||||
'read_only': 1,
|
||||
'section_style': u'Simple',
|
||||
'server_code_error': u' ',
|
||||
'show_in_menu': 1,
|
||||
'version': 41
|
||||
},
|
||||
|
||||
# These values are common for all DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'name': '__common__',
|
||||
'parent': u'SMS Center',
|
||||
'parentfield': u'fields',
|
||||
'parenttype': u'DocType',
|
||||
'permlevel': 0
|
||||
},
|
||||
|
||||
# These values are common for all DocPerm
|
||||
{
|
||||
'doctype': u'DocPerm',
|
||||
'name': '__common__',
|
||||
'parent': u'SMS Center',
|
||||
'parentfield': u'permissions',
|
||||
'parenttype': u'DocType',
|
||||
'read': 1,
|
||||
'role': u'System Manager'
|
||||
},
|
||||
|
||||
# DocType, SMS Center
|
||||
{
|
||||
'doctype': 'DocType',
|
||||
'name': u'SMS Center'
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 1,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 0,
|
||||
'write': 1
|
||||
},
|
||||
|
||||
# DocPerm
|
||||
{
|
||||
'create': 0,
|
||||
'doctype': u'DocPerm',
|
||||
'permlevel': 1,
|
||||
'write': 0
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break1',
|
||||
'fieldtype': u'Column Break',
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'send_to',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Send To',
|
||||
'options': u'\nAll Contact\nAll Customer Contact\nAll Supplier Contact\nAll Sales Partner Contact\nAll Lead (Open)\nAll Employee (Active)\nAll Sales Person',
|
||||
'trigger': u'Client'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u"eval:doc.send_to=='All Customer Contact'",
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'customer',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Customer',
|
||||
'options': u'Customer'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u"eval:doc.send_to=='All Supplier Contact'",
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'supplier',
|
||||
'fieldtype': u'Link',
|
||||
'label': u'Supplier',
|
||||
'options': u'Supplier'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u"eval:doc.send_to=='All Employee (Active)'",
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'department',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Department',
|
||||
'options': u'link:Department'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'colour': u'White:FFF',
|
||||
'depends_on': u"eval:doc.send_to=='All Employee (Active)'",
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'branch',
|
||||
'fieldtype': u'Select',
|
||||
'label': u'Branch',
|
||||
'options': u'link:Branch'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'create_receiver_list',
|
||||
'fieldtype': u'Button',
|
||||
'label': u'Create Receiver List',
|
||||
'options': u'create_receiver_list'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'receiver_list',
|
||||
'fieldtype': u'Code',
|
||||
'label': u'Receiver List'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'column_break9',
|
||||
'fieldtype': u'Column Break',
|
||||
'width': u'50%'
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'description': u'Message greater than 160 character will be splitted into multiple mesage',
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'message',
|
||||
'fieldtype': u'Text',
|
||||
'label': u'Message',
|
||||
'reqd': 1
|
||||
},
|
||||
|
||||
# DocField
|
||||
{
|
||||
'doctype': u'DocField',
|
||||
'fieldname': u'send_sms',
|
||||
'fieldtype': u'Button',
|
||||
'label': u'Send SMS',
|
||||
'options': u'send_sms'
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user