Merge branch 'master' of github.com:webnotes/erpnext
This commit is contained in:
commit
b7cc66384d
@ -209,6 +209,7 @@ class DocType(TransactionBase):
|
|||||||
if ret['warehouse']:
|
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']))
|
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
|
ret['actual_qty']= actual_qty and flt(actual_qty[0][0]) or 0
|
||||||
|
msgprint(ret)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def get_barcode_details(self, barcode):
|
def get_barcode_details(self, barcode):
|
||||||
|
@ -1,30 +1,29 @@
|
|||||||
def repost_reserved_qty():
|
def repost_reserved_qty():
|
||||||
import webnotes
|
import webnotes
|
||||||
|
from webnotes.utils import flt
|
||||||
bins = webnotes.conn.sql("select item_code, warehouse, name, reserved_qty from `tabBin`")
|
bins = webnotes.conn.sql("select item_code, warehouse, name, reserved_qty from `tabBin`")
|
||||||
for d in bins:
|
for d in bins:
|
||||||
reserved_qty = webnotes.conn.sql("""
|
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
|
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 so_item.parent = so.name
|
||||||
and dnpi.parenttype = 'Sales Order'
|
and dnpi.parenttype = 'Sales Order'
|
||||||
and dnpi.parent_detail_docname = so_item.name
|
and dnpi.parent_detail_docname = so_item.name
|
||||||
and dnpi.parent_item = so_item.item_code
|
and dnpi.parent_item = so_item.item_code
|
||||||
and so.docstatus = 1
|
and so.docstatus = 1
|
||||||
and so.status != 'Stopped'
|
and so.status != 'Stopped'
|
||||||
and dnpi.item_code = %s
|
|
||||||
and dnpi.warehouse = %s
|
|
||||||
""", (d[0], d[1]))
|
""", (d[0], d[1]))
|
||||||
if flt(d[3]) != flt(reserved_qty[0][0]):
|
if flt(d[3]) != flt(reserved_qty[0][0]):
|
||||||
print d, reserved_qty
|
print d[3], reserved_qty[0][0]
|
||||||
#webnotes.conn.sql("""
|
webnotes.conn.sql("""
|
||||||
# update `tabBin` set reserved_qty = %s where name = %s
|
update `tabBin` set reserved_qty = %s where name = %s
|
||||||
#""", (reserved_qty and reserved_qty[0][0] or 0, d[2]))
|
""", (reserved_qty and reserved_qty[0][0] or 0, d[2]))
|
||||||
|
|
||||||
repost_reserved_qty()
|
|
||||||
|
|
||||||
def cleanup_wrong_sle():
|
def cleanup_wrong_sle():
|
||||||
sle = webnotes.conn.sql("""
|
sle = webnotes.conn.sql("""
|
||||||
select item_code, warehouse, voucher_no, name
|
select item_code, warehouse, voucher_no, name
|
||||||
@ -44,10 +43,10 @@ def cleanup_wrong_sle():
|
|||||||
""")
|
""")
|
||||||
if sle:
|
if sle:
|
||||||
print sle
|
print sle
|
||||||
# for d in sle:
|
for d in sle:
|
||||||
# webnotes.conn.sql("update `tabStock Ledger Entry` set is_cancelled = 'Yes' where name = %s", d[3])
|
webnotes.conn.sql("update `tabStock Ledger Entry` set is_cancelled = 'Yes' where name = %s", d[3])
|
||||||
# create_comment(d[3])
|
create_comment(d[3])
|
||||||
# repost_bin(d[0], d[1])
|
repost_bin(d[0], d[1])
|
||||||
|
|
||||||
def create_comment(dn):
|
def create_comment(dn):
|
||||||
from webnotes.model.doc import Document
|
from webnotes.model.doc import Document
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
{
|
{
|
||||||
'creation': '2012-06-05 20:03:20',
|
'creation': '2012-06-05 20:03:20',
|
||||||
'docstatus': 0,
|
'docstatus': 0,
|
||||||
'modified': '2012-08-02 18:01:53',
|
'modified': '2012-08-03 10:49:22',
|
||||||
'modified_by': u'Administrator',
|
'modified_by': u'Administrator',
|
||||||
'owner': u'Administrator'
|
'owner': u'Administrator'
|
||||||
},
|
},
|
||||||
@ -686,5 +686,14 @@
|
|||||||
'fieldtype': u'Check',
|
'fieldtype': u'Check',
|
||||||
'label': u'Unsubscribed',
|
'label': u'Unsubscribed',
|
||||||
'permlevel': 0
|
'permlevel': 0
|
||||||
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'blog_subscriber',
|
||||||
|
'fieldtype': u'Check',
|
||||||
|
'label': u'Blog Subscriber',
|
||||||
|
'permlevel': 0
|
||||||
}
|
}
|
||||||
]
|
]
|
@ -15,9 +15,13 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# add startup propertes
|
# add startup propertes
|
||||||
|
mail_footer = """<div style="padding: 7px; text-align: right; color: #888"><small>Sent via
|
||||||
add_in_head = """
|
<a style="color: #888" href="https://erpnext.com">ERPNext</a></div>"""
|
||||||
<style>
|
|
||||||
|
def get_monthly_bulk_mail_limit():
|
||||||
</style>
|
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
|
@ -42,7 +42,7 @@ def execute_daily():
|
|||||||
run_fn(send)
|
run_fn(send)
|
||||||
|
|
||||||
# send bulk emails
|
# send bulk emails
|
||||||
from webnotes.utils.email_lib.bulk import cleanup
|
from webnotes.utils.email_lib.bulk import clear_outbox
|
||||||
run_fn(clear_outbox)
|
run_fn(clear_outbox)
|
||||||
|
|
||||||
def execute_weekly():
|
def execute_weekly():
|
||||||
|
@ -106,6 +106,25 @@ def add_comment(args=None):
|
|||||||
|
|
||||||
return comment_html
|
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):
|
def get_blog_content(blog_page_name):
|
||||||
import website.web_cache
|
import website.web_cache
|
||||||
content = website.web_cache.get_html(blog_page_name)
|
content = website.web_cache.get_html(blog_page_name)
|
||||||
|
25
erpnext/website/doctype/blog/blog.js
Normal file
25
erpnext/website/doctype/blog/blog.js
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
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();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -29,6 +29,31 @@ class DocType(website.web_page.Page):
|
|||||||
super(DocType, self).__init__('Blog')
|
super(DocType, self).__init__('Blog')
|
||||||
self.doc, self.doclist = d, dl
|
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 = '<h2><a href="%s/%s.html">%s</a></h2>\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):
|
def on_update(self):
|
||||||
super(DocType, self).on_update()
|
super(DocType, self).on_update()
|
||||||
if not webnotes.utils.cint(self.doc.published):
|
if not webnotes.utils.cint(self.doc.published):
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
# These values are common in all dictionaries
|
# These values are common in all dictionaries
|
||||||
{
|
{
|
||||||
'creation': '2012-07-13 13:02:27',
|
'creation': '2012-07-27 19:32:53',
|
||||||
'docstatus': 0,
|
'docstatus': 0,
|
||||||
'modified': '2012-07-27 14:15:24',
|
'modified': '2012-08-03 12:18:36',
|
||||||
'modified_by': u'Administrator',
|
'modified_by': u'Administrator',
|
||||||
'owner': u'Administrator'
|
'owner': u'Administrator'
|
||||||
},
|
},
|
||||||
@ -113,6 +113,16 @@
|
|||||||
'permlevel': 1
|
'permlevel': 1
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# DocField
|
||||||
|
{
|
||||||
|
'doctype': u'DocField',
|
||||||
|
'fieldname': u'email_sent',
|
||||||
|
'fieldtype': u'Check',
|
||||||
|
'hidden': 1,
|
||||||
|
'label': u'Email Sent',
|
||||||
|
'permlevel': 0
|
||||||
|
},
|
||||||
|
|
||||||
# DocField
|
# DocField
|
||||||
{
|
{
|
||||||
'doctype': u'DocField',
|
'doctype': u'DocField',
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
{% block javascript %}
|
{% block javascript %}
|
||||||
{% include "js/blog_page.js" %}
|
{% include "js/blog_page.js" %}
|
||||||
|
{% include "js/blog_subscribe.js" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
@ -41,11 +42,9 @@
|
|||||||
<div class="layout-side-section">
|
<div class="layout-side-section">
|
||||||
<p><a href="blog.html">All Blogs</a></p>
|
<p><a href="blog.html">All Blogs</a></p>
|
||||||
<br />
|
<br />
|
||||||
<h4>Subscribe</h4>
|
{% block blog_subscribe %}
|
||||||
<p>
|
{% include "html/blog_subscribe.html" %}
|
||||||
<img src="images/feed.png" style="margin-right: 4px; margin-bottom: -4px">
|
{% endblock %}
|
||||||
<a href="rss.xml" target="_blank">RSS Feed</a>
|
|
||||||
</p>
|
|
||||||
<br />
|
<br />
|
||||||
<h4>Recent Posts</h4>
|
<h4>Recent Posts</h4>
|
||||||
<div class="recent-posts" style="min-height: 100px;"></div>
|
<div class="recent-posts" style="min-height: 100px;"></div>
|
||||||
|
9
erpnext/website/templates/html/blog_subscribe.html
Normal file
9
erpnext/website/templates/html/blog_subscribe.html
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<h4>Subscribe</h4>
|
||||||
|
<br>
|
||||||
|
<p>
|
||||||
|
<button class="btn btn-warning btn-blog-subscribe">Get Updates via Email</button>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<img src="images/feed.png" style="margin-right: 4px; margin-bottom: -4px">
|
||||||
|
<a href="rss.xml" target="_blank">RSS Feed</a>
|
||||||
|
</p>
|
@ -59,8 +59,9 @@ erpnext.blog.render_recent_list = function(wrapper) {
|
|||||||
hide_refresh: true,
|
hide_refresh: true,
|
||||||
render_row: function(parent, data) {
|
render_row: function(parent, data) {
|
||||||
if(data.content && data.content.length>=100) data.content += '...';
|
if(data.content && data.content.length>=100) data.content += '...';
|
||||||
parent.innerHTML = repl('<a href="%(page_name)s.html">%(title)s</a>\
|
parent.innerHTML = repl('<div style="font-size: 80%">\
|
||||||
<div class="comment">%(content)s</div><br>', data);
|
<a href="%(page_name)s.html">%(title)s</a>\
|
||||||
|
<div class="comment">%(content)s</div><br></div>', data);
|
||||||
|
|
||||||
// adjust page height depending on sidebar height
|
// adjust page height depending on sidebar height
|
||||||
erpnext.blog.adjust_page_height(wrapper);
|
erpnext.blog.adjust_page_height(wrapper);
|
||||||
|
33
erpnext/website/templates/js/blog_subscribe.js
Normal file
33
erpnext/website/templates/js/blog_subscribe.js
Normal file
@ -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()
|
||||||
|
})
|
||||||
|
})()
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
{% block javascript %}
|
{% block javascript %}
|
||||||
{% include "js/blog.js" %}
|
{% include "js/blog.js" %}
|
||||||
|
{% include "js/blog_subscribe.js" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
@ -23,17 +24,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="layout-side-section">
|
<div class="layout-side-section">
|
||||||
<!-- for later
|
{% block blog_subscribe %}
|
||||||
<h4>Get Updates</h4>
|
{% include "html/blog_subscribe.html" %}
|
||||||
<p>
|
{% endblock %}
|
||||||
<input name="blog-subscribe">
|
|
||||||
<button class="btn" id="blog-subscribe">Subscribe</button>
|
|
||||||
</p>-->
|
|
||||||
<h4>Subscribe</h4>
|
|
||||||
<p>
|
|
||||||
<img src="images/feed.png" style="margin-right: 4px; margin-bottom: -4px">
|
|
||||||
<a href="rss.xml" target="_blank">RSS Feed</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div style="clear: both"></div>
|
<div style="clear: both"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -870,7 +870,8 @@ opts.parent.appframe=new wn.ui.AppFrame($(opts.parent).find('.layout-appframe'))
|
|||||||
* lib/js/wn/ui/dialog.js
|
* 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');}
|
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<fl.length;i++){var df=fl[i];var div=$a(body,'div','',{margin:'6px 0px'})
|
$y(this.body,{padding:'11px'});this.fields_dict={};for(var i=0;i<fl.length;i++){var df=fl[i];if(!df.fieldname&&df.label){df.fieldname=df.label.replace(/ /g,'_').toLowerCase();}
|
||||||
|
var div=$a(body,'div','',{margin:'6px 0px'})
|
||||||
f=make_field(df,null,div,null);f.not_in_form=1;this.fields_dict[df.fieldname]=f
|
f=make_field(df,null,div,null);f.not_in_form=1;this.fields_dict[df.fieldname]=f
|
||||||
f.refresh();if(df.fieldtype=='Button'&&!this.first_button){$(f.input).addClass('btn-info');this.first_button=true;}}}
|
f.refresh();if(df.fieldtype=='Button'&&!this.first_button){$(f.input).addClass('btn-info');this.first_button=true;}}}
|
||||||
this.get_values=function(){var ret={};var errors=[];for(var key in this.fields_dict){var f=this.fields_dict[key];var v=f.get_value?f.get_value():null;if(f.df.reqd&&!v)
|
this.get_values=function(){var ret={};var errors=[];for(var key in this.fields_dict){var f=this.fields_dict[key];var v=f.get_value?f.get_value():null;if(f.df.reqd&&!v)
|
||||||
|
@ -529,7 +529,8 @@ opts.parent.appframe=new wn.ui.AppFrame($(opts.parent).find('.layout-appframe'))
|
|||||||
* lib/js/wn/ui/dialog.js
|
* 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');}
|
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<fl.length;i++){var df=fl[i];var div=$a(body,'div','',{margin:'6px 0px'})
|
$y(this.body,{padding:'11px'});this.fields_dict={};for(var i=0;i<fl.length;i++){var df=fl[i];if(!df.fieldname&&df.label){df.fieldname=df.label.replace(/ /g,'_').toLowerCase();}
|
||||||
|
var div=$a(body,'div','',{margin:'6px 0px'})
|
||||||
f=make_field(df,null,div,null);f.not_in_form=1;this.fields_dict[df.fieldname]=f
|
f=make_field(df,null,div,null);f.not_in_form=1;this.fields_dict[df.fieldname]=f
|
||||||
f.refresh();if(df.fieldtype=='Button'&&!this.first_button){$(f.input).addClass('btn-info');this.first_button=true;}}}
|
f.refresh();if(df.fieldtype=='Button'&&!this.first_button){$(f.input).addClass('btn-info');this.first_button=true;}}}
|
||||||
this.get_values=function(){var ret={};var errors=[];for(var key in this.fields_dict){var f=this.fields_dict[key];var v=f.get_value?f.get_value():null;if(f.df.reqd&&!v)
|
this.get_values=function(){var ret={};var errors=[];for(var key in this.fields_dict){var f=this.fields_dict[key];var v=f.get_value?f.get_value():null;if(f.df.reqd&&!v)
|
||||||
|
Loading…
Reference in New Issue
Block a user