diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py index ec327c7e1b..6a7fb0186e 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py @@ -209,6 +209,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/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 9e9da7f5ec..5900a0af56 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,30 +1,29 @@ 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 @@ -44,10 +43,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/selling/doctype/lead/lead.txt b/erpnext/selling/doctype/lead/lead.txt index a467f3af18..056fc16bae 100644 --- a/erpnext/selling/doctype/lead/lead.txt +++ b/erpnext/selling/doctype/lead/lead.txt @@ -5,7 +5,7 @@ { 'creation': '2012-06-05 20:03:20', 'docstatus': 0, - 'modified': '2012-08-02 18:01:53', + 'modified': '2012-08-03 10:49:22', 'modified_by': u'Administrator', 'owner': u'Administrator' }, @@ -686,5 +686,14 @@ '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/startup/__init__.py b/erpnext/startup/__init__.py index 354989808d..cd443a082c 100644 --- a/erpnext/startup/__init__.py +++ b/erpnext/startup/__init__.py @@ -15,9 +15,13 @@ # along with this program. If not, see . # add startup propertes - -add_in_head = """ - -""" \ No newline at end of file +mail_footer = """
Sent via + ERPNext
""" + +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 \ No newline at end of file diff --git a/erpnext/startup/schedule_handlers.py b/erpnext/startup/schedule_handlers.py index 021cb1f600..2df7a5789d 100644 --- a/erpnext/startup/schedule_handlers.py +++ b/erpnext/startup/schedule_handlers.py @@ -42,7 +42,7 @@ def execute_daily(): run_fn(send) # send bulk emails - from webnotes.utils.email_lib.bulk import cleanup + from webnotes.utils.email_lib.bulk import clear_outbox run_fn(clear_outbox) def execute_weekly(): diff --git a/erpnext/website/blog.py b/erpnext/website/blog.py index 5692f51f43..ea1992b1fe 100644 --- a/erpnext/website/blog.py +++ b/erpnext/website/blog.py @@ -106,6 +106,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/doctype/blog/blog.js b/erpnext/website/doctype/blog/blog.js new file mode 100644 index 0000000000..b0c1ec284d --- /dev/null +++ b/erpnext/website/doctype/blog/blog.js @@ -0,0 +1,25 @@ +// 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 . + +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 e361ece996..786941c7e1 100644 --- a/erpnext/website/doctype/blog/blog.py +++ b/erpnext/website/doctype/blog/blog.py @@ -29,6 +29,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 = '

%s

\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/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

+
+

+ +

+

+ +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\ -
%(content)s

', data); + parent.innerHTML = repl('
\ + %(title)s\ +
%(content)s

', 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/public/js/all-app.js b/public/js/all-app.js index f7fc897a7f..df69de633f 100644 --- a/public/js/all-app.js +++ b/public/js/all-app.js @@ -870,7 +870,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