moved directory structure

This commit is contained in:
Rushabh Mehta
2012-09-24 19:13:42 +05:30
parent e47a6779e9
commit 2fa2f7178d
1637 changed files with 47 additions and 11450 deletions

View File

@@ -0,0 +1 @@
from __future__ import unicode_literals

View 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);
}

View 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()

File diff suppressed because it is too large Load Diff

View 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"}
]
});