mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-24 23:49:19 +00:00
Merge branch 'responsive' of github.com:webnotes/erpnext into responsive
Conflicts: selling/doctype/lead/lead.txt
This commit is contained in:
@@ -32,6 +32,7 @@ cur_frm.add_fetch('lead_name', 'company_name', 'customer_name');
|
||||
cur_frm.add_fetch('default_sales_partner','commission_rate','default_commission_rate');
|
||||
|
||||
cur_frm.cscript.refresh = function(doc,dt,dn) {
|
||||
cur_frm.cscript.setup_dashboard(doc);
|
||||
if(sys_defaults.cust_master_name == 'Customer Name')
|
||||
hide_field('naming_series');
|
||||
else
|
||||
@@ -39,7 +40,7 @@ cur_frm.cscript.refresh = function(doc,dt,dn) {
|
||||
|
||||
if(doc.__islocal){
|
||||
hide_field(['address_html','contact_html']);
|
||||
}else{
|
||||
}else{
|
||||
unhide_field(['address_html','contact_html']);
|
||||
// make lists
|
||||
cur_frm.cscript.make_address(doc,dt,dn);
|
||||
@@ -53,6 +54,36 @@ cur_frm.cscript.refresh = function(doc,dt,dn) {
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.cscript.setup_dashboard = function(doc) {
|
||||
cur_frm.dashboard.reset(doc);
|
||||
if(doc.__islocal)
|
||||
return;
|
||||
cur_frm.dashboard.set_headline('<span class="text-muted">Loading...</span>')
|
||||
|
||||
cur_frm.dashboard.add_doctype_badge("Opportunity", "customer");
|
||||
cur_frm.dashboard.add_doctype_badge("Quotation", "customer");
|
||||
cur_frm.dashboard.add_doctype_badge("Sales Order", "customer");
|
||||
cur_frm.dashboard.add_doctype_badge("Delivery Note", "customer");
|
||||
cur_frm.dashboard.add_doctype_badge("Sales Invoice", "customer");
|
||||
|
||||
wn.call({
|
||||
type: "GET",
|
||||
method:"selling.doctype.customer.customer.get_dashboard_info",
|
||||
args: {
|
||||
customer: cur_frm.doc.name
|
||||
},
|
||||
callback: function(r) {
|
||||
cur_frm.dashboard.set_headline(
|
||||
wn._("Total Billing This Year: ") + "<b>"
|
||||
+ format_currency(r.message.total_billing, cur_frm.doc.default_currency)
|
||||
+ '</b> / <span class="text-muted">' + wn._("Unpaid") + ": <b>"
|
||||
+ format_currency(r.message.total_unpaid, cur_frm.doc.default_currency)
|
||||
+ '</b></span>');
|
||||
cur_frm.dashboard.set_badge_count(r.message);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
cur_frm.cscript.make_address = function() {
|
||||
if(!cur_frm.address_list) {
|
||||
cur_frm.address_list = new wn.ui.Listing({
|
||||
@@ -95,4 +126,4 @@ cur_frm.fields_dict['customer_group'].get_query = function(doc,dt,dn) {
|
||||
}
|
||||
|
||||
|
||||
cur_frm.fields_dict.lead_name.get_query = erpnext.utils.lead_query;
|
||||
cur_frm.fields_dict.lead_name.get_query = erpnext.utils.lead_query;
|
||||
@@ -173,4 +173,25 @@ class DocType(TransactionBase):
|
||||
|
||||
#update master_name in doctype account
|
||||
webnotes.conn.sql("""update `tabAccount` set master_name = %s,
|
||||
master_type = 'Customer' where master_name = %s""", (new,old))
|
||||
master_type = 'Customer' where master_name = %s""", (new,old))
|
||||
|
||||
@webnotes.whitelist()
|
||||
def get_dashboard_info(customer):
|
||||
if not webnotes.has_permission("Customer", customer):
|
||||
webnotes.msgprint("No Permission", raise_exception=True)
|
||||
|
||||
out = {}
|
||||
for doctype in ["Opportunity", "Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]:
|
||||
out[doctype] = webnotes.conn.get_value(doctype,
|
||||
{"customer": customer, "docstatus": ["!=", 2] }, "count(*)")
|
||||
|
||||
billing = webnotes.conn.sql("""select sum(grand_total), sum(outstanding_amount)
|
||||
from `tabSales Invoice`
|
||||
where customer=%s
|
||||
and docstatus = 1
|
||||
and fiscal_year = %s""", (customer, webnotes.conn.get_default("fiscal_year")))
|
||||
|
||||
out["total_billing"] = billing[0][0]
|
||||
out["total_unpaid"] = billing[0][1]
|
||||
|
||||
return out
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"creation": "2013-06-11 14:26:44",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-06-11 14:27:57",
|
||||
"modified": "2013-07-03 10:26:04",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -43,6 +43,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Basic Info",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-user",
|
||||
"permlevel": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
@@ -142,6 +143,7 @@
|
||||
"fieldname": "address_contacts",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Address & Contacts",
|
||||
"options": "icon-map-marker",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
@@ -190,6 +192,8 @@
|
||||
"doctype": "DocField",
|
||||
"fieldname": "communication_history",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Communication History",
|
||||
"options": "icon-comments",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
@@ -205,6 +209,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "More Info",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-file-text",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
@@ -295,6 +300,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Sales Team",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-group",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
|
||||
@@ -40,9 +40,19 @@ erpnext.LeadController = wn.ui.form.Controller.extend({
|
||||
},
|
||||
|
||||
refresh: function() {
|
||||
var doc = this.frm.doc;
|
||||
erpnext.hide_naming_series();
|
||||
this.frm.clear_custom_buttons();
|
||||
|
||||
this.frm.dashboard.reset(doc);
|
||||
if(!doc.__islocal) {
|
||||
if(doc.status=="Converted") {
|
||||
this.frm.dashboard.set_headline_alert(wn._("Converted"), "alert-success", "icon-ok-sign");
|
||||
} else {
|
||||
this.frm.dashboard.set_headline_alert(wn._(doc.status), "alert-info", "icon-exclamation-sign");
|
||||
}
|
||||
}
|
||||
|
||||
this.frm.__is_customer = this.frm.__is_customer || this.frm.doc.__is_customer;
|
||||
if(!this.frm.doc.__islocal && !this.frm.__is_customer) {
|
||||
this.frm.add_custom_button("Create Customer", this.frm.cscript['Create Customer']);
|
||||
@@ -89,63 +99,15 @@ erpnext.LeadController = wn.ui.form.Controller.extend({
|
||||
$.extend(cur_frm.cscript, new erpnext.LeadController({frm: cur_frm}));
|
||||
|
||||
cur_frm.cscript['Create Customer'] = function(){
|
||||
var doc = cur_frm.doc;
|
||||
$c('runserverobj',args={ 'method':'check_status', 'docs':wn.model.compress(make_doclist(doc.doctype, doc.name))},
|
||||
function(r,rt){
|
||||
if(r.message == 'Converted'){
|
||||
msgprint("This lead is already converted to customer");
|
||||
}
|
||||
else{
|
||||
n = wn.model.make_new_doc_and_get_name("Customer");
|
||||
$c('dt_map', args={
|
||||
'docs':wn.model.compress([locals["Customer"][n]]),
|
||||
'from_doctype':'Lead',
|
||||
'to_doctype':'Customer',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Lead', 'Customer']]"
|
||||
},
|
||||
function(r,rt) {
|
||||
wn.model.with_doctype("Customer", function() {
|
||||
var customer = wn.model.get_doc("Customer", n);
|
||||
var customer_copy = $.extend({}, customer);
|
||||
|
||||
var updated = wn.model.set_default_values(customer_copy);
|
||||
$.each(updated, function(i, f) {
|
||||
if(!customer[f]) customer[f] = customer_copy[f];
|
||||
});
|
||||
|
||||
loaddoc("Customer", n);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
wn.model.open_mapped_doc({
|
||||
method: "selling.doctype.lead.lead.make_customer",
|
||||
source_name: cur_frm.doc.name
|
||||
})
|
||||
}
|
||||
|
||||
// Create New Opportunity
|
||||
// ===============================================================
|
||||
cur_frm.cscript['Create Opportunity'] = function(){
|
||||
var doc = cur_frm.doc;
|
||||
$c('runserverobj',args={ 'method':'check_status', 'docs':wn.model.compress(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 = wn.model.make_new_doc_and_get_name("Opportunity");
|
||||
$c('dt_map', args={
|
||||
'docs':wn.model.compress([locals["Opportunity"][n]]),
|
||||
'from_doctype':'Lead',
|
||||
'to_doctype':'Opportunity',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Lead', 'Opportunity']]"
|
||||
}
|
||||
, function(r,rt) {
|
||||
loaddoc("Opportunity", n);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
wn.model.open_mapped_doc({
|
||||
method: "selling.doctype.lead.lead.make_opportunity",
|
||||
source_name: cur_frm.doc.name
|
||||
})
|
||||
}
|
||||
@@ -95,4 +95,37 @@ class DocType(SellingController):
|
||||
webnotes.conn.sql("""update `tabSupport Ticket` set lead='' where lead=%s""",
|
||||
self.doc.name)
|
||||
|
||||
self.delete_events()
|
||||
self.delete_events()
|
||||
|
||||
@webnotes.whitelist()
|
||||
def make_customer(source_name, target_doclist=None):
|
||||
from webnotes.model.mapper import get_mapped_doclist
|
||||
|
||||
doclist = get_mapped_doclist("Lead", source_name,
|
||||
{"Lead": {
|
||||
"doctype": "Customer",
|
||||
"field_map": {
|
||||
"name": "lead_name",
|
||||
"company_name": "customer_name",
|
||||
"contact_no": "phone_1",
|
||||
"fax": "fax_1"
|
||||
}
|
||||
}}, target_doclist)
|
||||
|
||||
return [d.fields for d in doclist]
|
||||
|
||||
@webnotes.whitelist()
|
||||
def make_opportunity(source_name, target_doclist=None):
|
||||
from webnotes.model.mapper import get_mapped_doclist
|
||||
|
||||
doclist = get_mapped_doclist("Lead", source_name,
|
||||
{"Lead": {
|
||||
"doctype": "Opportunity",
|
||||
"field_map": {
|
||||
"campaign_name": "campaign",
|
||||
"doctype": "enquiry_from",
|
||||
"name": "lead",
|
||||
}
|
||||
}}, target_doclist)
|
||||
|
||||
return [d.fields for d in doclist]
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"creation": "2013-04-10 11:45:37",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-07-02 16:03:50",
|
||||
"modified": "2013-07-03 10:24:00",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -40,6 +40,13 @@
|
||||
"doctype": "DocType",
|
||||
"name": "Lead"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "lead_details",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Lead Details",
|
||||
"options": "icon-user"
|
||||
},
|
||||
{
|
||||
"description": "To manage multiple series please go to Setup > Manage Series",
|
||||
"doctype": "DocField",
|
||||
@@ -149,7 +156,9 @@
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "communication_history",
|
||||
"fieldtype": "Section Break"
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Communication History",
|
||||
"options": "icon-comments"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
@@ -165,7 +174,8 @@
|
||||
"fieldname": "contact_info",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Address & Contact",
|
||||
"oldfieldtype": "Column Break"
|
||||
"oldfieldtype": "Column Break",
|
||||
"options": "icon-map-marker"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.__islocal",
|
||||
@@ -248,7 +258,8 @@
|
||||
"fieldname": "more_info",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "More Info",
|
||||
"oldfieldtype": "Section Break"
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-file-text"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
test_records = [
|
||||
[{"doctype":"Lead", "lead_name": "_Test Lead", "status":"Open",
|
||||
"email_id":"test_lead@example.com"}],
|
||||
@@ -8,3 +10,17 @@ test_records = [
|
||||
[{"doctype":"Lead", "lead_name": "_Test Lead 3", "status":"Converted",
|
||||
"email_id":"test_lead3@example.com"}],
|
||||
]
|
||||
|
||||
import webnotes
|
||||
import unittest
|
||||
|
||||
class TestLead(unittest.TestCase):
|
||||
def test_make_customer(self):
|
||||
from selling.doctype.lead.lead import make_customer
|
||||
|
||||
customer = make_customer("_T-Lead-00001")
|
||||
self.assertEquals(customer[0]["doctype"], "Customer")
|
||||
self.assertEquals(customer[0]["lead_name"], "_T-Lead-00001")
|
||||
|
||||
webnotes.bean(customer).insert()
|
||||
|
||||
@@ -42,9 +42,18 @@ $.extend(cur_frm.cscript, new erpnext.selling.Opportunity({frm: cur_frm}));
|
||||
|
||||
cur_frm.cscript.refresh = function(doc, cdt, cdn){
|
||||
erpnext.hide_naming_series();
|
||||
|
||||
cur_frm.dashboard.reset(doc);
|
||||
if(!doc.__islocal) {
|
||||
if(doc.status=="Converted" || doc.status=="Order Confirmed") {
|
||||
cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-success", "icon-ok-sign");
|
||||
} else if(doc.status=="Opportunity Lost") {
|
||||
cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-danger", "icon-exclamation-sign");
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.clear_custom_buttons();
|
||||
if(doc.docstatus == 1) {
|
||||
if(doc.docstatus === 1 && doc.status!=="Opportunity Lost") {
|
||||
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);
|
||||
@@ -58,11 +67,21 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn){
|
||||
// ===============================================================
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
|
||||
if(!doc.enquiry_from) hide_field(['customer', 'customer_address', 'contact_person', 'customer_name','lead', '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 && doc.customer)
|
||||
doc.enquiry_from = "Customer";
|
||||
if(!doc.enquiry_from && doc.lead)
|
||||
doc.enquiry_from = "Lead";
|
||||
|
||||
if(!doc.enquiry_from)
|
||||
hide_field(['customer', 'customer_address', 'contact_person', 'customer_name','lead', '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') {
|
||||
@@ -85,6 +104,8 @@ cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
if(cur_frm.fields_dict.contact_by.df.options.match(/^Profile/)) {
|
||||
cur_frm.fields_dict.contact_by.get_query = erpnext.utils.profile_query;
|
||||
}
|
||||
|
||||
if(doc.customer && !doc.customer_name) cur_frm.cscript.customer(doc);
|
||||
}
|
||||
|
||||
cur_frm.cscript.onload_post_render = function(doc, cdt, cdn) {
|
||||
@@ -196,56 +217,35 @@ cur_frm.cscript['Create Quotation'] = function(){
|
||||
// declare enquiry lost
|
||||
//-------------------------
|
||||
cur_frm.cscript['Declare Opportunity Lost'] = function(){
|
||||
var e_lost_dialog;
|
||||
var dialog = new wn.ui.Dialog({
|
||||
title: "Set as Lost",
|
||||
fields: [
|
||||
{"fieldtype": "Text", "label": "Reason for losing", "fieldname": "reason",
|
||||
"reqd": 1 },
|
||||
{"fieldtype": "Button", "label": "Update", "fieldname": "update"},
|
||||
]
|
||||
});
|
||||
|
||||
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();
|
||||
cur_frm.refresh();
|
||||
dialog.fields_dict.update.$input.click(function() {
|
||||
args = dialog.get_values();
|
||||
if(!args) return;
|
||||
cur_frm.call({
|
||||
doc: cur_frm.doc,
|
||||
method: "declare_enquiry_lost",
|
||||
args: args.reason,
|
||||
callback: function(r) {
|
||||
if(r.exc) {
|
||||
msgprint("There were errors.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
dialog.hide();
|
||||
cur_frm.refresh();
|
||||
},
|
||||
btn: this
|
||||
})
|
||||
});
|
||||
dialog.show();
|
||||
|
||||
if(!e_lost_dialog){
|
||||
set_e_lost_dialog();
|
||||
}
|
||||
e_lost_dialog.show();
|
||||
}
|
||||
|
||||
//get query select Territory
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"creation": "2013-03-07 18:50:30",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-06-11 16:03:41",
|
||||
"modified": "2013-07-03 10:29:20",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -43,6 +43,13 @@
|
||||
"doctype": "DocType",
|
||||
"name": "Opportunity"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "from_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "From",
|
||||
"options": "icon-user"
|
||||
},
|
||||
{
|
||||
"description": "To manage multiple series please go to Setup > Manage Series",
|
||||
"doctype": "DocField",
|
||||
@@ -138,6 +145,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Items",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-shopping-cart",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
@@ -156,7 +164,9 @@
|
||||
"doctype": "DocField",
|
||||
"fieldname": "communication_history",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Communication History",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-comments",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
@@ -174,6 +184,7 @@
|
||||
"fieldname": "contact_info",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Contact Info",
|
||||
"options": "icon-bullhorn",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
@@ -278,6 +289,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "More Info",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-file-text",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
|
||||
@@ -26,12 +26,31 @@ wn.require('app/utilities/doctype/sms_control/sms_control.js');
|
||||
wn.require('app/selling/doctype/sales_common/sales_common.js');
|
||||
|
||||
erpnext.selling.QuotationController = erpnext.selling.SellingController.extend({
|
||||
onload: function(doc, dt, dn) {
|
||||
this._super(doc, dt, dn);
|
||||
if(doc.customer && !doc.quotation_to)
|
||||
doc.quotation_to = "Customer";
|
||||
else if(doc.lead && !doc.quotation_to)
|
||||
doc.quotation_to = "Lead";
|
||||
|
||||
},
|
||||
refresh: function(doc, dt, dn) {
|
||||
this._super();
|
||||
this._super(doc, dt, dn);
|
||||
|
||||
cur_frm.dashboard.reset(doc);
|
||||
if(!doc.__islocal) {
|
||||
if(doc.status=="Converted" || doc.status=="Order Confirmed") {
|
||||
cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-success", "icon-ok-sign");
|
||||
} else if(doc.status==="Order Lost") {
|
||||
cur_frm.dashboard.set_headline_alert(wn._(doc.status), "alert-danger", "icon-exclamation-sign");
|
||||
}
|
||||
}
|
||||
|
||||
if(doc.docstatus == 1 && doc.status!='Order Lost') {
|
||||
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']);
|
||||
if(doc.status!=="Order Confirmed") {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -108,20 +127,10 @@ cur_frm.fields_dict['enq_no'].get_query = function(doc,cdt,cdn){
|
||||
// Make Sales Order
|
||||
// =====================================================================================
|
||||
cur_frm.cscript['Make Sales Order'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
|
||||
if (doc.docstatus == 1) {
|
||||
var n = wn.model.make_new_doc_and_get_name("Sales Order");
|
||||
$c('dt_map', args={
|
||||
'docs':wn.model.compress([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);
|
||||
});
|
||||
}
|
||||
wn.model.open_mapped_doc({
|
||||
method: "selling.doctype.quotation.quotation.make_sales_order",
|
||||
source_name: cur_frm.doc.name
|
||||
})
|
||||
}
|
||||
|
||||
//pull enquiry details
|
||||
@@ -150,51 +159,35 @@ cur_frm.cscript.pull_enquiry_detail = function(doc,cdt,cdn){
|
||||
// declare order lost
|
||||
//-------------------------
|
||||
cur_frm.cscript['Declare Order Lost'] = function(){
|
||||
var qtn_lost_dialog;
|
||||
var dialog = new wn.ui.Dialog({
|
||||
title: "Set as Lost",
|
||||
fields: [
|
||||
{"fieldtype": "Text", "label": "Reason for losing", "fieldname": "reason",
|
||||
"reqd": 1 },
|
||||
{"fieldtype": "Button", "label": "Update", "fieldname": "update"},
|
||||
]
|
||||
});
|
||||
|
||||
set_qtn_lost_dialog = function(){
|
||||
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();
|
||||
cur_frm.refresh();
|
||||
dialog.fields_dict.update.$input.click(function() {
|
||||
args = dialog.get_values();
|
||||
if(!args) return;
|
||||
cur_frm.call({
|
||||
method: "declare_order_lost",
|
||||
doc: cur_frm.doc,
|
||||
args: args.reason,
|
||||
callback: function(r) {
|
||||
if(r.exc) {
|
||||
msgprint("There were errors.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
qtn_lost_dialog.show();
|
||||
dialog.hide();
|
||||
cur_frm.refresh();
|
||||
},
|
||||
btn: this
|
||||
})
|
||||
});
|
||||
dialog.show();
|
||||
|
||||
}
|
||||
|
||||
//================ Last Quoted Price and Last Sold Price suggestion ======================
|
||||
|
||||
@@ -154,8 +154,11 @@ class DocType(SellingController):
|
||||
super(DocType, self).validate()
|
||||
|
||||
import utilities
|
||||
utilities.validate_status(self.doc.status, ["Draft", "Submitted",
|
||||
"Order Confirmed", "Order Lost", "Cancelled"])
|
||||
if not self.doc.status:
|
||||
self.doc.status = "Draft"
|
||||
else:
|
||||
utilities.validate_status(self.doc.status, ["Draft", "Submitted",
|
||||
"Order Confirmed", "Order Lost", "Cancelled"])
|
||||
|
||||
self.validate_fiscal_year()
|
||||
self.set_last_contact_date()
|
||||
@@ -191,7 +194,7 @@ class DocType(SellingController):
|
||||
|
||||
# declare as order lost
|
||||
#-------------------------
|
||||
def declare_order_lost(self,arg):
|
||||
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.")
|
||||
@@ -247,3 +250,37 @@ class DocType(SellingController):
|
||||
sql("delete from `tabCommunication Log` where parent = '%s'"%self.doc.name)
|
||||
for d in getlist(self.doclist, 'follow_up'):
|
||||
d.save()
|
||||
|
||||
@webnotes.whitelist()
|
||||
def make_sales_order(source_name, target_doclist=None):
|
||||
from webnotes.model.mapper import get_mapped_doclist
|
||||
|
||||
if target_doclist:
|
||||
target_doclist = json.loads(target_doclist)
|
||||
|
||||
doclist = get_mapped_doclist("Quotation", source_name, {
|
||||
"Quotation": {
|
||||
"doctype": "Sales Order",
|
||||
"field_map": {
|
||||
"name": "quotation_no",
|
||||
"transaction_date": "quotation_date"
|
||||
},
|
||||
"validation": {
|
||||
"docstatus": ["=", 1]
|
||||
}
|
||||
},
|
||||
"Quotation Item": {
|
||||
"doctype": "Sales Order Item",
|
||||
"field_map": {
|
||||
"parent": "prevdoc_docname"
|
||||
}
|
||||
},
|
||||
"Sales Taxes and Charges": {
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
},
|
||||
"Sales Team": {
|
||||
"doctype": "Sales Team",
|
||||
}
|
||||
}, target_doclist)
|
||||
|
||||
return [d.fields for d in doclist]
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"creation": "2013-05-24 19:29:08",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-06-28 12:47:10",
|
||||
"modified": "2013-07-04 10:56:10",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -42,6 +42,13 @@
|
||||
"doctype": "DocType",
|
||||
"name": "Quotation"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "customer_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Customer",
|
||||
"options": "icon-user"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "column_break0",
|
||||
@@ -107,21 +114,19 @@
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "customer",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "customer_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"in_list_view": 1,
|
||||
"label": "Customer Name",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "customer",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "address_display",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"in_filter": 0,
|
||||
"label": "Address",
|
||||
"oldfieldname": "customer_address",
|
||||
@@ -132,32 +137,29 @@
|
||||
"search_index": 0
|
||||
},
|
||||
{
|
||||
"depends_on": "customer",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "contact_display",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"in_filter": 0,
|
||||
"label": "Contact",
|
||||
"print_hide": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "customer",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "contact_mobile",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"label": "Mobile No",
|
||||
"print_hide": 0,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "customer",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "contact_email",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"label": "Contact Email",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
@@ -234,6 +236,7 @@
|
||||
"fieldname": "section_break0",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Price List and Currency",
|
||||
"options": "icon-tag",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
@@ -316,6 +319,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Items",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-shopping-cart",
|
||||
"print_hide": 0,
|
||||
"read_only": 0,
|
||||
"search_index": 0
|
||||
@@ -337,7 +341,6 @@
|
||||
"doctype": "DocField",
|
||||
"fieldname": "sec_break23",
|
||||
"fieldtype": "Section Break",
|
||||
"options": "Simple",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
@@ -413,6 +416,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Taxes",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-money",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
@@ -512,6 +516,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Totals",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-money",
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
@@ -612,6 +617,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Terms and Conditions",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-legal",
|
||||
"print_hide": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
@@ -659,6 +665,7 @@
|
||||
"fieldname": "contact_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Contact Info",
|
||||
"options": "icon-bullhorn",
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
@@ -748,6 +755,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "More Info",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-file-text",
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
@@ -874,8 +882,9 @@
|
||||
"doctype": "DocField",
|
||||
"fieldname": "communication_history",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Communication History",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "Simple",
|
||||
"options": "icon-comments",
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
|
||||
63
selling/doctype/quotation/test_quotation.py
Normal file
63
selling/doctype/quotation/test_quotation.py
Normal file
@@ -0,0 +1,63 @@
|
||||
import webnotes, json
|
||||
from webnotes.utils import flt
|
||||
import unittest
|
||||
|
||||
test_dependencies = ["Sales BOM"]
|
||||
|
||||
class TestQuotation(unittest.TestCase):
|
||||
def test_make_sales_order(self):
|
||||
from selling.doctype.quotation.quotation import make_sales_order
|
||||
|
||||
self.assertRaises(webnotes.ValidationError, make_sales_order, "_T-Quotation-00001")
|
||||
|
||||
quotation = webnotes.bean("Quotation","_T-Quotation-00001")
|
||||
quotation.submit()
|
||||
|
||||
sales_order = make_sales_order("_T-Quotation-00001")
|
||||
|
||||
self.assertEquals(sales_order[0]["doctype"], "Sales Order")
|
||||
self.assertEquals(len(sales_order), 2)
|
||||
self.assertEquals(sales_order[1]["doctype"], "Sales Order Item")
|
||||
self.assertEquals(sales_order[1]["prevdoc_docname"], "_T-Quotation-00001")
|
||||
self.assertEquals(sales_order[0]["customer"], "_Test Customer")
|
||||
|
||||
sales_order[0]["delivery_date"] = "2014-01-01"
|
||||
|
||||
|
||||
webnotes.print_messages = True
|
||||
webnotes.bean(sales_order).insert()
|
||||
|
||||
|
||||
test_records = [
|
||||
[
|
||||
{
|
||||
"company": "_Test Company",
|
||||
"conversion_rate": 1.0,
|
||||
"currency": "INR",
|
||||
"customer": "_Test Customer",
|
||||
"customer_name": "_Test Customer",
|
||||
"customer_group": "_Test Customer Group",
|
||||
"doctype": "Quotation",
|
||||
"fiscal_year": "_Test Fiscal Year 2013",
|
||||
"order_type": "Sales",
|
||||
"plc_conversion_rate": 1.0,
|
||||
"price_list_currency": "INR",
|
||||
"price_list_name": "_Test Price List",
|
||||
"territory": "_Test Territory",
|
||||
"transaction_date": "2013-02-21",
|
||||
"grand_total": 1000.0,
|
||||
"grand_total_export": 1000.0,
|
||||
},
|
||||
{
|
||||
"description": "CPU",
|
||||
"doctype": "Quotation Item",
|
||||
"item_code": "_Test Item Home Desktop 100",
|
||||
"item_name": "CPU",
|
||||
"parentfield": "quotation_details",
|
||||
"qty": 10.0,
|
||||
"basic_rate": 100.0,
|
||||
"export_rate": 100.0,
|
||||
"amount": 1000.0,
|
||||
}
|
||||
],
|
||||
]
|
||||
@@ -105,6 +105,12 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
this.toggle_rounded_total();
|
||||
},
|
||||
|
||||
refresh: function(doc) {
|
||||
this.frm.toggle_display("customer_name",
|
||||
(this.customer_name && this.frm.doc.customer_name!==this.frm.doc.customer));
|
||||
this._super();
|
||||
},
|
||||
|
||||
customer: function() {
|
||||
var me = this;
|
||||
if(this.frm.doc.customer || this.frm.doc.debit_to) {
|
||||
@@ -592,4 +598,4 @@ var set_sales_bom_help = function(doc) {
|
||||
}
|
||||
}
|
||||
refresh_field('sales_bom_help');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,16 @@ wn.require('app/utilities/doctype/sms_control/sms_control.js');
|
||||
erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend({
|
||||
refresh: function(doc, dt, dn) {
|
||||
this._super();
|
||||
this.frm.dashboard.reset();
|
||||
|
||||
if(doc.docstatus==1) {
|
||||
if(doc.status != 'Stopped') {
|
||||
|
||||
cur_frm.dashboard.add_progress(cint(doc.per_delivered) + wn._("% Delivered"),
|
||||
doc.per_delivered);
|
||||
cur_frm.dashboard.add_progress(cint(doc.per_delivered) + wn._("% Billed"),
|
||||
doc.per_billed);
|
||||
|
||||
cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms);
|
||||
// delivery note
|
||||
if(flt(doc.per_delivered, 2) < 100 && doc.order_type=='Sales')
|
||||
@@ -56,6 +63,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
|
||||
cur_frm.add_custom_button('Stop!', cur_frm.cscript['Stop Sales Order']);
|
||||
} else {
|
||||
// un-stop
|
||||
cur_frm.dashboard.set_headline_alert("Stopped", "alert-danger", "icon-stop");
|
||||
cur_frm.add_custom_button('Unstop', cur_frm.cscript['Unstop Sales Order']);
|
||||
}
|
||||
}
|
||||
@@ -187,40 +195,18 @@ cur_frm.cscript.make_maintenance_visit = function() {
|
||||
}
|
||||
|
||||
cur_frm.cscript['Make Material Request'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
if (doc.docstatus == 1) {
|
||||
n = wn.model.make_new_doc_and_get_name("Material Request");
|
||||
$c('dt_map', args={
|
||||
'docs':wn.model.compress([locals["Material Request"][n]]),
|
||||
'from_doctype':'Sales Order',
|
||||
'to_doctype':'Material Request',
|
||||
'from_docname':doc.name,
|
||||
'from_to_list':"[['Sales Order', 'Material Request'], ['Sales Order Item', 'Material Request Item']]"
|
||||
}
|
||||
, function(r,rt) {
|
||||
loaddoc("Material Request", n);
|
||||
}
|
||||
);
|
||||
}
|
||||
wn.model.open_mapped_doc({
|
||||
method: "selling.doctype.sales_order.sales_order.make_material_request",
|
||||
source_name: cur_frm.doc.name
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
cur_frm.cscript['Make Delivery Note'] = function() {
|
||||
var doc = cur_frm.doc;
|
||||
if (doc.docstatus == 1) {
|
||||
n = wn.model.make_new_doc_and_get_name("Delivery Note");
|
||||
$c('dt_map', args={
|
||||
'docs':wn.model.compress([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);
|
||||
}
|
||||
);
|
||||
}
|
||||
wn.model.open_mapped_doc({
|
||||
method: "selling.doctype.sales_order.sales_order.make_delivery_note",
|
||||
source_name: cur_frm.doc.name
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ class DocType(SellingController):
|
||||
def validate_order_type(self):
|
||||
super(DocType, self).validate_order_type()
|
||||
|
||||
#validate delivery date
|
||||
def validate_delivery_date(self):
|
||||
if self.doc.order_type == 'Sales' and not self.doc.delivery_date:
|
||||
msgprint("Please enter 'Expected Delivery Date'")
|
||||
raise Exception
|
||||
@@ -186,6 +186,7 @@ class DocType(SellingController):
|
||||
|
||||
self.validate_fiscal_year()
|
||||
self.validate_order_type()
|
||||
self.validate_delivery_date()
|
||||
self.validate_mandatory()
|
||||
self.validate_proj_cust()
|
||||
self.validate_po()
|
||||
@@ -377,4 +378,72 @@ def get_currency_and_number_format():
|
||||
"currency": webnotes.conn.get_default("currency"),
|
||||
"currency_symbols": json.dumps(dict(webnotes.conn.sql("""select name, symbol
|
||||
from tabCurrency where ifnull(enabled,0)=1""")))
|
||||
}
|
||||
}
|
||||
|
||||
@webnotes.whitelist()
|
||||
def make_material_request(source_name, target_doclist=None):
|
||||
from webnotes.model.mapper import get_mapped_doclist
|
||||
|
||||
def postprocess(source, doclist):
|
||||
doclist[0].material_request_type = "Purchase"
|
||||
|
||||
doclist = get_mapped_doclist("Sales Order", source_name, {
|
||||
"Sales Order": {
|
||||
"doctype": "Material Request",
|
||||
"validation": {
|
||||
"docstatus": ["=", 1]
|
||||
}
|
||||
},
|
||||
"Sales Order Item": {
|
||||
"doctype": "Material Request Item",
|
||||
"field_map": {
|
||||
"parent": "sales_order_no",
|
||||
"reserved_warehouse": "warehouse",
|
||||
"stock_uom": "uom"
|
||||
}
|
||||
}
|
||||
}, target_doclist, postprocess)
|
||||
|
||||
return [d.fields for d in doclist]
|
||||
|
||||
@webnotes.whitelist()
|
||||
def make_delivery_note(source_name, target_doclist=None):
|
||||
from webnotes.model.mapper import get_mapped_doclist
|
||||
|
||||
def update_item(obj, target):
|
||||
target.amount = (flt(obj.qty) - flt(obj.delivered_qty)) * flt(obj.basic_rate)
|
||||
target.export_amount = (flt(obj.qty) - flt(obj.delivered_qty)) * flt(obj.export_rate)
|
||||
target.qty = flt(obj.qty) - flt(obj.delivered_qty)
|
||||
|
||||
doclist = get_mapped_doclist("Sales Order", source_name, {
|
||||
"Sales Order": {
|
||||
"doctype": "Delivery Note",
|
||||
"field_map": {
|
||||
"name": "sales_order_no",
|
||||
"shipping_address": "address_display",
|
||||
"shipping_address_name": "customer_address",
|
||||
},
|
||||
"validation": {
|
||||
"docstatus": ["=", 1]
|
||||
}
|
||||
},
|
||||
"Sales Order Item": {
|
||||
"doctype": "Delivery Note Item",
|
||||
"field_map": {
|
||||
"export_rate": "export_rate",
|
||||
"name": "prevdoc_detail_docname",
|
||||
"parent": "prevdoc_docname",
|
||||
"parenttype": "prevdoc_doctype",
|
||||
"reserved_warehouse": "warehouse"
|
||||
},
|
||||
"postprocess": update_item
|
||||
},
|
||||
"Sales Taxes and Charges": {
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
},
|
||||
"Sales Team": {
|
||||
"doctype": "Sales Team",
|
||||
}
|
||||
}, target_doclist)
|
||||
|
||||
return [d.fields for d in doclist]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"creation": "2013-06-18 12:39:59",
|
||||
"docstatus": 0,
|
||||
"modified": "2013-06-27 11:31:02",
|
||||
"modified": "2013-07-04 10:56:35",
|
||||
"modified_by": "Administrator",
|
||||
"owner": "Administrator"
|
||||
},
|
||||
@@ -39,6 +39,13 @@
|
||||
"doctype": "DocType",
|
||||
"name": "Sales Order"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "customer_section",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Customer",
|
||||
"options": "icon-user"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
"fieldname": "column_break0",
|
||||
@@ -77,7 +84,6 @@
|
||||
"search_index": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "customer",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "customer_name",
|
||||
"fieldtype": "Data",
|
||||
@@ -86,38 +92,34 @@
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "customer",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "address_display",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"label": "Address",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "customer",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "contact_display",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"label": "Contact",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "customer",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "contact_mobile",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"label": "Mobile No",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "customer",
|
||||
"doctype": "DocField",
|
||||
"fieldname": "contact_email",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"label": "Contact Email",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
@@ -252,7 +254,8 @@
|
||||
"doctype": "DocField",
|
||||
"fieldname": "sec_break45",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Price List and Currency"
|
||||
"label": "Price List and Currency",
|
||||
"options": "icon-tag"
|
||||
},
|
||||
{
|
||||
"description": "Customer's currency",
|
||||
@@ -323,7 +326,8 @@
|
||||
"fieldname": "items",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Items",
|
||||
"oldfieldtype": "Section Break"
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-shopping-cart"
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
@@ -345,6 +349,7 @@
|
||||
"hidden": 0,
|
||||
"label": "Packing List",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-suitcase",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
@@ -444,6 +449,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Taxes",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-money",
|
||||
"print_hide": 0
|
||||
},
|
||||
{
|
||||
@@ -537,6 +543,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Totals",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-money",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
@@ -626,6 +633,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Terms and Conditions",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-legal",
|
||||
"print_hide": 0
|
||||
},
|
||||
{
|
||||
@@ -671,7 +679,8 @@
|
||||
"doctype": "DocField",
|
||||
"fieldname": "contact_info",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Contact Info"
|
||||
"label": "Contact Info",
|
||||
"options": "icon-bullhorn"
|
||||
},
|
||||
{
|
||||
"doctype": "DocField",
|
||||
@@ -734,6 +743,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "More Info",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-file-text",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
@@ -904,6 +914,7 @@
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Sales Team",
|
||||
"oldfieldtype": "Section Break",
|
||||
"options": "icon-group",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
@@ -951,7 +962,6 @@
|
||||
"doctype": "DocField",
|
||||
"fieldname": "section_break1",
|
||||
"fieldtype": "Section Break",
|
||||
"options": "Simple",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
|
||||
@@ -3,6 +3,36 @@ from webnotes.utils import flt
|
||||
import unittest
|
||||
|
||||
class TestSalesOrder(unittest.TestCase):
|
||||
def test_make_material_request(self):
|
||||
from selling.doctype.sales_order.sales_order import make_material_request
|
||||
|
||||
so = webnotes.bean(copy=test_records[0]).insert()
|
||||
|
||||
self.assertRaises(webnotes.ValidationError, make_material_request,
|
||||
so.doc.name)
|
||||
|
||||
sales_order = webnotes.bean("Sales Order", so.doc.name)
|
||||
sales_order.submit()
|
||||
mr = make_material_request(so.doc.name)
|
||||
|
||||
self.assertEquals(mr[0]["material_request_type"], "Purchase")
|
||||
self.assertEquals(len(mr), len(sales_order.doclist))
|
||||
|
||||
def test_make_delivery_note(self):
|
||||
from selling.doctype.sales_order.sales_order import make_delivery_note
|
||||
|
||||
so = webnotes.bean(copy=test_records[0]).insert()
|
||||
|
||||
self.assertRaises(webnotes.ValidationError, make_delivery_note,
|
||||
so.doc.name)
|
||||
|
||||
sales_order = webnotes.bean("Sales Order", so.doc.name)
|
||||
sales_order.submit()
|
||||
dn = make_delivery_note(so.doc.name)
|
||||
|
||||
self.assertEquals(dn[0]["doctype"], "Delivery Note")
|
||||
self.assertEquals(len(dn), len(sales_order.doclist))
|
||||
|
||||
def create_so(self, so_doclist = None):
|
||||
if not so_doclist:
|
||||
so_doclist =test_records[0]
|
||||
|
||||
@@ -7,6 +7,11 @@ wn.module_page["Selling"] = [
|
||||
title: wn._("Documents"),
|
||||
icon: "icon-copy",
|
||||
items: [
|
||||
{
|
||||
label: wn._("Customer"),
|
||||
description: wn._("Customer database."),
|
||||
doctype:"Customer"
|
||||
},
|
||||
{
|
||||
label: wn._("Lead"),
|
||||
description: wn._("Database of potential customers."),
|
||||
@@ -33,11 +38,6 @@ wn.module_page["Selling"] = [
|
||||
title: wn._("Masters"),
|
||||
icon: "icon-book",
|
||||
items: [
|
||||
{
|
||||
label: wn._("Customer"),
|
||||
description: wn._("Customer database."),
|
||||
doctype:"Customer"
|
||||
},
|
||||
{
|
||||
label: wn._("Contact"),
|
||||
description: wn._("All Contacts."),
|
||||
|
||||
Reference in New Issue
Block a user