Merge branch 'master' of github.com:webnotes/erpnext

This commit is contained in:
Nabin Hait 2013-03-07 18:50:23 +05:30
commit 0e6ce9af17
14 changed files with 239 additions and 102 deletions

View File

@ -16,7 +16,7 @@
from __future__ import unicode_literals
import webnotes
from webnotes.utils import flt, cstr
from webnotes.utils import flt, cstr, now
from webnotes.model.doc import Document
def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True,
@ -109,5 +109,7 @@ def validate_total_debit_credit(total_debit, total_credit):
(total_debit - total_credit), raise_exception=1)
def set_as_cancel(voucher_type, voucher_no):
webnotes.conn.sql("""update `tabGL Entry` set is_cancelled='Yes'
where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no))
webnotes.conn.sql("""update `tabGL Entry` set is_cancelled='Yes',
modified=%s, modified_by=%s
where voucher_type=%s and voucher_no=%s""",
(now(), webnotes.session.user, voucher_type, voucher_no))

View File

@ -71,9 +71,11 @@ erpnext.FinancialAnalytics = erpnext.AccountTreeGrid.extend({
setup_filters: function() {
var me = this;
this._super();
this.filter_inputs.pl_or_bs.change(function() {
me.filter_inputs.refresh.click();
}).add_options($.map(wn.report_dump.data["Cost Center"], function(v) {return v.name;}));
this.trigger_refresh_on_change(["pl_or_bs"]);
this.filter_inputs.pl_or_bs
.add_options($.map(wn.report_dump.data["Cost Center"], function(v) {return v.name;}));
this.setup_plot_check();
},
init_filter_values: function() {

View File

@ -108,7 +108,7 @@ erpnext.GeneralLedger = wn.views.GridReport.extend({
// filter accounts options by company
this.filter_inputs.company.change(function() {
me.setup_account_filter(this);
me.filter_inputs.refresh.click();
me.set_route()
});
this.filter_inputs.account.change(function() {

View File

@ -121,17 +121,7 @@ erpnext.PurchaseAnalytics = wn.views.TreeGridReport.extend({
var me = this;
this._super();
this.filter_inputs.value_or_qty.change(function() {
me.filter_inputs.refresh.click();
});
this.filter_inputs.tree_type.change(function() {
me.filter_inputs.refresh.click();
});
this.filter_inputs.based_on.change(function() {
me.filter_inputs.refresh.click();
});
this.trigger_refresh_on_change(["value_or_qty", "tree_type", "based_on"]);
this.show_zero_check()
this.setup_plot_check();

View File

@ -16,6 +16,7 @@
from __future__ import unicode_literals
patch_list = [
"execute:webnotes.reload_doc('core', 'doctype', 'report') # 2013-03-07",
"patches.mar_2012.so_rv_mapper_fix",
"patches.mar_2012.clean_property_setter",
"patches.april_2012.naming_series_patch",

View File

@ -123,17 +123,7 @@ erpnext.SalesAnalytics = wn.views.TreeGridReport.extend({
var me = this;
this._super();
this.filter_inputs.value_or_qty.change(function() {
me.filter_inputs.refresh.click();
});
this.filter_inputs.tree_type.change(function() {
me.filter_inputs.refresh.click();
});
this.filter_inputs.based_on.change(function() {
me.filter_inputs.refresh.click();
});
this.trigger_refresh_on_change(["value_or_qty", "tree_type", "based_on"]);
this.show_zero_check()
this.setup_plot_check();

View File

@ -0,0 +1,115 @@
import os
import webnotes
from webnotes.utils import get_request_site_address
@webnotes.whitelist()
def get_dropbox_authorize_url():
sess = get_dropbox_session()
request_token = sess.obtain_request_token()
return_address = get_request_site_address(True) \
+ "?cmd=setup.doctype.backup_manager.backup_dropbox.dropbox_callback"
url = sess.build_authorize_url(request_token, return_address)
return {
"url": url,
"key": request_token.key,
"secret": request_token.secret,
}
@webnotes.whitelist(allow_guest=True)
def dropbox_callback(oauth_token=None, not_approved=False):
if not not_approved:
if webnotes.conn.get_value("Backup Manager", None, "dropbox_access_key")==oauth_token:
webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 1)
message = "Dropbox access allowed."
sess = get_dropbox_session()
sess.set_request_token(webnotes.conn.get_value("Backup Manager", None, "dropbox_access_key"),
webnotes.conn.get_value("Backup Manager", None, "dropbox_access_secret"))
access_token = sess.obtain_access_token()
webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_key",
access_token.key)
webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_secret",
access_token.secret)
else:
webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 0)
message = "Illegal Access Token Please try again."
else:
webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 0)
message = "Dropbox Access not approved."
webnotes.message_title = "Dropbox Approval"
webnotes.message = "<h3>%s</h3><p>Please close this window.</p>" % message
webnotes.conn.commit()
webnotes.response['type'] = 'page'
webnotes.response['page_name'] = 'message.html'
def backup_to_dropbox():
from dropbox import client, session
from conf import dropbox_access_key, dropbox_secret_key
from webnotes.utils.backups import new_backup
if not webnotes.conn:
webnotes.connect()
sess = session.DropboxSession(dropbox_access_key, dropbox_secret_key, "app_folder")
sess.set_token(webnotes.conn.get_value("Backup Manager", None, "dropbox_access_key"),
webnotes.conn.get_value("Backup Manager", None, "dropbox_access_secret"))
dropbox_client = client.DropboxClient(sess)
# upload database
backup = new_backup()
filename = backup.backup_path_db
upload_file_to_dropbox(filename, "database", dropbox_client)
# upload files
response = dropbox_client.metadata("files")
# add missing files
for filename in os.listdir(os.path.join("public", "files")):
found = False
for file_metadata in response["contents"]:
if filename==os.path.basename(file_metadata["path"]):
if os.stat(os.path.join("public", "files", filename)).st_size==file_metadata["bytes"]:
found=True
if not found:
upload_file_to_dropbox(os.path.join("public", "files", filename), "files", dropbox_client)
def get_dropbox_session():
from dropbox import session
try:
from conf import dropbox_access_key, dropbox_secret_key
except ImportError, e:
webnotes.msgprint(_("Please set Dropbox access keys in") + " conf.py",
raise_exception=True)
sess = session.DropboxSession(dropbox_access_key, dropbox_secret_key, "app_folder")
return sess
def upload_file_to_dropbox(filename, folder, dropbox_client):
if __name__=="__main__":
print "Uploading " + filename
size = os.stat(filename).st_size
f = open(filename,'r')
if size > 4194304:
uploader = dropbox_client.get_chunked_uploader(f, size)
while uploader.offset < size:
try:
uploader.upload_chunked()
except rest.ErrorResponse, e:
pass
else:
response = dropbox_client.put_file(folder + "/" + os.path.basename(filename), f, overwrite=True)
if __name__=="__main__":
backup_to_dropbox()

View File

@ -1,6 +1,6 @@
cur_frm.cscript.allow_dropbox_access = function(doc) {
wn.call({
method: "setup.doctype.backup_manager.backup_manager.get_dropbox_authorize_url",
method: "setup.doctype.backup_manager.backup_dropbox.get_dropbox_authorize_url",
callback: function(r) {
if(!r.exc) {
cur_frm.set_value("dropbox_access_secret", r.message.secret);
@ -12,3 +12,13 @@ cur_frm.cscript.allow_dropbox_access = function(doc) {
}
})
}
cur_frm.cscript.backup_right_now = function(doc) {
msgprint("Backing up and uploading. This may take a few minutes.")
wn.call({
method: "setup.doctype.backup_manager.backup_manager.take_backups",
callback: function(r) {
msgprint("Backups taken. Please check your email for the response.")
}
})
}

View File

@ -3,51 +3,46 @@
from __future__ import unicode_literals
import webnotes
from webnotes import _
from webnotes.utils import get_request_site_address
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl
def take_backups_daily():
take_backups_if("Daily")
def take_backups_weekly():
take_backups_if("Weekly")
def take_backups_if(freq):
if webnotes.conn.get_value("Backup Manager", None, "upload_backups_to_dropbox")==freq:
take_backups()
@webnotes.whitelist()
def get_dropbox_authorize_url():
from dropbox import session
def take_backups():
try:
from conf import dropbox_access_key, dropbox_secret_key
except ImportError, e:
webnotes.msgprint(_("Please set Dropbox access keys in") + " conf.py",
raise_exception=True)
from setup.doctype.backup_manager.backup_dropbox import backup_to_dropbox
backup_to_dropbox()
send_email(True, "Dropbox")
except Exception, e:
send_email(False, "Dropbox", e)
sess = session.DropboxSession(dropbox_access_key, dropbox_secret_key, "app_folder")
request_token = sess.obtain_request_token()
return_address = get_request_site_address(True) \
+ "?cmd=setup.doctype.backup_manager.backup_manager.dropbox_callback"
def send_email(success, service_name, error_status=None):
if success:
subject = "Backup Upload Successful"
message ="""<h3>Backup Uploaded Successfully</h3><p>Hi there, this is just to inform you
that your backup was successfully uploaded to your %s account. So relax!</p>
""" % service_name
url = sess.build_authorize_url(request_token, return_address)
return {
"url": url,
"key": request_token.key,
"secret": request_token.secret,
}
@webnotes.whitelist(allow_guest=True)
def dropbox_callback(oauth_token=None, not_approved=False):
if not not_approved:
if webnotes.conn.get_value("Backup Manager", None, "dropbox_access_key")==oauth_token:
webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 1)
message = "Dropbox access allowed."
else:
webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 0)
message = "Illegal Access Token Please try again."
else:
webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", 0)
message = "Dropbox Access not approved."
subject = "[Warning] Backup Upload Failed"
message ="""<h3>Backup Upload Failed</h3><p>Oops, your automated backup to %s
failed.</p>
<p>Error message: %s</p>
<p>Please contact your system manager for more information.</p>
""" % (service_name, error_status)
webnotes.message_title = "Dropbox Approval"
webnotes.message = "<h3>%s</h3><p>Please close this window.</p>" % message
webnotes.conn.commit()
webnotes.response['type'] = 'page'
webnotes.response['page_name'] = 'message.html'
# email system managers
from webnotes.utils.email_lib import sendmail
sendmail(webnotes.conn.get_value("Backup Manager", None, "send_notifications_to").split(","),
subject=subject, msg=message)

View File

@ -2,7 +2,7 @@
{
"creation": "2013-03-05 16:35:50",
"docstatus": 0,
"modified": "2013-03-05 18:05:05",
"modified": "2013-03-07 12:18:07",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -39,6 +39,27 @@
"name": "Backup Manager"
},
{
"doctype": "DocField",
"fieldname": "setup",
"fieldtype": "Section Break",
"label": "Setup"
},
{
"description": "Email ids separated by commas.",
"doctype": "DocField",
"fieldname": "send_notifications_to",
"fieldtype": "Data",
"label": "Send Notifications To",
"reqd": 1
},
{
"doctype": "DocField",
"fieldname": "backup_right_now",
"fieldtype": "Button",
"label": "Backup Right Now"
},
{
"description": "Note: Backups and files are not deleted from Dropbox, you will have to delete them manually.",
"doctype": "DocField",
"fieldname": "sync_with_dropbox",
"fieldtype": "Section Break",
@ -47,27 +68,31 @@
{
"doctype": "DocField",
"fieldname": "upload_backups_to_dropbox",
"fieldtype": "Check",
"label": "Upload Backups to Dropbox"
"fieldtype": "Select",
"label": "Upload Backups to Dropbox",
"options": "Never\nWeekly\nDaily"
},
{
"doctype": "DocField",
"fieldname": "dropbox_access_key",
"fieldtype": "Data",
"hidden": 1,
"label": "Dropbox Access Key"
"label": "Dropbox Access Key",
"read_only": 1
},
{
"doctype": "DocField",
"fieldname": "dropbox_access_secret",
"fieldtype": "Data",
"hidden": 1,
"label": "Dropbox Access Secret"
"label": "Dropbox Access Secret",
"read_only": 1
},
{
"doctype": "DocField",
"fieldname": "dropbox_access_allowed",
"fieldtype": "Check",
"hidden": 1,
"label": "Dropbox Access Allowed",
"read_only": 1
},

View File

@ -186,19 +186,19 @@ wn.module_page["Setup"] = [
},
]
},
// {
// title: wn._("Backups"),
// icon: "icon-cloud-upload",
// right: true,
// items: [
// {
// "route":"Form/Backup Manager",
// doctype:"Backup Manager",
// label: wn._("Backup Manager"),
// "description":wn._("Sync backups with remote tools like Dropbox etc.")
// },
// ]
// },
{
title: wn._("Backups"),
icon: "icon-cloud-upload",
right: true,
items: [
{
"route":"Form/Backup Manager",
doctype:"Backup Manager",
label: wn._("Backup Manager"),
"description":wn._("Sync backups with remote tools like Dropbox etc.")
},
]
},
]
pscript['onload_Setup'] = function(wrapper) {

View File

@ -51,8 +51,13 @@ def execute_daily():
from webnotes.utils.email_lib.bulk import clear_outbox
run_fn(clear_outbox)
# daily backup
from setup.doctype.backup_manager.backup_manager import take_backups_daily
take_backups_daily()
def execute_weekly():
pass
from setup.doctype.backup_manager.backup_manager import take_backups_weekly
take_backups_weekly()
def execute_monthly():
pass

View File

@ -17,7 +17,7 @@
from __future__ import unicode_literals
import webnotes
from webnotes.utils import add_days, cstr, flt, nowdate, cint
from webnotes.utils import add_days, cstr, flt, nowdate, cint, now
from webnotes.model.doc import Document
from webnotes.model.bean import getlist
from webnotes.model.code import get_obj
@ -49,7 +49,7 @@ class DocType:
serial_nos = get_valid_serial_nos(d.serial_no)
for s in serial_nos:
s = s.strip()
sr_war = sql("select warehouse,name from `tabSerial No` where name = '%s'" % (s))
sr_war = webnotes.conn.sql("select warehouse,name from `tabSerial No` where name = '%s'" % (s))
if not sr_war:
msgprint("Serial No %s does not exists"%s, raise_exception = 1)
elif not sr_war[0][0]:
@ -81,7 +81,7 @@ class DocType:
def set_pur_serial_no_values(self, obj, serial_no, d, s, new_rec, rejected=None):
item_details = sql("""select item_group, warranty_period
item_details = webnotes.conn.sql("""select item_group, warranty_period
from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or
end_of_life = '0000-00-00' or end_of_life > now()) """ %(d.item_code), as_dict=1)
@ -112,7 +112,7 @@ class DocType:
def update_serial_purchase_details(self, obj, d, serial_no, is_submit, purpose = '', rejected=None):
exists = sql("select name, status, docstatus from `tabSerial No` where name = '%s'" % (serial_no))
exists = webnotes.conn.sql("select name, status, docstatus from `tabSerial No` where name = '%s'" % (serial_no))
if is_submit:
if exists and exists[0][2] != 2 and purpose not in ['Material Transfer', 'Sales Return']:
msgprint("Serial No: %s already %s" % (serial_no, exists and exists[0][1]), raise_exception = 1)
@ -126,15 +126,15 @@ class DocType:
if exists and exists[0][1] == 'Delivered' and exists[0][2] != 2:
msgprint("Serial No: %s is already delivered, you can not cancel the document." % serial_no, raise_exception=1)
elif purpose == 'Material Transfer':
sql("update `tabSerial No` set status = 'In Store', purchase_document_type = '', purchase_document_no = '', warehouse = '%s' where name = '%s'" % (d.s_warehouse, serial_no))
webnotes.conn.sql("update `tabSerial No` set status = 'In Store', purchase_document_type = '', purchase_document_no = '', warehouse = '%s' where name = '%s'" % (d.s_warehouse, serial_no))
elif purpose == 'Sales Return':
sql("update `tabSerial No` set status = 'Delivered', purchase_document_type = '', purchase_document_no = '' where name = '%s'" % serial_no)
webnotes.conn.sql("update `tabSerial No` set status = 'Delivered', purchase_document_type = '', purchase_document_no = '' where name = '%s'" % serial_no)
else:
sql("update `tabSerial No` set docstatus = 2, status = 'Not in Use', purchase_document_type = '', purchase_document_no = '', purchase_date = null, purchase_rate = 0, supplier = null, supplier_name = '', supplier_address = '', warehouse = '' where name = '%s'" % serial_no)
webnotes.conn.sql("update `tabSerial No` set docstatus = 2, status = 'Not in Use', purchase_document_type = '', purchase_document_no = '', purchase_date = null, purchase_rate = 0, supplier = null, supplier_name = '', supplier_address = '', warehouse = '' where name = '%s'" % serial_no)
def check_serial_no_exists(self, serial_no, item_code):
chk = sql("select name, status, docstatus, item_code from `tabSerial No` where name = %s", (serial_no), as_dict=1)
chk = webnotes.conn.sql("select name, status, docstatus, item_code from `tabSerial No` where name = %s", (serial_no), as_dict=1)
if not chk:
msgprint("Serial No: %s does not exists in the system" % serial_no, raise_exception=1)
elif chk and chk[0]['item_code'] != item_code:
@ -169,7 +169,7 @@ class DocType:
self.check_serial_no_exists(serial_no, d.item_code)
self.set_delivery_serial_no_values(obj, serial_no)
else:
sql("update `tabSerial No` set docstatus = 0, status = 'In Store', delivery_document_type = '', delivery_document_no = '', delivery_date = null, customer = null, customer_name = '', delivery_address = '', territory = null where name = '%s'" % (serial_no))
webnotes.conn.sql("update `tabSerial No` set docstatus = 0, status = 'In Store', delivery_document_type = '', delivery_document_no = '', delivery_date = null, customer = null, customer_name = '', delivery_address = '', territory = null where name = '%s'" % (serial_no))
def update_serial_record(self, obj, fname, is_submit = 1, is_incoming = 0):
@ -202,8 +202,10 @@ class DocType:
if v.get('is_cancelled') == 'Yes':
v['actual_qty'] = -flt(v['actual_qty'])
# cancel matching entry
sql("update `tabStock Ledger Entry` set is_cancelled='Yes' where voucher_no=%s \
and voucher_type=%s", (v['voucher_no'], v['voucher_type']))
webnotes.conn.sql("""update `tabStock Ledger Entry` set is_cancelled='Yes',
modified=%s, modified_by=%s
where voucher_no=%s and voucher_type=%s""",
(now(), webnotes.session.user, v['voucher_no'], v['voucher_type']))
if v.get("actual_qty"):
sle_id = self.make_entry(v)
@ -230,5 +232,5 @@ class DocType:
"""
Repost everything!
"""
for wh in sql("select name from tabWarehouse"):
for wh in webnotes.conn.sql("select name from tabWarehouse"):
get_obj('Warehouse', wh[0]).repost_stock()

View File

@ -153,7 +153,7 @@ class TransactionBase(DocListController):
# Get Lead Details
# -----------------------
def get_lead_details(self, name):
details = webnotes.conn.sql("select name, lead_name, address_line1, address_line2, city, country, state, pincode, territory, contact_no, mobile_no, email_id, company_name from `tabLead` where name = '%s'" %(name), as_dict = 1)
details = webnotes.conn.sql("select name, lead_name, address_line1, address_line2, city, country, state, pincode, territory, phone, mobile_no, email_id, company_name from `tabLead` where name = '%s'" %(name), as_dict = 1)
extract = lambda x: details and details[0] and details[0].get(x,'') or ''
address_fields = [('','address_line1'),('\n','address_line2'),('\n','city'),(' ','pincode'),('\n','state'),('\n','country'),('\nPhone: ','contact_no')]