diff --git a/.gitignore b/.gitignore
index ba0a9a311b..99a0c8a95a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,13 +5,12 @@ patch.log
lib
conf.py
version.num
-public/*.html
-!public/blank.html
-!public/unsupported.html
-!public/app.html
public/js/lib
public/images/lib
public/files
public/backups
public/css/wn-web.css
public/js/wn-web.js
+backups
+files
+logs
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 97848a36a8..a527ad4a1d 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -197,6 +197,7 @@ class DocType(TransactionBase):
if ret['warehouse']:
actual_qty = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], ret['warehouse']))
ret['actual_qty']= actual_qty and flt(actual_qty[0][0]) or 0
+ msgprint(ret)
return ret
def get_barcode_details(self, barcode):
diff --git a/erpnext/buying/DocType Mapper/Purchase Request-Supplier Quotation/Purchase Request-Supplier Quotation.txt b/erpnext/buying/DocType Mapper/Purchase Request-Supplier Quotation/Purchase Request-Supplier Quotation.txt
new file mode 100644
index 0000000000..95b13ba447
--- /dev/null
+++ b/erpnext/buying/DocType Mapper/Purchase Request-Supplier Quotation/Purchase Request-Supplier Quotation.txt
@@ -0,0 +1,124 @@
+# DocType Mapper, Purchase Request-Supplier Quotation
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2012-08-02 18:36:26',
+ 'docstatus': 0,
+ 'modified': '2012-08-02 18:37:32',
+ 'modified_by': u'Administrator',
+ 'owner': u'Administrator'
+ },
+
+ # These values are common for all Table Mapper Detail
+ {
+ 'doctype': u'Table Mapper Detail',
+ 'name': '__common__',
+ 'parent': u'Purchase Request-Supplier Quotation',
+ 'parentfield': u'table_mapper_details',
+ 'parenttype': u'DocType Mapper'
+ },
+
+ # These values are common for all Field Mapper Detail
+ {
+ 'doctype': u'Field Mapper Detail',
+ 'name': '__common__',
+ 'parent': u'Purchase Request-Supplier Quotation',
+ 'parentfield': u'field_mapper_details',
+ 'parenttype': u'DocType Mapper'
+ },
+
+ # These values are common for all DocType Mapper
+ {
+ 'doctype': u'DocType Mapper',
+ 'from_doctype': u'Purchase Request',
+ 'module': u'Buying',
+ 'name': '__common__',
+ 'ref_doc_submitted': 1,
+ 'to_doctype': u'Supplier Quotation'
+ },
+
+ # DocType Mapper, Purchase Request-Supplier Quotation
+ {
+ 'doctype': u'DocType Mapper',
+ 'name': u'Purchase Request-Supplier Quotation'
+ },
+
+ # Field Mapper Detail
+ {
+ 'checking_operator': u'=',
+ 'doctype': u'Field Mapper Detail',
+ 'from_field': u'company',
+ 'map': u'Yes',
+ 'match_id': 0,
+ 'to_field': u'company'
+ },
+
+ # Field Mapper Detail
+ {
+ 'doctype': u'Field Mapper Detail',
+ 'from_field': u'parenttype',
+ 'map': u'Yes',
+ 'match_id': 1,
+ 'to_field': u'prevdoc_doctype'
+ },
+
+ # Field Mapper Detail
+ {
+ 'doctype': u'Field Mapper Detail',
+ 'from_field': u'parent',
+ 'map': u'Yes',
+ 'match_id': 1,
+ 'to_field': u'prevdoc_docname'
+ },
+
+ # Field Mapper Detail
+ {
+ 'doctype': u'Field Mapper Detail',
+ 'from_field': u'name',
+ 'map': u'Yes',
+ 'match_id': 1,
+ 'to_field': u'prevdoc_detail_docname'
+ },
+
+ # Field Mapper Detail
+ {
+ 'doctype': u'Field Mapper Detail',
+ 'from_field': u'uom',
+ 'map': u'Yes',
+ 'match_id': 1,
+ 'to_field': u'stock_uom'
+ },
+
+ # Field Mapper Detail
+ {
+ 'checking_operator': u'>=',
+ 'doctype': u'Field Mapper Detail',
+ 'from_field': u'transaction_date',
+ 'map': u'No',
+ 'match_id': 0,
+ 'to_field': u'transaction_date'
+ },
+
+ # Table Mapper Detail
+ {
+ 'doctype': u'Table Mapper Detail',
+ 'from_table': u'Purchase Request',
+ 'match_id': 0,
+ 'reference_key': u'prevdoc_docname',
+ 'to_table': u'Supplier Quotation',
+ 'validation_logic': u'docstatus = 1'
+ },
+
+ # Table Mapper Detail
+ {
+ 'doctype': u'Table Mapper Detail',
+ 'from_field': u'indent_details',
+ 'from_table': u'Purchase Request Item',
+ 'match_id': 1,
+ 'reference_doctype_key': u'prevdoc_doctype',
+ 'to_field': u'quotation_details',
+ 'to_table': u'Supplier Quotation Item',
+ 'validation_logic': u'docstatus =1'
+ }
+]
\ No newline at end of file
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.js b/erpnext/buying/doctype/purchase_common/purchase_common.js
index 82a9953df1..81d5fbf813 100644
--- a/erpnext/buying/doctype/purchase_common/purchase_common.js
+++ b/erpnext/buying/doctype/purchase_common/purchase_common.js
@@ -121,27 +121,21 @@ var set_dynamic_label_child = function(doc, cdt, cdn, base_curr) {
//------------------------------------------------------------------
cur_frm.cscript.dynamic_label = function(doc, cdt, cdn, callback1) {
- var callback = function(r, rt) {
- if (r.message) base_curr = r.message;
- else base_curr = sys_defaults['currency'];
-
- if (base_curr == doc.currency) {
- set_multiple(cdt, cdn, {conversion_rate:1});
- hide_field(['conversion_rate', 'net_total_import','grand_total_import', 'in_words_import', 'other_charges_added_import', 'other_charges_deducted_import']);
- } else unhide_field(['conversion_rate', 'net_total_import','grand_total_import', 'in_words_import', 'other_charges_added_import', 'other_charges_deducted_import']);
-
- set_dynamic_label_par(doc, cdt, cdn, base_curr);
- set_dynamic_label_child(doc, cdt, cdn, base_curr);
-
- if(callback1) callback1(doc, cdt, cdn);
+ var base_currency = wn.boot.company[doc.company].default_currency || sys_defaults['currency'];
+
+ if (doc.currency === base_currency) {
+ set_multiple(cdt, cdn, {conversion_rate:1});
+ hide_field(['conversion_rate', 'net_total_import','grand_total_import',
+ 'in_words_import', 'other_charges_added_import', 'other_charges_deducted_import']);
+ } else {
+ unhide_field(['conversion_rate', 'net_total_import','grand_total_import',
+ 'in_words_import', 'other_charges_added_import', 'other_charges_deducted_import']);
}
-
- if (doc.company == sys_defaults['company']) callback('', '');
- else wn.call({
- method: 'selling.doctype.sales_common.sales_common.get_comp_base_currency',
- args: {company: doc.company},
- callback: callback
- });
+
+ set_dynamic_label_par(doc, cdt, cdn, base_currency);
+ set_dynamic_label_child(doc, cdt, cdn, base_currency);
+
+ if (callback1) callback1(doc, cdt, cdn);
}
cur_frm.cscript.currency = function(doc, cdt, cdn) {
diff --git a/erpnext/buying/doctype/purchase_common/purchase_common.py b/erpnext/buying/doctype/purchase_common/purchase_common.py
index fd8ec92eac..b9e689fe6a 100644
--- a/erpnext/buying/doctype/purchase_common/purchase_common.py
+++ b/erpnext/buying/doctype/purchase_common/purchase_common.py
@@ -616,7 +616,7 @@ class DocType(TransactionBase):
sql("update `tab%s` set %s = '%s', modified = '%s' where name = '%s'" % (self.ref_doctype_dict[ref_dn][0], self.update_percent_field[self.ref_doctype_dict[ref_dn][2]], percent_complete, obj.doc.modified, ref_dn))
- def validate_fiscal_year(self,fiscal_year,transaction_date,dn):
+ def validate_fiscal_year(self, fiscal_year, transaction_date, dn):
fy=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)
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.js b/erpnext/buying/doctype/purchase_order/purchase_order.js
index 9d50020952..a27f6ff73b 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.js
@@ -23,7 +23,6 @@ wn.require('erpnext/buying/doctype/purchase_common/purchase_common.js');
wn.require('erpnext/utilities/doctype/sms_control/sms_control.js');
wn.require('erpnext/setup/doctype/notification_control/notification_control.js');
-//========================== On Load =================================================
cur_frm.cscript.onload = function(doc, cdt, cdn) {
if(!doc.fiscal_year && doc.__islocal){ //set_default_values(doc);
@@ -37,22 +36,14 @@ cur_frm.cscript.onload = function(doc, cdt, cdn) {
}
cur_frm.cscript.onload_post_render = function(doc, dt, dn) {
- var callback = function(doc, dt, dn) {
- if(doc.__islocal){
- cur_frm.cscript.get_default_schedule_date(doc);
- }
- }
- cur_frm.cscript.dynamic_label(doc, dt, dn, callback);
+ if(doc.__islocal) cur_frm.cscript.get_default_schedule_date(doc);
}
-// ================================== Refresh ==========================================
cur_frm.cscript.refresh = function(doc, cdt, cdn) {
- // Show buttons
- // ---------------------------------
cur_frm.clear_custom_buttons();
erpnext.hide_naming_series();
- if (!cur_frm.cscript.is_onload) cur_frm.cscript.dynamic_label(doc, cdt, cdn);
+ cur_frm.cscript.dynamic_label(doc, cdt, cdn);
if(doc.docstatus == 1 && doc.status != 'Stopped'){
cur_frm.add_custom_button('Send SMS', cur_frm.cscript['Send SMS']);
@@ -68,7 +59,6 @@ cur_frm.cscript.refresh = function(doc, cdt, cdn) {
else $(cur_frm.fields_dict.contact_section.row.wrapper).toggle(false);
}
-//Supplier
cur_frm.cscript.supplier = function(doc,dt,dn) {
if (doc.supplier) {
get_server_fields('get_default_supplier_address',
@@ -102,33 +92,14 @@ cur_frm.fields_dict.contact_person.on_new = function(dn) {
locals['Contact'][dn].supplier_name = locals[cur_frm.doctype][cur_frm.docname].supplier_name;
}
-
-
-
-
-//================ create new contact ============================================================================
-cur_frm.cscript.new_contact = function(){
- tn = createLocal('Contact');
- locals['Contact'][tn].is_supplier = 1;
- if(doc.supplier) locals['Contact'][tn].supplier = doc.supplier;
- loaddoc('Contact', tn);
-}
-
-//======================= transaction date =============================
cur_frm.cscript.transaction_date = function(doc,cdt,cdn){
- if(doc.__islocal){
- cur_frm.cscript.get_default_schedule_date(doc);
- }
+ if(doc.__islocal){ cur_frm.cscript.get_default_schedule_date(doc); }
}
-
-// ---------------------- Get project name --------------------------
cur_frm.fields_dict['po_details'].grid.get_field('project_name').get_query = function(doc, cdt, cdn) {
return 'SELECT `tabProject`.name FROM `tabProject` WHERE `tabProject`.status = "Open" AND `tabProject`.name LIKE "%s" ORDER BY `tabProject`.name ASC LIMIT 50';
}
-//==================== Purchase Request No Get Query =======================================================
-//===== Only those Purchase Requests status != 'Completed' and docstatus = 1 i.e. submitted=================
cur_frm.fields_dict['indent_no'].get_query = function(doc) {
return 'SELECT DISTINCT `tabPurchase Request`.`name` FROM `tabPurchase Request` WHERE `tabPurchase Request`.company = "' + doc.company + '" and `tabPurchase Request`.`docstatus` = 1 and `tabPurchase Request`.`status` != "Stopped" and ifnull(`tabPurchase Request`.`per_ordered`,0) < 100 and `tabPurchase Request`.%(key)s LIKE "%s" ORDER BY `tabPurchase Request`.`name` DESC LIMIT 50';
}
@@ -203,10 +174,6 @@ cur_frm.cscript['Unstop Purchase Order'] = function() {
}
}
-// ***************** Get Print Heading *****************
-cur_frm.fields_dict['select_print_heading'].get_query = function(doc, cdt, cdn) {
- return 'SELECT `tabPrint Heading`.name FROM `tabPrint Heading` WHERE `tabPrint Heading`.docstatus !=2 AND `tabPrint Heading`.name LIKE "%s" ORDER BY `tabPrint Heading`.name ASC LIMIT 50';
-}
//****************** For print sales order no and date*************************
cur_frm.pformat.indent_no = function(doc, cdt, cdn){
//function to make row of table
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index d6463d7bf2..f4e07038eb 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -84,7 +84,6 @@ class DocType(TransactionBase):
# Pull Purchase Request
def get_indent_details(self):
- #self.validate_prev_docname()
if self.doc.indent_no:
get_obj('DocType Mapper','Purchase Request-Purchase Order').dt_map('Purchase Request','Purchase Order',self.doc.indent_no, self.doc, self.doclist, "[['Purchase Request','Purchase Order'],['Purchase Request Item', 'Purchase Order Item']]")
pcomm = get_obj('Purchase Common')
@@ -102,26 +101,13 @@ class DocType(TransactionBase):
else:
d.purchase_ref_rate = d.discount_rate = d.purchase_rate = d.import_ref_rate = d.import_rate = 0.0
- # GET TERMS & CONDITIONS
- # =====================================================================================
def get_tc_details(self):
+ """get terms & conditions"""
return get_obj('Purchase Common').get_tc_details(self)
-
-
- # validate if indent has been pulled twice
- def validate_prev_docname(self):
- for d in getlist(self.doclist, 'po_details'):
- if d.prevdoc_docname and self.doc.indent_no == d.prevdoc_docname:
- msgprint(cstr(self.doc.indent_no) + " indent details have already been pulled. ")
- raise Exception
-
- # get last purchase rate
def get_last_purchase_rate(self):
get_obj('Purchase Common').get_last_purchase_rate(self)
- # validation
- #-------------------------------------------------------------------------------------------------------------
def validate_doc(self,pc_obj):
# Validate values with reference document
pc_obj.validate_reference_value(obj = self)
@@ -234,16 +220,14 @@ class DocType(TransactionBase):
get_obj('Authorization Control').validate_approving_authority(self.doc.doctype, self.doc.company, self.doc.grand_total)
# Step 4 :=> Update Current PO No. in Supplier as last_purchase_order.
- update_supplier = sql("update `tabSupplier` set last_purchase_order = '%s' where name = '%s'" % (self.doc.name, self.doc.supplier))
+ update_supplier = webnotes.conn.set_value("Supplier", self.doc.supplier,
+ "last_purchase_order", self.doc.name)
# Step 5 :=> Update last purchase rate
pc_obj.update_last_purchase_rate(self, is_submit = 1)
# Step 6 :=> Set Status
set(self.doc,'status','Submitted')
-
- self.doc.indent_no = '';
-
# On Cancel
# -------------------------------------------------------------------------------------------------------
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.txt b/erpnext/buying/doctype/purchase_order/purchase_order.txt
index 169f662fe6..9900adb224 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.txt
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-06-11 12:09:56',
+ 'creation': '2012-07-02 14:44:19',
'docstatus': 0,
- 'modified': '2012-07-16 16:25:43',
+ 'modified': '2012-08-02 13:43:50',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -854,23 +854,6 @@
'width': u'50%'
},
- # DocField
- {
- 'colour': u'White:FFF',
- 'description': u'Track this Purchase Order against any Project',
- 'doctype': u'DocField',
- 'fieldname': u'project_name',
- 'fieldtype': u'Link',
- 'in_filter': 1,
- 'label': u'Project Name',
- 'oldfieldname': u'project_name',
- 'oldfieldtype': u'Link',
- 'options': u'Project',
- 'permlevel': 0,
- 'search_index': 1,
- 'trigger': u'Client'
- },
-
# DocField
{
'colour': u'White:FFF',
diff --git a/erpnext/website/doctype/blog_subscriber/__init__.py b/erpnext/buying/doctype/supplier_quotation/__init__.py
similarity index 100%
rename from erpnext/website/doctype/blog_subscriber/__init__.py
rename to erpnext/buying/doctype/supplier_quotation/__init__.py
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js
new file mode 100644
index 0000000000..4d2673c5ef
--- /dev/null
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.js
@@ -0,0 +1,113 @@
+// 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 .
+
+// define defaults for purchase common
+cur_frm.cscript.tname = "Supplier Quotation Item";
+cur_frm.cscript.fname = "quotation_items";
+cur_frm.cscript.other_fname = "purchase_tax_details";
+
+// attach required files
+wn.require('erpnext/accounts/doctype/purchase_taxes_and_charges_master/purchase_taxes_and_charges_master.js');
+wn.require('erpnext/buying/doctype/purchase_common/purchase_common.js');
+
+cur_frm.cscript.onload = function(doc, dt, dn) {
+ // set missing values in parent doc
+ set_missing_values(doc, {
+ fiscal_year: sys_defaults.fiscal_year,
+ conversion_rate: 1,
+ currency: sys_defaults.currency,
+ status: "Draft",
+ transaction_date: get_today(),
+ is_subcontracted: "No"
+ });
+}
+
+cur_frm.cscript.refresh = function(doc, dt, dn) {
+ erpnext.hide_naming_series();
+ cur_frm.cscript.dynamic_label(doc, dt, dn);
+
+ cur_frm.cscript.toggle_contact_section(doc);
+
+ cur_frm.clear_custom_buttons();
+ if (doc.docstatus === 1) {
+ cur_frm.add_custom_button("Make Purchase Order", cur_frm.cscript.make_purchase_order);
+ }
+}
+
+cur_frm.cscript.toggle_contact_section = function(doc) {
+ console.log(doc.supplier);
+ doc.supplier ? unhide_field("contact_section") : hide_field("contact_section");
+}
+
+cur_frm.cscript.make_purchase_order = function(doc, dt, dn) {
+
+}
+
+cur_frm.cscript.supplier = function(doc, dt, dn) {
+ if (doc.supplier) {
+ get_server_fields('get_default_supplier_address',
+ JSON.stringify({ supplier: doc.supplier }), '', doc, dt, dn, 1,
+ function() { cur_frm.refresh(); });
+ cur_frm.cscript.toggle_contact_section(doc);
+ }
+}
+
+cur_frm.fields_dict['quotation_items'].grid.get_field('project_name').get_query =
+ function(doc, cdt, cdn) {
+ return "select `tabProject`.name from `tabProject` \
+ where `tabProject`.status = \"Open\" and `tabProject`.name like \"%s\" \
+ order by `tabProject`.name ASC LIMIT 50";
+ }
+
+cur_frm.fields_dict['indent_no'].get_query = function(doc) {
+ return "select distinct `tabPurchase Request`.`name` from `tabPurchase Request` \
+ where `tabPurchase Request`.company = \"" + doc.company +
+ "\" and `tabPurchase Request`.`docstatus` = 1 and \
+ `tabPurchase Request`.`status` != \"Stopped\" and \
+ ifnull(`tabPurchase Request`.`per_ordered`,0) < 100 and \
+ `tabPurchase Request`.%(key)s LIKE \"%s\" \
+ order by `tabPurchase Request`.`name` desc limit 50";
+}
+
+
+cur_frm.cscript.supplier_address = function(doc, dt, dn) {
+ if (doc.supplier) {
+ get_server_fields("get_supplier_address", JSON.stringify({supplier: doc.supplier,
+ address: doc.supplier_address, contact: doc.contact_person}), '', doc, dt, dn, 1);
+ }
+}
+cur_frm.cscript.contact_person = cur_frm.cscript.supplier_address;
+
+cur_frm.fields_dict['supplier_address'].get_query = function(doc, cdt, cdn) {
+ return "SELECT name, address_line1, city FROM tabAddress WHERE supplier = \"" + doc.supplier
+ + "\" 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 supplier = \"" + doc.supplier
+ +"\" AND docstatus != 2 AND name LIKE \"%s\" ORDER BY name ASC LIMIT 50";
+}
+
+cur_frm.fields_dict.supplier_address.on_new = function(dn) {
+ locals['Address'][dn].supplier = locals[cur_frm.doctype][cur_frm.docname].supplier;
+ locals['Address'][dn].supplier_name = locals[cur_frm.doctype][cur_frm.docname].supplier_name;
+}
+
+cur_frm.fields_dict.contact_person.on_new = function(dn) {
+ locals['Contact'][dn].supplier = locals[cur_frm.doctype][cur_frm.docname].supplier;
+ locals['Contact'][dn].supplier_name = locals[cur_frm.doctype][cur_frm.docname].supplier_name;
+}
\ No newline at end of file
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
new file mode 100644
index 0000000000..b90411cddb
--- /dev/null
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.py
@@ -0,0 +1,97 @@
+# 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 .
+
+from __future__ import unicode_literals
+import webnotes
+from webnotes.model.code import get_obj
+from utilities.transaction_base import TransactionBase
+
+class DocType(TransactionBase):
+ def __init__(self, doc, doclist=None):
+ self.doc, self.doclist = doc, doclist or []
+ self.tname, self.fname = "Supplier Quotation Item", "quotation_item"
+
+ def autoname(self):
+ """autoname based on naming series value"""
+ from webnotes.model.doc import make_autoname
+ self.doc.name = make_autoname(self.doc.naming_series + ".#####")
+
+ def validate(self):
+ self.validate_fiscal_year()
+ self.validate_common()
+ self.set_in_words()
+ self.doc.status = "Draft"
+
+ def on_submit(self):
+ webnotes.conn.set(self.doc, "status", "Submitted")
+
+ def on_cancel(self):
+ webnotes.conn.set(self.doc, "status", "Cancelled")
+
+ def on_trash(self):
+ pass
+
+ def get_item_details(self, args=None):
+ if args:
+ return get_obj(dt='Purchase Common').get_item_details(self, args)
+ else:
+ obj = get_obj('Purchase Common')
+ for doc in self.doclist:
+ if doc.fields.get('item_code'):
+ temp = {
+ 'item_code': doc.fields.get('item_code'),
+ 'warehouse': doc.fields.get('warehouse')
+ }
+ ret = obj.get_item_details(self, json.dumps(temp))
+ for r in ret:
+ if not doc.fields.get(r):
+ doc.fields[r] = ret[r]
+
+ def get_indent_details(self):
+ if self.doc.indent_no:
+ mapper = get_obj("DocType Mapper", "Purchase Request-Supplier Quotation")
+ mapper.dt_map("Purchase Request", "Supplier Quotation", self.doc.indent_no,
+ self.doc, self.doclist, """[['Purchase Request', 'Supplier Quotation'],
+ ['Purchase Request Item', 'Supplier Quotation Item']]""")
+
+ for d in getlist(self.doclist, "quotation_details"):
+ if d.item_code and not d.purchase_rate:
+ d.purchase_ref_rate = d.discount_rate = d.purchase_rate = 0.0
+ d.import_ref_rate = d.import_rate = 0.0
+
+ def get_purchase_tax_details(self):
+ self.doclist = get_obj('Purchase Common').get_purchase_tax_details(self)
+
+ def get_uom_details(self, args=None):
+ return get_obj('Purchase Common').get_uom_details(args)
+
+ def validate_fiscal_year(self):
+ get_obj(dt = 'Purchase Common').validate_fiscal_year( \
+ self.doc.fiscal_year, self.doc.transaction_date, 'Quotation Date')
+
+ def validate_common(self):
+ pc = get_obj('Purchase Common')
+ pc.validate_mandatory(self)
+ pc.validate_for_items(self)
+ pc.validate_conversion_rate(self)
+ pc.get_prevdoc_date(self)
+ pc.validate_reference_value(self)
+
+ def set_in_words(self):
+ pc = get_obj('Purchase Common')
+ company_currency = TransactionBase().get_company_currency(self.doc.company)
+ self.doc.in_words = pc.get_total_in_words(company_currency, self.doc.grand_total)
+ self.doc.in_words_import = pc.get_total_in_words(self.doc.currency, self.doc.grand_total_import)
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.txt b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.txt
new file mode 100644
index 0000000000..e4a33ca91b
--- /dev/null
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.txt
@@ -0,0 +1,924 @@
+# DocType, Supplier Quotation
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2012-08-01 20:03:35',
+ 'docstatus': 0,
+ 'modified': '2012-08-02 18:04:35',
+ 'modified_by': u'Administrator',
+ 'owner': u'Administrator'
+ },
+
+ # These values are common for all DocType
+ {
+ 'allow_attach': 1,
+ 'default_print_format': u'Standard',
+ 'doctype': 'DocType',
+ 'document_type': u'Transaction',
+ 'is_submittable': 1,
+ 'is_transaction_doc': 1,
+ 'module': u'Buying',
+ 'name': '__common__',
+ 'read_only_onload': 1,
+ 'search_fields': u'status, transaction_date, supplier,grand_total',
+ 'version': 1
+ },
+
+ # These values are common for all DocField
+ {
+ 'doctype': u'DocField',
+ 'name': '__common__',
+ 'parent': u'Supplier Quotation',
+ 'parentfield': u'fields',
+ 'parenttype': u'DocType'
+ },
+
+ # These values are common for all DocPerm
+ {
+ 'doctype': u'DocPerm',
+ 'name': '__common__',
+ 'parent': u'Supplier Quotation',
+ 'parentfield': u'permissions',
+ 'parenttype': u'DocType',
+ 'read': 1
+ },
+
+ # DocType, Supplier Quotation
+ {
+ 'doctype': 'DocType',
+ 'name': u'Supplier Quotation'
+ },
+
+ # DocPerm
+ {
+ 'amend': 1,
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Production Manager',
+ 'submit': 1,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'amend': 1,
+ 'cancel': 1,
+ 'create': 1,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Purchase Manager',
+ 'submit': 1,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'amend': 1,
+ 'cancel': 0,
+ 'create': 1,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Purchase User',
+ 'submit': 0,
+ 'write': 1
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Material User',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 0,
+ 'role': u'Supplier',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 1,
+ 'role': u'All',
+ 'submit': 0,
+ 'write': 0
+ },
+
+ # DocPerm
+ {
+ 'amend': 0,
+ 'cancel': 0,
+ 'create': 0,
+ 'doctype': u'DocPerm',
+ 'permlevel': 2,
+ 'role': u'All',
+ 'submit': 0,
+ 'write': 1
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'doctype': u'DocField',
+ 'fieldname': u'basic_info',
+ 'fieldtype': u'Section Break',
+ 'label': u'Basic Info',
+ 'oldfieldtype': u'Section Break',
+ 'permlevel': 0,
+ 'print_hide': 0
+ },
+
+ # 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',
+ 'description': u'To manage multiple series please go to Setup > Manage Series',
+ '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'SQTN',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'Supplier (vendor) name as entered in supplier master',
+ 'doctype': u'DocField',
+ 'fieldname': u'supplier',
+ 'fieldtype': u'Link',
+ 'in_filter': 1,
+ 'label': u'Supplier',
+ 'oldfieldname': u'supplier',
+ 'oldfieldtype': u'Link',
+ 'options': u'Supplier',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 1,
+ 'search_index': 1,
+ 'trigger': u'Client'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'supplier_name',
+ 'fieldtype': u'Data',
+ 'hidden': 1,
+ 'label': u'Name',
+ 'permlevel': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'address_display',
+ 'fieldtype': u'Small Text',
+ 'hidden': 1,
+ 'label': u'Address',
+ 'permlevel': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'contact_display',
+ 'fieldtype': u'Small Text',
+ 'hidden': 1,
+ 'label': u'Contact',
+ 'permlevel': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'contact_mobile',
+ 'fieldtype': u'Text',
+ 'hidden': 1,
+ 'label': u'Mobile No',
+ 'permlevel': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'contact_email',
+ 'fieldtype': u'Text',
+ 'hidden': 1,
+ 'label': u'Contact Email',
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'column_break1',
+ 'fieldtype': u'Column Break',
+ 'oldfieldtype': u'Column Break',
+ 'permlevel': 0,
+ 'print_hide': 0,
+ 'width': u'50%'
+ },
+
+ # 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',
+ 'in_filter': 1,
+ 'label': u'Quotation Date',
+ 'oldfieldname': u'transaction_date',
+ 'oldfieldtype': u'Date',
+ 'permlevel': 0,
+ 'reqd': 1,
+ 'search_index': 1,
+ 'trigger': u'Client'
+ },
+
+ # 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
+ {
+ 'allow_on_submit': 1,
+ 'doctype': u'DocField',
+ 'fieldname': u'quotation_items',
+ 'fieldtype': u'Table',
+ 'label': u'Quotation Items',
+ 'no_copy': 0,
+ 'oldfieldname': u'po_details',
+ 'oldfieldtype': u'Table',
+ 'options': u'Supplier Quotation Item',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'section_break0',
+ 'fieldtype': u'Section Break',
+ 'options': u'Simple',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'column_break2',
+ 'fieldtype': u'Column Break',
+ 'permlevel': 0,
+ 'width': u'50%'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'net_total',
+ 'fieldtype': u'Currency',
+ 'label': u'Net Total*',
+ 'no_copy': 1,
+ 'oldfieldname': u'net_total',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 1,
+ 'print_hide': 1,
+ 'reqd': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'net_total_import',
+ 'fieldtype': u'Currency',
+ 'label': u'Net Total (Import)',
+ 'no_copy': 0,
+ 'oldfieldname': u'net_total_import',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'recalculate_values',
+ 'fieldtype': u'Button',
+ 'label': u'Re-Calculate Values',
+ 'oldfieldtype': u'Button',
+ 'permlevel': 0,
+ 'trigger': u'Client'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'column_break3',
+ 'fieldtype': u'Column Break',
+ 'permlevel': 0,
+ 'width': u'50%'
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u"Supplier's currency",
+ 'doctype': u'DocField',
+ 'fieldname': u'currency',
+ 'fieldtype': u'Select',
+ 'label': u'Currency',
+ 'no_copy': 0,
+ 'oldfieldname': u'currency',
+ 'oldfieldtype': u'Select',
+ 'options': u'link:Currency',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'default': u'1',
+ 'description': u"Rate at which supplier's currency is converted to company's base currency",
+ 'doctype': u'DocField',
+ 'fieldname': u'conversion_rate',
+ 'fieldtype': u'Currency',
+ 'hidden': 0,
+ 'label': u'Conversion Rate',
+ 'no_copy': 1,
+ 'oldfieldname': u'conversion_rate',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 1,
+ 'trigger': u'Client'
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'You can make a purchase order from multiple Purchase Requests. Select Purchase Requests one by one and click on the button below.',
+ 'doctype': u'DocField',
+ 'fieldname': u'indent_no',
+ 'fieldtype': u'Link',
+ 'hidden': 0,
+ 'label': u'Select Purchase Request',
+ 'no_copy': 1,
+ 'oldfieldname': u'indent_no',
+ 'oldfieldtype': u'Link',
+ 'options': u'Purchase Request',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'get_items',
+ 'fieldtype': u'Button',
+ 'hidden': 0,
+ 'label': u'Get Items',
+ 'oldfieldtype': u'Button',
+ 'options': u'get_indent_details',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'doctype': u'DocField',
+ 'fieldname': u'taxes',
+ 'fieldtype': u'Section Break',
+ 'label': u'Taxes',
+ 'oldfieldtype': u'Section Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'If you have created a standard template in Purchase Taxes and Charges Master, select one and click on the button below.',
+ 'doctype': u'DocField',
+ 'fieldname': u'purchase_other_charges',
+ 'fieldtype': u'Link',
+ 'label': u'Purchase Taxes and Charges',
+ 'no_copy': 1,
+ 'oldfieldname': u'purchase_other_charges',
+ 'oldfieldtype': u'Link',
+ 'options': u'Purchase Taxes and Charges Master',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'get_tax_detail',
+ 'fieldtype': u'Button',
+ 'label': u'Get Tax Detail',
+ 'oldfieldtype': u'Button',
+ 'options': u'get_purchase_tax_details',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'purchase_tax_details',
+ 'fieldtype': u'Table',
+ 'label': u'Purchase Taxes and Charges',
+ 'no_copy': 0,
+ 'oldfieldname': u'purchase_tax_details',
+ 'oldfieldtype': u'Table',
+ 'options': u'Purchase Taxes and Charges',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'calculate_tax',
+ 'fieldtype': u'Button',
+ 'label': u'Calculate Tax',
+ 'oldfieldtype': u'Button',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'trigger': u'Client'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'tax_calculation',
+ 'fieldtype': u'HTML',
+ 'label': u'Tax Calculation',
+ 'no_copy': 1,
+ 'oldfieldtype': u'HTML',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'total_tax',
+ 'fieldtype': u'Currency',
+ 'label': u'Total Tax*',
+ 'no_copy': 1,
+ 'oldfieldname': u'total_tax',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'doctype': u'DocField',
+ 'fieldname': u'totals',
+ 'fieldtype': u'Section Break',
+ 'label': u'Totals',
+ 'oldfieldtype': u'Section Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'grand_total',
+ 'fieldtype': u'Currency',
+ 'label': u'Grand Total',
+ 'no_copy': 1,
+ 'oldfieldname': u'grand_total',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'rounded_total',
+ 'fieldtype': u'Currency',
+ 'label': u'Rounded Total',
+ 'oldfieldname': u'rounded_total',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'In Words will be visible once you save the Purchase Order.',
+ 'doctype': u'DocField',
+ 'fieldname': u'in_words',
+ 'fieldtype': u'Data',
+ 'label': u'In Words',
+ 'oldfieldname': u'in_words',
+ 'oldfieldtype': u'Data',
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'other_charges_added',
+ 'fieldtype': u'Currency',
+ 'label': u'Taxes and Charges Added',
+ 'no_copy': 0,
+ 'oldfieldname': u'other_charges_added',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'other_charges_deducted',
+ 'fieldtype': u'Currency',
+ 'label': u'Taxes and Charges Deducted',
+ 'no_copy': 0,
+ 'oldfieldname': u'other_charges_deducted',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'column_break4',
+ 'fieldtype': u'Column Break',
+ 'oldfieldtype': u'Column Break',
+ 'permlevel': 0,
+ 'print_hide': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'grand_total_import',
+ 'fieldtype': u'Currency',
+ 'label': u'Grand Total (Import)',
+ 'no_copy': 0,
+ 'oldfieldname': u'grand_total_import',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 1,
+ 'print_hide': 1,
+ 'report_hide': 0
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'doctype': u'DocField',
+ 'fieldname': u'in_words_import',
+ 'fieldtype': u'Data',
+ 'label': u'In Words(Import)',
+ 'oldfieldname': u'in_words_import',
+ 'oldfieldtype': u'Data',
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'other_charges_added_import',
+ 'fieldtype': u'Currency',
+ 'label': u'Taxes and Charges Added (Import)',
+ 'no_copy': 0,
+ 'oldfieldname': u'other_charges_added_import',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 1,
+ 'print_hide': 1,
+ 'report_hide': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'other_charges_deducted_import',
+ 'fieldtype': u'Currency',
+ 'label': u'Taxes and Charges Deducted (Import)',
+ 'no_copy': 0,
+ 'oldfieldname': u'other_charges_deducted_import',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 1,
+ 'print_hide': 1,
+ 'report_hide': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'terms_section_break',
+ 'fieldtype': u'Section Break',
+ 'label': u'Terms and Conditions',
+ 'oldfieldtype': u'Section Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'allow_on_submit': 1,
+ 'doctype': u'DocField',
+ 'fieldname': u'letter_head',
+ 'fieldtype': u'Select',
+ 'label': u'Letter Head',
+ 'oldfieldname': u'letter_head',
+ 'oldfieldtype': u'Select',
+ 'options': u'link:Letter Head',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'tc_name',
+ 'fieldtype': u'Link',
+ 'label': u'Select Terms and Conditions',
+ 'oldfieldname': u'tc_name',
+ 'oldfieldtype': u'Link',
+ 'options': u'Terms and Conditions',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'get_terms',
+ 'fieldtype': u'Button',
+ 'label': u'Get Terms and Conditions',
+ 'oldfieldtype': u'Button',
+ 'options': u'get_tc_details',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'terms_html',
+ 'fieldtype': u'HTML',
+ 'label': u'Terms and Conditions HTML',
+ 'oldfieldtype': u'HTML',
+ 'options': u'You can add Terms and Notes that will be printed in the Transaction',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'terms',
+ 'fieldtype': u'Text Editor',
+ 'label': u'Terms and Conditions1',
+ 'oldfieldname': u'terms',
+ 'oldfieldtype': u'Text Editor',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'contact_section',
+ 'fieldtype': u'Section Break',
+ 'label': u'Contact Info',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'supplier_address',
+ 'fieldtype': u'Link',
+ 'in_filter': 1,
+ 'label': u'Supplier Address',
+ 'options': u'Address',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # 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
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'more_info',
+ 'fieldtype': u'Section Break',
+ 'label': u'More Info',
+ 'oldfieldtype': u'Section Break',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ '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'\nDraft\nSubmitted\nStopped\nCancelled',
+ 'permlevel': 1,
+ 'print_hide': 1,
+ 'reqd': 1,
+ 'search_index': 1
+ },
+
+ # DocField
+ {
+ 'default': u'No',
+ 'doctype': u'DocField',
+ 'fieldname': u'is_subcontracted',
+ 'fieldtype': u'Select',
+ 'label': u'Is Subcontracted',
+ 'options': u'\nYes\nNo',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'amended_from',
+ 'fieldtype': u'Data',
+ 'hidden': 1,
+ 'label': u'Amended From',
+ 'no_copy': 1,
+ 'oldfieldname': u'amended_from',
+ 'oldfieldtype': u'Data',
+ 'permlevel': 1,
+ 'print_hide': 1,
+ 'report_hide': 0
+ },
+
+ # DocField
+ {
+ '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
+ {
+ 'colour': u'White:FFF',
+ 'description': u'Select the relevant company name if you have multiple companies',
+ 'doctype': u'DocField',
+ 'fieldname': u'company',
+ 'fieldtype': u'Link',
+ 'in_filter': 1,
+ 'label': u'Company',
+ 'no_copy': 0,
+ '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'fiscal_year',
+ 'fieldtype': u'Select',
+ 'in_filter': 1,
+ 'label': u'Fiscal Year',
+ 'no_copy': 0,
+ 'oldfieldname': u'fiscal_year',
+ 'oldfieldtype': u'Select',
+ 'options': u'link:Fiscal Year',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 1,
+ 'search_index': 1
+ },
+
+ # DocField
+ {
+ 'allow_on_submit': 1,
+ 'colour': u'White:FFF',
+ 'doctype': u'DocField',
+ 'fieldname': u'select_print_heading',
+ 'fieldtype': u'Link',
+ 'label': u'Select Print Heading',
+ 'no_copy': 1,
+ 'oldfieldname': u'select_print_heading',
+ 'oldfieldtype': u'Link',
+ 'options': u'Print Heading',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'report_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'column_break5',
+ 'fieldtype': u'Column Break',
+ 'oldfieldtype': u'Column Break',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'width': u'50%'
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'depends_on': u'eval:!doc.__islocal',
+ 'doctype': u'DocField',
+ 'fieldname': u'cancel_reason',
+ 'fieldtype': u'Data',
+ 'hidden': 0,
+ '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'file_list',
+ 'fieldtype': u'Text',
+ 'hidden': 1,
+ 'label': u'File List',
+ 'no_copy': 1,
+ 'permlevel': 0,
+ 'print_hide': 1
+ }
+]
\ No newline at end of file
diff --git a/erpnext/website/page/unsubscribe/__init__.py b/erpnext/buying/doctype/supplier_quotation_item/__init__.py
similarity index 100%
rename from erpnext/website/page/unsubscribe/__init__.py
rename to erpnext/buying/doctype/supplier_quotation_item/__init__.py
diff --git a/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.txt b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.txt
new file mode 100644
index 0000000000..1ee10ae496
--- /dev/null
+++ b/erpnext/buying/doctype/supplier_quotation_item/supplier_quotation_item.txt
@@ -0,0 +1,402 @@
+# DocType, Supplier Quotation Item
+[
+
+ # These values are common in all dictionaries
+ {
+ 'creation': '2012-08-01 20:07:22',
+ 'docstatus': 0,
+ 'modified': '2012-08-02 16:00:52',
+ 'modified_by': u'Administrator',
+ 'owner': u'Administrator'
+ },
+
+ # These values are common for all DocType
+ {
+ 'autoname': u'SQI-.#####',
+ 'default_print_format': u'Standard',
+ 'doctype': 'DocType',
+ 'istable': 1,
+ 'module': u'Buying',
+ 'name': '__common__',
+ 'version': 1
+ },
+
+ # These values are common for all DocField
+ {
+ 'doctype': u'DocField',
+ 'name': '__common__',
+ 'parent': u'Supplier Quotation Item',
+ 'parentfield': u'fields',
+ 'parenttype': u'DocType'
+ },
+
+ # DocType, Supplier Quotation Item
+ {
+ 'doctype': 'DocType',
+ 'name': u'Supplier Quotation 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,
+ 'print_hide': 0,
+ 'reqd': 1,
+ 'search_index': 1,
+ 'trigger': u'Client'
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'If Supplier Part Number exists for given Item, it gets stored here',
+ 'doctype': u'DocField',
+ 'fieldname': u'supplier_part_no',
+ 'fieldtype': u'Data',
+ 'hidden': 1,
+ 'label': u'Supplier Part Number',
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'item_name',
+ 'fieldtype': u'Data',
+ 'hidden': 0,
+ 'in_filter': 1,
+ 'label': u'Item Name',
+ 'oldfieldname': u'item_name',
+ 'oldfieldtype': u'Data',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 1,
+ 'search_index': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'description',
+ 'fieldtype': u'Small Text',
+ 'label': u'Description',
+ 'oldfieldname': u'description',
+ 'oldfieldtype': u'Small Text',
+ 'permlevel': 0,
+ 'reqd': 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'60px'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'import_ref_rate',
+ 'fieldtype': u'Currency',
+ 'label': u'Ref Rate ',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'discount_rate',
+ 'fieldtype': u'Currency',
+ 'label': u'Discount %',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'trigger': u'Client'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'import_rate',
+ 'fieldtype': u'Currency',
+ 'hidden': 0,
+ 'label': u'Rate ',
+ 'oldfieldname': u'import_rate',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 0,
+ 'print_hide': 0,
+ 'trigger': u'Client'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'import_amount',
+ 'fieldtype': u'Currency',
+ 'label': u'Amount',
+ 'oldfieldname': u'import_amount',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'purchase_ref_rate',
+ 'fieldtype': u'Currency',
+ 'label': u'Ref Rate *',
+ 'permlevel': 0,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'default': u'0.00',
+ 'doctype': u'DocField',
+ 'fieldname': u'purchase_rate',
+ 'fieldtype': u'Currency',
+ 'label': u'Rate (Default Curr.) *',
+ 'oldfieldname': u'purchase_rate',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 1,
+ 'trigger': u'Client',
+ 'width': u'100px'
+ },
+
+ # DocField
+ {
+ 'default': u'0.00',
+ 'doctype': u'DocField',
+ 'fieldname': u'amount',
+ 'fieldtype': u'Currency',
+ 'label': u'Amount (Default Curr.)',
+ 'oldfieldname': u'amount',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 1,
+ 'print_hide': 1,
+ 'reqd': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'warehouse',
+ 'fieldtype': u'Link',
+ 'hidden': 0,
+ 'label': u'Warehouse',
+ 'oldfieldname': u'warehouse',
+ 'oldfieldtype': u'Link',
+ 'options': u'Warehouse',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 0,
+ 'trigger': u'Client'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'project_name',
+ 'fieldtype': u'Link',
+ 'in_filter': 1,
+ 'label': u'Project Name',
+ 'options': u'Project',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'report_hide': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'uom',
+ 'fieldtype': u'Link',
+ 'label': u'UOM',
+ 'oldfieldname': u'uom',
+ 'oldfieldtype': u'Link',
+ 'options': u'UOM',
+ 'permlevel': 0,
+ 'print_hide': 0,
+ 'reqd': 1,
+ 'trigger': u'Client',
+ 'width': u'100px'
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'doctype': u'DocField',
+ 'fieldname': u'conversion_factor',
+ 'fieldtype': u'Currency',
+ 'hidden': 0,
+ 'label': u'UOM Conversion Factor',
+ 'oldfieldname': u'conversion_factor',
+ 'oldfieldtype': u'Currency',
+ 'permlevel': 0,
+ 'print_hide': 1,
+ 'reqd': 1,
+ 'trigger': u'Client',
+ 'width': u'100px'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'stock_uom',
+ 'fieldtype': u'Data',
+ 'hidden': 0,
+ 'label': u'Stock UOM',
+ 'oldfieldname': u'stock_uom',
+ 'oldfieldtype': u'Data',
+ 'permlevel': 1,
+ 'print_hide': 1,
+ 'reqd': 1,
+ 'width': u'100px'
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'doctype': u'DocField',
+ 'fieldname': u'prevdoc_doctype',
+ 'fieldtype': u'Data',
+ 'hidden': 1,
+ 'label': u'Prevdoc DocType',
+ 'no_copy': 0,
+ 'oldfieldname': u'prevdoc_doctype',
+ 'oldfieldtype': u'Data',
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'doctype': u'DocField',
+ 'fieldname': u'prevdoc_docname',
+ 'fieldtype': u'Link',
+ 'hidden': 0,
+ 'in_filter': 1,
+ 'label': u'Purchase Request No',
+ 'no_copy': 0,
+ 'oldfieldname': u'prevdoc_docname',
+ 'oldfieldtype': u'Link',
+ 'options': u'Purchase Request',
+ 'permlevel': 1,
+ 'print_hide': 1,
+ 'search_index': 1,
+ 'width': u'120px'
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'prevdoc_date',
+ 'fieldtype': u'Date',
+ 'hidden': 1,
+ 'in_filter': 1,
+ 'label': u'Purchase Request Date',
+ 'oldfieldname': u'prevdoc_date',
+ 'oldfieldtype': u'Date',
+ 'permlevel': 1,
+ 'print_hide': 1,
+ 'search_index': 0
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'doctype': u'DocField',
+ 'fieldname': u'prevdoc_detail_docname',
+ 'fieldtype': u'Data',
+ 'hidden': 1,
+ 'in_filter': 1,
+ 'label': u'Purchase Request Detail No',
+ 'no_copy': 0,
+ 'oldfieldname': u'prevdoc_detail_docname',
+ 'oldfieldtype': u'Data',
+ 'permlevel': 1,
+ 'print_hide': 1,
+ 'search_index': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'brand',
+ 'fieldtype': u'Link',
+ 'hidden': 1,
+ 'label': u'Brand',
+ 'oldfieldname': u'brand',
+ 'oldfieldtype': u'Link',
+ 'options': u'Brand',
+ 'permlevel': 1,
+ 'print_hide': 1
+ },
+
+ # 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': 0
+ },
+
+ # DocField
+ {
+ 'colour': u'White:FFF',
+ 'description': u'Tax detail table fetched from item master as a string and stored in this field.\nUsed for Taxes and Charges',
+ '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
+ {
+ '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
+ }
+]
\ No newline at end of file
diff --git a/erpnext/buying/page/buying_home/buying_home.html b/erpnext/buying/page/buying_home/buying_home.html
index 8e28e1b1e1..cd9312c7f1 100644
--- a/erpnext/buying/page/buying_home/buying_home.html
+++ b/erpnext/buying/page/buying_home/buying_home.html
@@ -5,6 +5,9 @@
Request for purchase
+
+ Track Quotations received from Suppliers
+
Purchase Orders given to Suppliers
diff --git a/erpnext/home/doctype/home_control/home_control.py b/erpnext/home/doctype/home_control/home_control.py
index 501d73aa6a..1a8be78e08 100644
--- a/erpnext/home/doctype/home_control/home_control.py
+++ b/erpnext/home/doctype/home_control/home_control.py
@@ -119,22 +119,6 @@ class DocType:
out[dt][s[0]] = cint(cnt)
return out
- def send_feedback(self, args):
- args = json.loads(args)
-
- fb_sender = sql("select concat_ws(' ',first_name, last_name), email from tabProfile where name=%s", session['user'])
- fb_subject = 'Feedback : ' + args['subject']
-
-
- fb_msg = '''
-
- ''' % (fb_sender[0][0], args['feedback'])
-
- sendmail('info@webnotestech.com', fb_sender[0][1], msg = fb_msg, subject=args['subject'],parts=[], cc=[], attach=[])
-
def get_dt_help(self,dt):
return sql("select description from tabDocType where name=%s",dt)[0][0] or ''
diff --git a/erpnext/patches/july_2012/auth_table.py b/erpnext/patches/july_2012/auth_table.py
index ef99a317de..9700495fd3 100644
--- a/erpnext/patches/july_2012/auth_table.py
+++ b/erpnext/patches/july_2012/auth_table.py
@@ -9,5 +9,6 @@ def execute():
webnotes.conn.begin()
for user, password in webnotes.conn.sql("""select name, password from tabProfile"""):
- webnotes.conn.sql("""insert into __Auth (user, `password`) values (%s, %s)""",
- (user, password))
+ if password:
+ webnotes.conn.sql("""insert into __Auth (user, `password`) values (%s, %s)""",
+ (user, password))
diff --git a/erpnext/patches/july_2012/bin_permission.py b/erpnext/patches/july_2012/bin_permission.py
index e1d0ea6f95..d48460cd94 100644
--- a/erpnext/patches/july_2012/bin_permission.py
+++ b/erpnext/patches/july_2012/bin_permission.py
@@ -1,3 +1,4 @@
+from __future__ import unicode_literals
def execute():
import webnotes
webnotes.conn.sql("update `tabDocPerm` set permlevel = 0 where parent = 'Bin'")
\ No newline at end of file
diff --git a/erpnext/patches/july_2012/blog_guest_permission.py b/erpnext/patches/july_2012/blog_guest_permission.py
index eb254b1fbd..bc42a9d05c 100644
--- a/erpnext/patches/july_2012/blog_guest_permission.py
+++ b/erpnext/patches/july_2012/blog_guest_permission.py
@@ -1,3 +1,4 @@
+from __future__ import unicode_literals
def execute():
"""allocate read write permission to guest for doctype 'Blog'"""
import webnotes
diff --git a/erpnext/patches/july_2012/project_patch_repeat.py b/erpnext/patches/july_2012/project_patch_repeat.py
new file mode 100644
index 0000000000..bd52522938
--- /dev/null
+++ b/erpnext/patches/july_2012/project_patch_repeat.py
@@ -0,0 +1,19 @@
+from __future__ import unicode_literals
+def execute():
+ import webnotes
+ webnotes.conn.sql("""update `tabPurchase Order Item` t1, `tabPurchase Order` t2
+ set t1.project_name = t2.project_name where t1.parent = t2.name
+ and ifnull(t1.project_name, '') = ''""")
+ webnotes.conn.sql("""update `tabPurchase Invoice Item` t1, `tabPurchase Invoice` t2
+ set t1.project_name = t2.project_name where t1.parent = t2.name
+ and ifnull(t1.project_name, '') = ''""")
+ webnotes.conn.sql("""update `tabPurchase Receipt Item` t1, `tabPurchase Receipt` t2
+ set t1.project_name = t2.project_name where t1.parent = t2.name
+ and ifnull(t1.project_name, '') = ''""")
+
+ webnotes.conn.commit()
+ from webnotes.model.sync import sync
+ sync("buying", "purchase_order")
+ sync("buying", "purchase_request")
+ sync("accounts", "purchase_invoice")
+ webnotes.conn.begin()
\ No newline at end of file
diff --git a/erpnext/patches/july_2012/repost_stock_due_to_wrong_packing_list.py b/erpnext/patches/july_2012/repost_stock_due_to_wrong_packing_list.py
index 95a0bea29a..ba818ecf25 100644
--- a/erpnext/patches/july_2012/repost_stock_due_to_wrong_packing_list.py
+++ b/erpnext/patches/july_2012/repost_stock_due_to_wrong_packing_list.py
@@ -1,31 +1,30 @@
from __future__ import unicode_literals
def repost_reserved_qty():
import webnotes
+ from webnotes.utils import flt
bins = webnotes.conn.sql("select item_code, warehouse, name, reserved_qty from `tabBin`")
for d in bins:
reserved_qty = webnotes.conn.sql("""
- select sum((dnpi.qty/so_item.qty)*(so_item.qty - ifnull(so_item.delivered_qty, 0))), so.transaction_date
+ select sum((dnpi.qty/so_item.qty)*(so_item.qty - ifnull(so_item.delivered_qty, 0)))
from `tabDelivery Note Packing Item` dnpi, `tabSales Order Item` so_item, `tabSales Order` so
- where dnpi.parent = so.name
+ where dnpi.item_code = %s
+ and dnpi.warehouse = %s
+ and dnpi.parent = so.name
and so_item.parent = so.name
and dnpi.parenttype = 'Sales Order'
and dnpi.parent_detail_docname = so_item.name
and dnpi.parent_item = so_item.item_code
and so.docstatus = 1
and so.status != 'Stopped'
- and dnpi.item_code = %s
- and dnpi.warehouse = %s
""", (d[0], d[1]))
if flt(d[3]) != flt(reserved_qty[0][0]):
- print d, reserved_qty
- #webnotes.conn.sql("""
- # update `tabBin` set reserved_qty = %s where name = %s
- #""", (reserved_qty and reserved_qty[0][0] or 0, d[2]))
+ print d[3], reserved_qty[0][0]
+ webnotes.conn.sql("""
+ update `tabBin` set reserved_qty = %s where name = %s
+ """, (reserved_qty and reserved_qty[0][0] or 0, d[2]))
-repost_reserved_qty()
-
def cleanup_wrong_sle():
sle = webnotes.conn.sql("""
select item_code, warehouse, voucher_no, name
@@ -45,10 +44,10 @@ def cleanup_wrong_sle():
""")
if sle:
print sle
- # for d in sle:
- # webnotes.conn.sql("update `tabStock Ledger Entry` set is_cancelled = 'Yes' where name = %s", d[3])
- # create_comment(d[3])
- # repost_bin(d[0], d[1])
+ for d in sle:
+ webnotes.conn.sql("update `tabStock Ledger Entry` set is_cancelled = 'Yes' where name = %s", d[3])
+ create_comment(d[3])
+ repost_bin(d[0], d[1])
def create_comment(dn):
from webnotes.model.doc import Document
diff --git a/erpnext/patches/patch_list.py b/erpnext/patches/patch_list.py
index 14d56a0e93..38b22e8166 100644
--- a/erpnext/patches/patch_list.py
+++ b/erpnext/patches/patch_list.py
@@ -529,4 +529,8 @@ patch_list = [
'patch_module': 'patches.july_2012',
'patch_file': 'bin_permission',
},
+ {
+ 'patch_module': 'patches.july_2012',
+ 'patch_file': 'project_patch_repeat',
+ },
]
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project_control/project_control.py b/erpnext/projects/doctype/project_control/project_control.py
index 5ebc19ee4b..8369aabbf1 100644
--- a/erpnext/projects/doctype/project_control/project_control.py
+++ b/erpnext/projects/doctype/project_control/project_control.py
@@ -156,7 +156,6 @@ def sent_reminder_task():
If you have already completed this task, please update the system
Good Luck!
(This notification is autogenerated)
""" % i
- sendmail(i['allocated_to'], sender='automail@webnotestech.com', msg=msg2,send_now=1, \
- subject='A task has been assigned')
+ sendmail(i['allocated_to'], msg=msg2, subject='A task has been assigned')
sql("update `tabTask` set sent_reminder='1' where name='%(name)s' and allocated_to= '%(allocated_to)s'" % i)
diff --git a/erpnext/projects/doctype/task/task.py b/erpnext/projects/doctype/task/task.py
index 52ba36037c..5cc5270229 100644
--- a/erpnext/projects/doctype/task/task.py
+++ b/erpnext/projects/doctype/task/task.py
@@ -116,10 +116,7 @@ class DocType:
Expected End Date: %(exp_end_date)s
Details: %(description)s
(This notification is autogenerated)
""" % i
- sendmail(self.doc.allocated_to, sender='automail@webnotestech.com', msg=msg2,send_now=1,\
- subject= task_label + self.doc.subject)
-
-
+ sendmail(self.doc.allocated_to, msg=msg2,subject= task_label + self.doc.subject)
#validate before closing task
def validate_for_closed(self):
diff --git a/erpnext/selling/doctype/lead/lead.js b/erpnext/selling/doctype/lead/lead.js
index 57f2bee185..504b0bdc7a 100644
--- a/erpnext/selling/doctype/lead/lead.js
+++ b/erpnext/selling/doctype/lead/lead.js
@@ -110,16 +110,6 @@ cur_frm.cscript['Create Customer'] = function(){
);
}
-// send email
-// ===============================================================
-cur_frm.cscript.send_email = function(doc,cdt,cdn){
- if(doc.__islocal != 1){
- $c_obj(make_doclist(doc.doctype, doc.name),'send_mail','',function(r,rt){});
- }else{
- msgprint("Please save lead first before sending email")
- }
-}
-
// Create New Opportunity
// ===============================================================
cur_frm.cscript['Create Opportunity'] = function(){
diff --git a/erpnext/selling/doctype/lead/lead.py b/erpnext/selling/doctype/lead/lead.py
index f0e85e92e6..ddccbc1d7f 100644
--- a/erpnext/selling/doctype/lead/lead.py
+++ b/erpnext/selling/doctype/lead/lead.py
@@ -83,15 +83,9 @@ class DocType:
def on_update(self):
- # Add to calendar
- # ========================================================================
if self.doc.contact_by:
self.add_calendar_event()
- if session['user'] == 'Guest':
- if self.doc.email_id:
- self.send_email_notification()
-
if not self.doc.naming_series:
if session['user'] == 'Guest':
import webnotes.model.doctype
@@ -103,37 +97,6 @@ class DocType:
else:
msgprint("Please specify naming series")
raise Exception
-
- def send_email_notification(self):
- if not validate_email_add(self.doc.email_id.strip(' ')):
- msgprint('error:%s is not a valid email id' % self.doc.email_id.strip(' '))
- raise Exception
- else:
- subject = 'Thank you for interest in erpnext'
-
- sendmail([self.doc.email_id.strip(' ')], sender = sender_email[0][0], subject = subject , parts = [['text/html', self.get_notification_msg()]])
- msgprint("Mail Sent")
-
- def get_notification_msg(self):
- t = """
-
-
- Dear %s,
-
- Thank you for contacting us.
-
- You have left following message for us,
- %s
-
-
- You will receive reply on this shortly.
-
- Cheers!
-
-
- """ % (self.doc.lead_name, self.doc.remark)
-
- return t
# Add to Calendar
# ===========================================================================
@@ -158,25 +121,6 @@ class DocType:
ev.ref_name = self.doc.name
ev.save(1)
-
-#-----------------Email--------------------------------------------
- def send_emails(self, email=[], subject='', message=''):
- if email:
- sendmail(email, sender = webnotes.user.name, subject = subject , parts = [['text/html', message]])
- msgprint("Mail Sent")
- self.add_in_follow_up(message,'Email')
-
-#-------------------------Checking Sent Mails Details----------------------------------------------
- def send_mail(self):
- if not self.doc.subject or not self.doc.message:
- msgprint("Please enter subject & message in their respective fields.")
- elif not self.doc.email_id:
- msgprint("Recipient not specified. Please add email id of lead in 'Email id' field provided in 'Contact Info' section.")
- raise Exception
- else :
- self.send_emails([self.doc.email_id.strip(' ')], subject = self.doc.subject ,message = self.doc.message)
-
-#---------------------- 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)
diff --git a/erpnext/selling/doctype/lead/lead.txt b/erpnext/selling/doctype/lead/lead.txt
index b6aa8397d7..056fc16bae 100644
--- a/erpnext/selling/doctype/lead/lead.txt
+++ b/erpnext/selling/doctype/lead/lead.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-05-15 12:14:52',
+ 'creation': '2012-06-05 20:03:20',
'docstatus': 0,
- 'modified': '2012-05-30 12:43:03',
+ 'modified': '2012-08-03 10:49:22',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -505,23 +505,6 @@
'permlevel': 0
},
- # DocField
- {
- 'colour': u'White:FFF',
- 'description': u'Probability of lead converting to customer',
- 'doctype': u'DocField',
- 'fieldname': u'rating',
- 'fieldtype': u'Select',
- 'in_filter': 1,
- 'label': u'Rating',
- 'oldfieldname': u'rating',
- 'oldfieldtype': u'Select',
- 'options': u'\nHot\nWarm\nCold',
- 'permlevel': 0,
- 'reqd': 0,
- 'search_index': 0
- },
-
# DocField
{
'default': u'__user',
@@ -694,5 +677,23 @@
'oldfieldtype': u'Small Text',
'permlevel': 1,
'print_hide': 1
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'unsubscribed',
+ 'fieldtype': u'Check',
+ 'label': u'Unsubscribed',
+ 'permlevel': 0
+ },
+
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'blog_subscriber',
+ 'fieldtype': u'Check',
+ 'label': u'Blog Subscriber',
+ 'permlevel': 0
}
]
\ No newline at end of file
diff --git a/erpnext/selling/doctype/lead/lead_list.js b/erpnext/selling/doctype/lead/lead_list.js
index ca18dc6941..b876d52cbb 100644
--- a/erpnext/selling/doctype/lead/lead_list.js
+++ b/erpnext/selling/doctype/lead/lead_list.js
@@ -4,8 +4,7 @@ wn.doclistviews['Lead'] = wn.views.ListView.extend({
this.fields = this.fields.concat([
'tabLead.lead_name',
'tabLead.status',
- 'tabLead.source',
- 'tabLead.rating'
+ 'tabLead.source'
]);
this.stats = this.stats.concat(['status', 'source', 'rating', 'company']);
},
diff --git a/erpnext/selling/doctype/opportunity/opportunity.py b/erpnext/selling/doctype/opportunity/opportunity.py
index 0a53cf0bc3..c3a6fb7596 100644
--- a/erpnext/selling/doctype/opportunity/opportunity.py
+++ b/erpnext/selling/doctype/opportunity/opportunity.py
@@ -198,118 +198,7 @@ class DocType(TransactionBase):
set(self.doc, 'status', 'Opportunity Lost')
set(self.doc, 'order_lost_reason', arg)
return 'true'
-
-
- # On Send Email
- # ====================================================================================================================
- #def send_emails(self,email,sender,subject,message):
- # if email:
- # sendmail(email,sender,subject=subject or 'Opportunity',parts=[['text/plain',message or self.get_enq_summary()]])
-
- # Prepare HTML Table and Enter Opportunity Items in it, which will be added in enq summary
- # ====================================================================================================================
- def quote_table(self):
- if getlist(self.doclist,'enq_details'):
- header_lbl = ['Item Code','Item Name','Description','Reqd Qty','UOM']
- item_tbl = ''''''
- for i in header_lbl:
- item_header = '''%s ''' % i
- item_tbl += item_header
- item_tbl += ''' '''
-
- for d in getlist(self.doclist,'enq_details'):
- item_det = '''
- %s
- %s
- %s
- %s
- %s
- ''' % (d.item_code,d.item_name,d.description,d.reqd_qty,d.uom)
- item_tbl += item_det
- item_tbl += '''
'''
- return item_tbl
-
- # Prepare HTML Page containing summary of Opportunity, which will be sent as message in E-mail
- # ====================================================================================================================
- def get_enq_summary(self):
-
- t = """
-
-
-
-
Request For Quotation
-
%(from_company)s
-
%(company_address)s
-
-
-
Quotation Items
-
- Opportunity No: %(name)s
- Opening Date: %(transaction_date)s
- Expected By Date: %(expected_date)s
-
-
-
-
Terms and Conditions
-
%(terms_and_conditions)s
-
-
Contact Details
-
- Contact Person: %(contact_person)s
- Contact No: %(contact_no)s
- Email: %(email)s
-
- """ % (self.doc.fields)
-
- t += """
Quotation Items
%s
-
-To login into the system, use link :
-
-
-
- """ % (self.quote_table())
- return t
-
- #-----------------Email--------------------------------------------
- # ====================================================================================================================
- def send_emails(self, email=[], subject='', message=''):
- if email:
- sender_email= sql("Select email from `tabProfile` where name='%s'"%session['user'])
- if sender_email and sender_email[0][0]:
- attach_list=[]
- for at in getlist(self.doclist,'enquiry_attachment_detail'):
- if at.select_file:
- attach_list.append(at.select_file)
- cc_list=[]
- if self.doc.cc_to:
- for cl in (self.doc.cc_to.split(',')):
- if not validate_email_add(cl.strip(' ')):
- msgprint('error:%s is not a valid email id' % cl.strip(' '))
- raise Exception
- cc_list.append(cl.strip(' '))
- sendmail(cc_list, sender=sender_email[0][0], subject=subject, parts=[['text/html', message]], attach=attach_list)
- sendmail(email, sender=sender_email[0][0], subject=subject, parts=[['text/html', message]], cc=cc_list, attach=attach_list)
- #sendmail(cc_list, sender = sender_email[0][0], subject = subject , parts = [['text/html', message]],attach=attach_list)
- msgprint("Mail has been sent")
- self.add_in_follow_up(message,'Email')
- else:
- msgprint("Please enter your mail id in Profile")
- raise Exception
-
- #-------------------------Checking Sent Mails Details----------------------------------------------
- # ====================================================================================================================
- def sent_mail(self):
- if not self.doc.subject or not self.doc.message:
- msgprint("Please enter subject & message in their respective fields.")
- elif not self.doc.email_id1:
- msgprint("Recipient not specified. Please add email id in 'Send To'.")
- raise Exception
- else :
- if not validate_email_add(self.doc.email_id1.strip(' ')):
- msgprint('error:%s is not a valid email id' % self.doc.email_id1)
- else:
- self.send_emails([self.doc.email_id1.strip(' ')], subject = self.doc.subject ,message = self.doc.message)
-
+
#---------------------- Add details in follow up table----------------
# ====================================================================================================================
def add_in_follow_up(self,message,type):
diff --git a/erpnext/setup/doctype/email_digest/email_digest.py b/erpnext/setup/doctype/email_digest/email_digest.py
index e8d3bad0a7..3e3f55a645 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.py
+++ b/erpnext/setup/doctype/email_digest/email_digest.py
@@ -416,7 +416,6 @@ class DocType:
from webnotes.utils.email_lib import sendmail
try:
- #webnotes.msgprint('in send')
sendmail(
recipients=recipient_list,
sender='notifications+email_digest@erpnext.com',
diff --git a/erpnext/setup/doctype/email_settings/email_settings.py b/erpnext/setup/doctype/email_settings/email_settings.py
index ed8134a094..e17f55cb1c 100644
--- a/erpnext/setup/doctype/email_settings/email_settings.py
+++ b/erpnext/setup/doctype/email_settings/email_settings.py
@@ -25,44 +25,25 @@ class DocType:
self.doc,self.doclist = doc,doclist
def validate(self):
- """
- Checks connectivity to email servers before saving
- """
+ """Checks connectivity to email servers before saving"""
self.validate_outgoing()
self.validate_incoming()
-
def validate_outgoing(self):
- """
- Checks incoming email settings
- """
+ """Checks incoming email settings"""
+ self.doc.encode()
if self.doc.outgoing_mail_server:
- from webnotes.utils import cint, get_encoded_string
- import _socket
- from webnotes.utils.email_lib.send import EMail
- import smtplib
- out_email = EMail()
- out_email.server = get_encoded_string(self.doc.outgoing_mail_server)
- out_email.port = cint(self.doc.mail_port)
- out_email.use_ssl = self.doc.use_ssl
- try:
- err_msg = "Login Id or Mail Password missing. Please enter and try again."
- if not (self.doc.mail_login and self.doc.mail_password):
- raise AttributeError, err_msg
- out_email.login = get_encoded_string(self.doc.mail_login)
- out_email.password = get_encoded_string(self.doc.mail_password)
- except AttributeError, e:
- webnotes.msgprint(err_msg)
- raise e
-
- # exceptions are handled in smtp_connect
- sess = out_email.smtp_connect()
-
- try:
- sess.quit()
- except:
- pass
-
+ from webnotes.utils import cint
+ from webnotes.utils.email_lib.smtp import SMTPServer
+ smtpserver = SMTPServer(login = self.doc.mail_login,
+ password = self.doc.mail_password,
+ server = self.doc.outgoing_mail_server,
+ port = cint(self.doc.mail_port),
+ use_ssl = self.doc.use_ssl
+ )
+
+ # exceptions are handled in session connect
+ sess = smtpserver.sess
def validate_incoming(self):
"""
@@ -72,17 +53,17 @@ class DocType:
from webnotes.utils.email_lib.receive import POP3Mailbox
from webnotes.model.doc import Document
import _socket, poplib
- from webnotes.utils import get_encoded_string
inc_email = Document('Incoming Email Settings')
- inc_email.host = get_encoded_string(self.doc.support_host)
+ inc_email.encode()
+ inc_email.host = self.doc.support_host
inc_email.use_ssl = self.doc.support_use_ssl
try:
err_msg = 'User Name or Support Password missing. Please enter and try again.'
if not (self.doc.support_username and self.doc.support_password):
raise AttributeError, err_msg
- inc_email.username = get_encoded_string(self.doc.support_username)
- inc_email.password = get_encoded_string(self.doc.support_password)
+ inc_email.username = self.doc.support_username
+ inc_email.password = self.doc.support_password
except AttributeError, e:
webnotes.msgprint(err_msg)
raise e
diff --git a/erpnext/startup/__init__.py b/erpnext/startup/__init__.py
index 42a23ab18b..c763d9c054 100644
--- a/erpnext/startup/__init__.py
+++ b/erpnext/startup/__init__.py
@@ -14,14 +14,23 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-
# default settings that can be made for a profile.
from __future__ import unicode_literals
-import webnotes
product_name = "ERPNext"
profile_defaults = {
"Company": "company",
"Territory": "territory"
}
-
\ No newline at end of file
+
+# add startup propertes
+mail_footer = """"""
+
+def get_monthly_bulk_mail_limit():
+ import webnotes
+ # if global settings, then 500 or unlimited
+ if webnotes.conn.get_value('Email Settings', None, 'outgoing_mail_server'):
+ return 999999
+ else:
+ return 500
diff --git a/erpnext/startup/schedule_handlers.py b/erpnext/startup/schedule_handlers.py
index 179586ffac..424482b2af 100644
--- a/erpnext/startup/schedule_handlers.py
+++ b/erpnext/startup/schedule_handlers.py
@@ -25,27 +25,26 @@ def execute_all():
* get support email
* recurring invoice
"""
- try:
- from support.doctype.support_ticket import get_support_mails
- get_support_mails()
- except Exception, e:
- scheduler.log('get_support_mails')
-
- try:
- from accounts.doctype.gl_control.gl_control import manage_recurring_invoices
- manage_recurring_invoices()
- except Exception, e:
- scheduler.log('manage_recurring_invoices')
+ # pull emails
+ from support.doctype.support_ticket import get_support_mails
+ run_fn(get_support_mails)
+ # run recurring invoices
+ from accounts.doctype.gl_control.gl_control import manage_recurring_invoices
+ run_fn(manage_recurring_invoices)
+ # bulk email
+ from webnotes.utils.email_lib.bulk import flush
+ run_fn(flush)
def execute_daily():
- """email digest"""
- try:
- from setup.doctype.email_digest.email_digest import send
- send()
- except Exception, e:
- scheduler.log('email_digest.send')
+ # email digest
+ from setup.doctype.email_digest.email_digest import send
+ run_fn(send)
+
+ # send bulk emails
+ from webnotes.utils.email_lib.bulk import clear_outbox
+ run_fn(clear_outbox)
def execute_weekly():
pass
@@ -55,3 +54,9 @@ def execute_monthly():
def execute_hourly():
pass
+
+def run_fn(fn):
+ try:
+ fn()
+ except Exception, e:
+ scheduler.log(fn.func_name)
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index ce6ef3eba4..6a3914fdf6 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -182,27 +182,6 @@ class DocType:
self.doc.is_asset_item = 'No'
raise Exception
- def check_min_inventory_level(self):
- if self.doc.minimum_inventory_level:
- total_qty = sql("select sum(projected_qty) from tabBin where item_code = %s",self.doc.name)
- if flt(total_qty) < flt(self.doc.minimum_inventory_level):
- msgprint("Your minimum inventory level is reached")
- send_to = []
- send = sql("select t1.email from `tabProfile` t1,`tabUserRole` t2 where t2.role IN ('Material Master Manager','Purchase Manager') and t2.parent = t1.name")
- for d in send:
- send_to.append(d[0])
- msg = '''
-Minimum Inventory Level Reached
-
-Item Code: %s
-Item Name: %s
-Minimum Inventory Level: %s
-Total Available Qty: %s
-
-''' % (self.doc.item_code, self.doc.item_name, self.doc.minimum_inventory_level, total_qty)
-
- sendmail(send_to, sender='automail@webnotestech.com', subject='Minimum Inventory Level Reached', parts=[['text/plain', msg]])
-
def get_file_details(self, arg = ''):
file = sql("select file_group, description from tabFile where name = %s", eval(arg)['file_name'], as_dict = 1)
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 1cd40815db..d922a11b45 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -79,9 +79,8 @@ class DocType:
def get_reconciliation_data(self,submit = 1):
"""Read and validate csv data"""
import csv
- from webnotes.utils import get_encoded_string
from core.page.data_import_tool.data_import_tool import read_csv_content
- csv_content = get_encoded_string(self.get_csv_file_data(submit))
+ csv_content = self.get_csv_file_data(submit).encode('utf-8')
data = read_csv_content(csv_content)
self.convert_into_list(data, submit)
diff --git a/erpnext/utilities/doctype/contact/contact.txt b/erpnext/utilities/doctype/contact/contact.txt
index 135699b768..baa2a775ee 100644
--- a/erpnext/utilities/doctype/contact/contact.txt
+++ b/erpnext/utilities/doctype/contact/contact.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-07-02 19:57:48',
+ 'creation': '2012-07-03 14:22:38',
'docstatus': 0,
- 'modified': '2012-07-03 12:54:52',
+ 'modified': '2012-08-02 13:16:48',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -38,133 +38,12 @@
'parenttype': u'DocType'
},
- # These values are common for all DocPerm
- {
- 'doctype': u'DocPerm',
- 'name': '__common__',
- 'parent': u'Contact',
- 'parentfield': u'permissions',
- 'parenttype': u'DocType',
- 'read': 1
- },
-
# DocType, Contact
{
'doctype': 'DocType',
'name': u'Contact'
},
- # DocPerm
- {
- 'cancel': 1,
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'System Manager',
- 'write': 1
- },
-
- # DocPerm
- {
- 'amend': 0,
- 'cancel': 1,
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Sales Master Manager',
- 'submit': 0,
- 'write': 1
- },
-
- # DocPerm
- {
- 'cancel': 1,
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Purchase Master Manager',
- 'write': 1
- },
-
- # DocPerm
- {
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Sales Manager',
- 'write': 1
- },
-
- # DocPerm
- {
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Purchase Manager',
- 'write': 1
- },
-
- # DocPerm
- {
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Maintenance Manager',
- 'write': 1
- },
-
- # DocPerm
- {
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Accounts Manager',
- 'write': 1
- },
-
- # DocPerm
- {
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Sales User',
- 'write': 1
- },
-
- # DocPerm
- {
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Purchase User',
- 'write': 1
- },
-
- # DocPerm
- {
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Maintenance User',
- 'write': 1
- },
-
- # DocPerm
- {
- 'create': 1,
- 'doctype': u'DocPerm',
- 'permlevel': 0,
- 'role': u'Accounts User',
- 'write': 1
- },
-
- # DocPerm
- {
- 'doctype': u'DocPerm',
- 'permlevel': 1,
- 'role': u'All'
- },
-
# DocField
{
'colour': u'White:FFF',
@@ -356,6 +235,15 @@
'permlevel': 0
},
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'unsubscribed',
+ 'fieldtype': u'Check',
+ 'label': u'Unsubscribed',
+ 'permlevel': 0
+ },
+
# DocField
{
'doctype': u'DocField',
diff --git a/erpnext/website/blog.py b/erpnext/website/blog.py
index 87945ab1ef..1ebea29d7c 100644
--- a/erpnext/website/blog.py
+++ b/erpnext/website/blog.py
@@ -107,6 +107,25 @@ def add_comment(args=None):
return comment_html
+@webnotes.whitelist(allow_guest=True)
+def add_subscriber():
+ """add blog subscriber to lead"""
+ full_name = webnotes.form_dict.get('your_name')
+ email = webnotes.form_dict.get('your_email_address')
+ name = webnotes.conn.sql("""select name from tabLead where email_id=%s""", email)
+
+ from webnotes.model.doc import Document
+ if name:
+ lead = Document('Lead', name[0][0])
+ else:
+ lead = Document('Lead')
+
+ lead.unsubscribed = 0
+ lead.blog_subscriber = 1
+ lead.lead_name = full_name
+ lead.email_id = email
+ lead.save()
+
def get_blog_content(blog_page_name):
import website.web_cache
content = website.web_cache.get_html(blog_page_name)
diff --git a/erpnext/website/page/unsubscribe/unsubscribe.js b/erpnext/website/doctype/blog/blog.js
similarity index 59%
rename from erpnext/website/page/unsubscribe/unsubscribe.js
rename to erpnext/website/doctype/blog/blog.js
index 9e83020a98..b0c1ec284d 100644
--- a/erpnext/website/page/unsubscribe/unsubscribe.js
+++ b/erpnext/website/doctype/blog/blog.js
@@ -14,24 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-pscript.onload_unsubscribe = function(wrapper) {
- var email = window.location.hash.split('/').splice(-1);
- $(wrapper).find('input[name="unsubscribe"]').val(email)
-
- $('#btn-unsubscribe').click(function() {
- var email = $(wrapper).find('input[name="unsubscribe"]').val();
- if(email) {
- var btn = this;
- wn.call({
- module:'website',
- page:'unsubscribe',
- method:'unsubscribe',
- args:email,
- btn: this,
- callback: function() {
- $(wrapper).find('input[name="unsubscribe"]').val('');
- }
+cur_frm.cscript.refresh = function(doc) {
+ if(!doc.__islocal && doc.published && !doc.email_sent) {
+ cur_frm.add_custom_button('Email Subscribers', function() {
+ $c_obj(make_doclist(doc.doctype, doc.name), 'send_emails', '', function(r) {
+ cur_frm.refresh();
});
- }
- });
+ })
+ }
}
\ No newline at end of file
diff --git a/erpnext/website/doctype/blog/blog.py b/erpnext/website/doctype/blog/blog.py
index 6ccab0b7a5..c1b25f6971 100644
--- a/erpnext/website/doctype/blog/blog.py
+++ b/erpnext/website/doctype/blog/blog.py
@@ -30,6 +30,31 @@ class DocType(website.web_page.Page):
super(DocType, self).__init__('Blog')
self.doc, self.doclist = d, dl
+ def send_emails(self):
+ """send emails to subscribers"""
+ if self.doc.email_sent:
+ webnotes.msgprint("""Blog Subscribers already updated""", raise_exception=1)
+
+ from webnotes.utils.email_lib.bulk import send
+ from markdown2 import markdown
+ import webnotes.utils
+
+ # get leads that are subscribed to the blog
+ recipients = [e[0] for e in webnotes.conn.sql("""select distinct email_id from tabLead where
+ ifnull(blog_subscriber,0)=1""")]
+
+ # make heading as link
+ content = '\n\n%s' % (webnotes.utils.get_request_site_address(),
+ self.doc.page_name, self.doc.title, markdown(self.doc.content))
+
+ # send the blog
+ send(recipients = recipients, doctype='Lead', email_field='email_id',
+ first_name_field = 'lead_name', last_name_field="", subject=self.doc.title,
+ message = markdown(content))
+
+ webnotes.conn.set(self.doc, 'email_sent', 1)
+ webnotes.msgprint("""Scheduled to send to %s subscribers""" % len(recipients))
+
def on_update(self):
super(DocType, self).on_update()
if not webnotes.utils.cint(self.doc.published):
diff --git a/erpnext/website/doctype/blog/blog.txt b/erpnext/website/doctype/blog/blog.txt
index 6ed7143b2d..35d31c67d9 100644
--- a/erpnext/website/doctype/blog/blog.txt
+++ b/erpnext/website/doctype/blog/blog.txt
@@ -3,9 +3,9 @@
# These values are common in all dictionaries
{
- 'creation': '2012-07-13 13:02:27',
+ 'creation': '2012-07-27 19:32:53',
'docstatus': 0,
- 'modified': '2012-07-27 14:15:24',
+ 'modified': '2012-08-03 12:18:36',
'modified_by': u'Administrator',
'owner': u'Administrator'
},
@@ -113,6 +113,16 @@
'permlevel': 1
},
+ # DocField
+ {
+ 'doctype': u'DocField',
+ 'fieldname': u'email_sent',
+ 'fieldtype': u'Check',
+ 'hidden': 1,
+ 'label': u'Email Sent',
+ 'permlevel': 0
+ },
+
# DocField
{
'doctype': u'DocField',
diff --git a/erpnext/website/doctype/blog_subscriber/blog_subscriber.txt b/erpnext/website/doctype/blog_subscriber/blog_subscriber.txt
deleted file mode 100644
index 1fa8223cd0..0000000000
--- a/erpnext/website/doctype/blog_subscriber/blog_subscriber.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-# DocType, Blog Subscriber
-[
-
- # These values are common in all dictionaries
- {
- 'creation': '2012-03-27 14:36:47',
- 'docstatus': 0,
- 'modified': '2012-03-27 14:36:47',
- 'modified_by': u'Administrator',
- 'owner': u'Administrator'
- },
-
- # These values are common for all DocType
- {
- 'colour': u'White:FFF',
- 'doctype': 'DocType',
- 'module': u'Website',
- 'name': '__common__',
- 'section_style': u'Simple',
- 'show_in_menu': 0,
- 'version': 1
- },
-
- # DocType, Blog Subscriber
- {
- 'doctype': 'DocType',
- 'name': u'Blog Subscriber'
- }
-]
\ No newline at end of file
diff --git a/erpnext/website/page/unsubscribe/unsubscribe.html b/erpnext/website/page/unsubscribe/unsubscribe.html
deleted file mode 100644
index 7b2b68ee9c..0000000000
--- a/erpnext/website/page/unsubscribe/unsubscribe.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
Unsubscribe
-
-
-
- Unsubscribe
-
-
-
-
-
-
\ No newline at end of file
diff --git a/erpnext/website/page/unsubscribe/unsubscribe.txt b/erpnext/website/page/unsubscribe/unsubscribe.txt
deleted file mode 100644
index 2cc3b58a35..0000000000
--- a/erpnext/website/page/unsubscribe/unsubscribe.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-# Page, unsubscribe
-[
-
- # These values are common in all dictionaries
- {
- 'creation': '2012-01-27 17:19:02',
- 'docstatus': 0,
- 'modified': '2012-01-27 17:19:02',
- 'modified_by': 'Administrator',
- 'owner': 'Administrator'
- },
-
- # These values are common for all Page
- {
- 'doctype': 'Page',
- 'module': 'Website',
- 'name': '__common__',
- 'page_name': 'unsubscribe',
- 'standard': 'Yes',
- 'title': 'Unsubscribe'
- },
-
- # These values are common for all Page Role
- {
- 'doctype': 'Page Role',
- 'name': '__common__',
- 'parent': 'unsubscribe',
- 'parentfield': 'roles',
- 'parenttype': 'Page',
- 'role': 'Guest'
- },
-
- # Page, unsubscribe
- {
- 'doctype': 'Page',
- 'name': 'unsubscribe'
- },
-
- # Page Role
- {
- 'doctype': 'Page Role'
- }
-]
\ No newline at end of file
diff --git a/erpnext/website/templates/html/blog_page.html b/erpnext/website/templates/html/blog_page.html
index 3b8348d8a7..12a1c7ac85 100644
--- a/erpnext/website/templates/html/blog_page.html
+++ b/erpnext/website/templates/html/blog_page.html
@@ -2,6 +2,7 @@
{% block javascript %}
{% include "js/blog_page.js" %}
+ {% include "js/blog_subscribe.js" %}
{% endblock %}
{% block css %}
@@ -41,11 +42,9 @@
All Blogs
-
Subscribe
-
-
- RSS Feed
-
+ {% block blog_subscribe %}
+ {% include "html/blog_subscribe.html" %}
+ {% endblock %}
Recent Posts
diff --git a/erpnext/website/templates/html/blog_subscribe.html b/erpnext/website/templates/html/blog_subscribe.html
new file mode 100644
index 0000000000..7a4fd4954d
--- /dev/null
+++ b/erpnext/website/templates/html/blog_subscribe.html
@@ -0,0 +1,9 @@
+
Subscribe
+
+
+Get Updates via Email
+
+
+
+RSS Feed
+
\ No newline at end of file
diff --git a/erpnext/website/templates/js/blog_page.js b/erpnext/website/templates/js/blog_page.js
index 56dcf21b9d..02d6dd5377 100644
--- a/erpnext/website/templates/js/blog_page.js
+++ b/erpnext/website/templates/js/blog_page.js
@@ -59,8 +59,9 @@ erpnext.blog.render_recent_list = function(wrapper) {
hide_refresh: true,
render_row: function(parent, data) {
if(data.content && data.content.length>=100) data.content += '...';
- parent.innerHTML = repl('
%(title)s \
-
', data);
+ parent.innerHTML = repl('
', data);
// adjust page height depending on sidebar height
erpnext.blog.adjust_page_height(wrapper);
diff --git a/erpnext/website/templates/js/blog_subscribe.js b/erpnext/website/templates/js/blog_subscribe.js
new file mode 100644
index 0000000000..b3e10a7f70
--- /dev/null
+++ b/erpnext/website/templates/js/blog_subscribe.js
@@ -0,0 +1,33 @@
+wn.provide('erpnext.blog');
+
+(function() {
+ $('body').on('click', '.btn-blog-subscribe', function() {
+ var d = new wn.ui.Dialog({
+ title: "Get Blog Updates via Email",
+ fields: [
+ {label: "Your Name", fieldtype:"Data", reqd:1},
+ {label: "Your Email Address", fieldtype:"Data", reqd:1
+ ,description: "You can unsubscribe anytime."},
+ {label: "Subscribe", fieldtype:"Button"}
+ ]
+ });
+ $(d.fields_dict.subscribe.input).click(function() {
+ var args = d.get_values();
+ if(!args) return;
+ wn.call({
+ method: 'website.blog.add_subscriber',
+ args: args,
+ callback: function(r) {
+ if(r.exc) {
+ msgprint('Opps there seems to be some error, Please check back after some time.');
+ } else {
+ msgprint('Thanks for subscribing!');
+ }
+ d.hide();
+ },
+ btn: this
+ })
+ })
+ d.show()
+ })
+})()
diff --git a/erpnext/website/templates/pages/blog.html b/erpnext/website/templates/pages/blog.html
index 40c90c29a3..17fd6e7ba6 100644
--- a/erpnext/website/templates/pages/blog.html
+++ b/erpnext/website/templates/pages/blog.html
@@ -2,6 +2,7 @@
{% block javascript %}
{% include "js/blog.js" %}
+ {% include "js/blog_subscribe.js" %}
{% endblock %}
{% block css %}
@@ -23,17 +24,9 @@
-
-
Subscribe
-
-
- RSS Feed
-
+ {% block blog_subscribe %}
+ {% include "html/blog_subscribe.html" %}
+ {% endblock %}
diff --git a/erpnext/website/templates/pages/unsubscribed.html b/erpnext/website/templates/pages/unsubscribed.html
new file mode 100644
index 0000000000..3dc7df9e43
--- /dev/null
+++ b/erpnext/website/templates/pages/unsubscribed.html
@@ -0,0 +1,11 @@
+{% extends "html/outer.html" %}
+
+{% block content %}
+
+
+
Unsubscribed
+
+
{{ webnotes.unsubscribed_email }} has been unsubscribed.
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/erpnext/website/utils.py b/erpnext/website/utils.py
index 10ec88e0f9..5393a3d157 100644
--- a/erpnext/website/utils.py
+++ b/erpnext/website/utils.py
@@ -42,3 +42,37 @@ def page_name(title):
name = title.lower()
name = re.sub('[~!@#$%^&*()<>,."\']', '', name)
return '-'.join(name.split()[:4])
+
+def render(page_name):
+ """render html page"""
+ import webnotes
+ try:
+ if page_name:
+ html = get_html(page_name)
+ else:
+ html = get_html('index')
+ except Exception, e:
+ html = get_html('404')
+
+ from webnotes.handler import eprint, print_zip
+ eprint("Content-Type: text/html")
+ print_zip(html)
+
+def get_html(page_name):
+ """get page html"""
+ page_name = scrub_page_name(page_name)
+ comments = get_comments(page_name)
+
+ import website.web_cache
+ html = website.web_cache.get_html(page_name, comments)
+ return html
+
+def get_comments(page_name):
+ import webnotes
+
+ if page_name == '404':
+ comments = """error: %s""" % webnotes.getTraceback()
+ else:
+ comments = """page: %s""" % page_name
+
+ return comments
diff --git a/erpnext/website/web_cache.py b/erpnext/website/web_cache.py
index b0b5a34d6f..7b3de0aaef 100644
--- a/erpnext/website/web_cache.py
+++ b/erpnext/website/web_cache.py
@@ -92,6 +92,7 @@ def get_predefined_pages():
return page_list
def prepare_args(page_name):
+ import webnotes
if page_name == 'index':
page_name = get_home_page()
@@ -99,6 +100,7 @@ def prepare_args(page_name):
args = {
'template': 'pages/%s.html' % page_name,
'name': page_name,
+ 'webnotes': webnotes
}
else:
args = get_doc_fields(page_name)
diff --git a/public/js/all-app.js b/public/js/all-app.js
index 7b4febe796..e732d05cc7 100644
--- a/public/js/all-app.js
+++ b/public/js/all-app.js
@@ -869,7 +869,8 @@ opts.parent.appframe=new wn.ui.AppFrame($(opts.parent).find('.layout-appframe'))
* lib/js/wn/ui/dialog.js
*/
wn.widgets.FieldGroup=function(){this.first_button=false;this.make_fields=function(body,fl){if(!window.make_field){wn.require('css/fields.css');wn.require('js/fields.js');}
-$y(this.body,{padding:'11px'});this.fields_dict={};for(var i=0;i