Merge pull request #4076 from anandpdoshi/shopping-cart-order
check doc.has_website_permission in order.html. Merge after frappe/frappe#1316
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 45b94d7..2620385 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -169,7 +169,7 @@
if item.price_list_rate:
item.rate = flt(item.price_list_rate *
- (1.0 - (item.discount_percentage / 100.0)), item.precision("rate"))
+ (1.0 - (flt(item.discount_percentage) / 100.0)), item.precision("rate"))
def set_taxes(self):
if not self.meta.get_field("taxes"):
diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py
index c43493c..42eaf4d 100644
--- a/erpnext/controllers/status_updater.py
+++ b/erpnext/controllers/status_updater.py
@@ -207,10 +207,10 @@
# update percent complete in the parent table
if args.get('target_parent_field'):
frappe.db.sql("""update `tab%(target_parent_dt)s`
- set %(target_parent_field)s = (select sum(if(%(target_ref_field)s >
+ set %(target_parent_field)s = round((select sum(if(%(target_ref_field)s >
ifnull(%(target_field)s, 0), %(target_field)s,
%(target_ref_field)s))/sum(%(target_ref_field)s)*100
- from `tab%(target_dt)s` where parent="%(name)s") %(set_modified)s
+ from `tab%(target_dt)s` where parent="%(name)s"), 2) %(set_modified)s
where name='%(name)s'""" % args)
# update field
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index 2053694..7d40d85 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -128,12 +128,6 @@
"erpnext.support.doctype.issue.issue.auto_close_tickets",
"erpnext.accounts.doctype.fiscal_year.fiscal_year.auto_create_fiscal_year",
"erpnext.hr.doctype.employee.employee.send_birthday_reminders"
- ],
- "daily_long": [
- "erpnext.setup.doctype.backup_manager.backup_manager.take_backups_daily"
- ],
- "weekly_long": [
- "erpnext.setup.doctype.backup_manager.backup_manager.take_backups_weekly"
]
}
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 51356e5..1d95904 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -211,3 +211,4 @@
erpnext.patches.v6_2.fix_missing_default_taxes_and_lead
erpnext.patches.v5_8.tax_rule
erpnext.patches.v6_3.convert_applicable_territory
+erpnext.patches.v6_4.round_status_updater_percentages
diff --git a/erpnext/patches/v6_4/__init__.py b/erpnext/patches/v6_4/__init__.py
new file mode 100644
index 0000000..baffc48
--- /dev/null
+++ b/erpnext/patches/v6_4/__init__.py
@@ -0,0 +1 @@
+from __future__ import unicode_literals
diff --git a/erpnext/patches/v6_4/round_status_updater_percentages.py b/erpnext/patches/v6_4/round_status_updater_percentages.py
new file mode 100644
index 0000000..900e906
--- /dev/null
+++ b/erpnext/patches/v6_4/round_status_updater_percentages.py
@@ -0,0 +1,14 @@
+from __future__ import unicode_literals
+import frappe
+
+def execute():
+ for doctype, fieldname in (
+ ("Sales Order", "per_billed"),
+ ("Sales Order", "per_delivered"),
+ ("Delivery Note", "per_installed"),
+ ("Purchase Order", "per_billed"),
+ ("Purchase Order", "per_received"),
+ ("Material Request", "per_ordered"),
+ ):
+ frappe.db.sql("""update `tab{doctype}` set `{fieldname}`=round(`{fieldname}`, 2)""".format(
+ doctype=doctype, fieldname=fieldname))
diff --git a/erpnext/projects/doctype/task/task_list.js b/erpnext/projects/doctype/task/task_list.js
index 9150501..2a02fbb 100644
--- a/erpnext/projects/doctype/task/task_list.js
+++ b/erpnext/projects/doctype/task/task_list.js
@@ -1,6 +1,10 @@
frappe.listview_settings['Task'] = {
add_fields: ["project", "status", "priority", "exp_end_date"],
onload: function(listview) {
+ frappe.route_options = {
+ "status": "Open"
+ };
+
var method = "erpnext.projects.doctype.task.task.set_multiple_status";
listview.page.add_menu_item(__("Set as Open"), function() {
diff --git a/erpnext/public/js/conf.js b/erpnext/public/js/conf.js
index 1191c47..640a79e 100644
--- a/erpnext/public/js/conf.js
+++ b/erpnext/public/js/conf.js
@@ -37,3 +37,40 @@
"Sales Partner": "Selling",
"Brand": "Selling"
});
+
+frappe.desk_home_buttons.push({label:"<i class='icon-facetime-video'></i> "+ __("Learn"),
+ route:"Module/Learn"})
+
+frappe.desk_home_flows.push({
+ title: __("Selling"),
+ sequence: [
+ {title: __("Opportunity"), route:"List/Opportunity"},
+ {title: __("Quotation"), route:"List/Quotation"},
+ {title: __("Sales Order"), route:"List/Sales Order"},
+ {title: __("Delivery Note"), route:"List/Delivery Note"},
+ {title: __("Sales Invoice"), route:"List/Sales Invoice"},
+ {title: __("Payment"), route:"List/Journal Entry"},
+ ]
+ });
+
+frappe.desk_home_flows.push({
+ title: __("Buying"),
+ sequence: [
+ {title: __("Material Request"), route:"List/Material Request"},
+ {title: __("Supplier Quotation"), route:"List/Supplier Quotation"},
+ {title: __("Purchase Order"), route:"List/Purchase Order"},
+ {title: __("Purchase Receipt"), route:"List/Purchase Receipt"},
+ {title: __("Purchase Invoice"), route:"List/Purchase Invoice"},
+ {title: __("Payment"), route:"List/Journal Entry"},
+ ]
+ });
+
+frappe.desk_home_flows.push({
+ title: __("Manufacturing"),
+ sequence: [
+ {title: __("BOM"), route:"List/BOM"},
+ {title: __("Production Planning Tool"), route:"Form/Production Planning Tool"},
+ {title: __("Production Order"), route:"List/Production Order"},
+ {title: __("Stock Entry"), route:"List/Stock Entry"},
+ ]
+ });
diff --git a/erpnext/public/js/startup.js b/erpnext/public/js/startup.js
deleted file mode 100644
index 8d2b1ad..0000000
--- a/erpnext/public/js/startup.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-// License: GNU General Public License v3. See license.txt
-
-// start
-$(document).on('startup', function() {
- console.log(__('Starting up...'));
-});
diff --git a/erpnext/setup/doctype/backup_manager/README.md b/erpnext/setup/doctype/backup_manager/README.md
deleted file mode 100644
index 4f037bf..0000000
--- a/erpnext/setup/doctype/backup_manager/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Settings to manage automated backups to third party tools like Dropbox and Google Drive.
\ No newline at end of file
diff --git a/erpnext/setup/doctype/backup_manager/__init__.py b/erpnext/setup/doctype/backup_manager/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/erpnext/setup/doctype/backup_manager/__init__.py
+++ /dev/null
diff --git a/erpnext/setup/doctype/backup_manager/backup_dropbox.py b/erpnext/setup/doctype/backup_manager/backup_dropbox.py
deleted file mode 100644
index 9e38833..0000000
--- a/erpnext/setup/doctype/backup_manager/backup_dropbox.py
+++ /dev/null
@@ -1,155 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-# SETUP:
-# install pip install --upgrade dropbox
-#
-# Create new Dropbox App
-#
-# in conf.py, set oauth2 settings
-# dropbox_access_key
-# dropbox_access_secret
-
-from __future__ import unicode_literals
-import os
-import frappe
-from frappe.utils import get_request_site_address, cstr
-from frappe import _
-
-ignore_list = [".DS_Store"]
-
-@frappe.whitelist()
-def get_dropbox_authorize_url():
- sess = get_dropbox_session()
- request_token = sess.obtain_request_token()
- return_address = get_request_site_address(True) \
- + "?cmd=erpnext.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,
- }
-
-@frappe.whitelist(allow_guest=True)
-def dropbox_callback(oauth_token=None, not_approved=False):
- from dropbox import client
- if not not_approved:
- if frappe.db.get_value("Backup Manager", None, "dropbox_access_key")==oauth_token:
- allowed = 1
- message = "Dropbox access allowed."
-
- sess = get_dropbox_session()
- sess.set_request_token(frappe.db.get_value("Backup Manager", None, "dropbox_access_key"),
- frappe.db.get_value("Backup Manager", None, "dropbox_access_secret"))
- access_token = sess.obtain_access_token()
- frappe.db.set_value("Backup Manager", "Backup Manager", "dropbox_access_key", access_token.key)
- frappe.db.set_value("Backup Manager", "Backup Manager", "dropbox_access_secret", access_token.secret)
- frappe.db.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", allowed)
- frappe.db.set_value("Backup Manager", "Backup Manager", "send_backups_to_dropbox", 1)
- dropbox_client = client.DropboxClient(sess)
- try:
- dropbox_client.file_create_folder("files")
- except:
- pass
-
- else:
- allowed = 0
- message = "Illegal Access Token Please try again."
- else:
- allowed = 0
- message = "Dropbox Access not approved."
-
- frappe.local.message_title = "Dropbox Approval"
- frappe.local.message = "<h3>%s</h3><p>Please close this window.</p>" % message
-
- if allowed:
- frappe.local.message_success = True
-
- frappe.db.commit()
- frappe.response['type'] = 'page'
- frappe.response['page_name'] = 'message.html'
-
-def backup_to_dropbox():
- from dropbox import client, session
- from frappe.utils.backups import new_backup
- from frappe.utils import get_files_path, get_backups_path
- if not frappe.db:
- frappe.connect()
-
- sess = session.DropboxSession(frappe.conf.dropbox_access_key, frappe.conf.dropbox_secret_key, "app_folder")
-
- sess.set_token(frappe.db.get_value("Backup Manager", None, "dropbox_access_key"),
- frappe.db.get_value("Backup Manager", None, "dropbox_access_secret"))
-
- dropbox_client = client.DropboxClient(sess)
-
- # upload database
- backup = new_backup()
- filename = os.path.join(get_backups_path(), os.path.basename(backup.backup_path_db))
- upload_file_to_dropbox(filename, "/database", dropbox_client)
-
- frappe.db.close()
- response = dropbox_client.metadata("/files")
-
- # upload files to files folder
- did_not_upload = []
- error_log = []
- path = get_files_path()
- for filename in os.listdir(path):
- filename = cstr(filename)
-
- if filename in ignore_list:
- continue
-
- found = False
- filepath = os.path.join(path, filename)
- for file_metadata in response["contents"]:
- if os.path.basename(filepath) == os.path.basename(file_metadata["path"]) and os.stat(filepath).st_size == int(file_metadata["bytes"]):
- found = True
- break
- if not found:
- try:
- upload_file_to_dropbox(filepath, "/files", dropbox_client)
- except Exception:
- did_not_upload.append(filename)
- error_log.append(frappe.get_traceback())
-
- frappe.connect()
- return did_not_upload, list(set(error_log))
-
-def get_dropbox_session():
- try:
- from dropbox import session
- except:
- frappe.msgprint(_("Please install dropbox python module"), raise_exception=1)
-
- if not (frappe.conf.dropbox_access_key or frappe.conf.dropbox_secret_key):
- frappe.throw(_("Please set Dropbox access keys in your site config"))
-
- sess = session.DropboxSession(frappe.conf.dropbox_access_key, frappe.conf.dropbox_secret_key, "app_folder")
- return sess
-
-def upload_file_to_dropbox(filename, folder, dropbox_client):
- from dropbox import rest
- size = os.stat(filename).st_size
-
- with open(filename, 'r') as f:
- # if max packet size reached, use chunked uploader
- max_packet_size = 4194304
-
- if size > max_packet_size:
- uploader = dropbox_client.get_chunked_uploader(f, size)
- while uploader.offset < size:
- try:
- uploader.upload_chunked()
- uploader.finish(folder + "/" + os.path.basename(filename), overwrite=True)
- except rest.ErrorResponse:
- pass
- else:
- dropbox_client.put_file(folder + "/" + os.path.basename(filename), f, overwrite=True)
-
-if __name__=="__main__":
- backup_to_dropbox()
diff --git a/erpnext/setup/doctype/backup_manager/backup_files_list.html b/erpnext/setup/doctype/backup_manager/backup_files_list.html
deleted file mode 100644
index 5ee52ef..0000000
--- a/erpnext/setup/doctype/backup_manager/backup_files_list.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<table class="table table-striped" style="max-width: 600px;">
- <thead>
- <tr>
- <th style="width: 30%;">
- {{ __("Date") }}
- </th>
- <th style="width: 50%;">
- {{ __("File") }}
- </th>
- <th>
- {{ __("Size") }}
- </th>
- </tr>
- </thead>
- <tbody>
- {% for (var i=0; i < files.length; i++) { %}
- <tr>
- <td>
- {{ files[i][1] }}
- </td>
- <td>
- <a href="{{ files[i][0] }}" target="_blank">{{ files[i][0] }}</a>
- </td>
- <td>
- {{ files[i][2] }}
- </td>
- </tr>
- {% } %}
- </tbody>
-</table>
diff --git a/erpnext/setup/doctype/backup_manager/backup_googledrive.py b/erpnext/setup/doctype/backup_manager/backup_googledrive.py
deleted file mode 100644
index 5fec9b8..0000000
--- a/erpnext/setup/doctype/backup_manager/backup_googledrive.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-# SETUP:
-# install pip install --upgrade google-api-python-client
-#
-# In Google API
-# - create new API project
-# - create new oauth2 client (create installed app type as google \
-# does not support subdomains)
-#
-# in conf.py, set oauth2 settings
-# gdrive_client_id
-# gdrive_client_secret
-
-from __future__ import unicode_literals
-import httplib2
-import os
-import mimetypes
-import frappe
-import oauth2client.client
-from frappe.utils import cstr
-from frappe import _
-from apiclient.discovery import build
-from apiclient.http import MediaFileUpload
-
-# define log config for google drive api's log messages
-# basicConfig redirects log to stderr
-import logging
-logging.basicConfig()
-
-@frappe.whitelist()
-def get_gdrive_authorize_url():
- flow = get_gdrive_flow()
- authorize_url = flow.step1_get_authorize_url()
- return {
- "authorize_url": authorize_url,
- }
-
-def upload_files(name, mimetype, service, folder_id):
- if not frappe.db:
- frappe.connect()
- file_name = os.path.basename(name)
- media_body = MediaFileUpload(name, mimetype=mimetype, resumable=True)
- body = {
- 'title': file_name,
- 'description': 'Backup File',
- 'mimetype': mimetype,
- 'parents': [{
- 'kind': 'drive#filelink',
- 'id': folder_id
- }]
- }
- request = service.files().insert(body=body, media_body=media_body)
- response = None
- while response is None:
- status, response = request.next_chunk()
-
-def backup_to_gdrive():
- from frappe.utils.backups import new_backup
- if not frappe.db:
- frappe.connect()
- get_gdrive_flow()
- credentials_json = frappe.db.get_value("Backup Manager", None, "gdrive_credentials")
- credentials = oauth2client.client.Credentials.new_from_json(credentials_json)
- http = httplib2.Http()
- http = credentials.authorize(http)
- drive_service = build('drive', 'v2', http=http)
-
- # upload database
- backup = new_backup()
- path = os.path.join(frappe.local.site_path, "public", "backups")
- filename = os.path.join(path, os.path.basename(backup.backup_path_db))
-
- # upload files to database folder
- upload_files(filename, 'application/x-gzip', drive_service,
- frappe.db.get_value("Backup Manager", None, "database_folder_id"))
-
- # upload files to files folder
- did_not_upload = []
- error_log = []
-
- files_folder_id = frappe.db.get_value("Backup Manager", None, "files_folder_id")
-
- frappe.db.close()
- path = os.path.join(frappe.local.site_path, "public", "files")
- for filename in os.listdir(path):
- filename = cstr(filename)
- found = False
- filepath = os.path.join(path, filename)
- ext = filename.split('.')[-1]
- size = os.path.getsize(filepath)
- if ext == 'gz' or ext == 'gzip':
- mimetype = 'application/x-gzip'
- else:
- mimetype = mimetypes.types_map.get("." + ext) or "application/octet-stream"
-
- #Compare Local File with Server File
- children = drive_service.children().list(folderId=files_folder_id).execute()
- for child in children.get('items', []):
- file = drive_service.files().get(fileId=child['id']).execute()
- if filename == file['title'] and size == int(file['fileSize']):
- found = True
- break
- if not found:
- try:
- upload_files(filepath, mimetype, drive_service, files_folder_id)
- except Exception, e:
- did_not_upload.append(filename)
- error_log.append(cstr(e))
-
- frappe.connect()
- return did_not_upload, list(set(error_log))
-
-def get_gdrive_flow():
- from oauth2client.client import OAuth2WebServerFlow
- from frappe import conf
-
- if not "gdrive_client_id" in conf:
- frappe.throw(_("Please set Google Drive access keys in {0}"),format("site_config.json"))
-
- flow = OAuth2WebServerFlow(conf.gdrive_client_id, conf.gdrive_client_secret,
- "https://www.googleapis.com/auth/drive", 'urn:ietf:wg:oauth:2.0:oob')
- return flow
-
-@frappe.whitelist()
-def gdrive_callback(verification_code = None):
- flow = get_gdrive_flow()
- if verification_code:
- credentials = flow.step2_exchange(verification_code)
- allowed = 1
-
- # make folders to save id
- http = httplib2.Http()
- http = credentials.authorize(http)
- drive_service = build('drive', 'v2', http=http)
- erpnext_folder_id = create_erpnext_folder(drive_service)
- database_folder_id = create_folder('database', drive_service, erpnext_folder_id)
- files_folder_id = create_folder('files', drive_service, erpnext_folder_id)
-
- frappe.db.set_value("Backup Manager", "Backup Manager", "gdrive_access_allowed", allowed)
- frappe.db.set_value("Backup Manager", "Backup Manager", "database_folder_id", database_folder_id)
- frappe.db.set_value("Backup Manager", "Backup Manager", "files_folder_id", files_folder_id)
- final_credentials = credentials.to_json()
- frappe.db.set_value("Backup Manager", "Backup Manager", "gdrive_credentials", final_credentials)
-
- frappe.msgprint(_("Updated"))
-
-def create_erpnext_folder(service):
- if not frappe.db:
- frappe.connect()
- erpnext = {
- 'title': 'erpnext',
- 'mimeType': 'application/vnd.google-apps.folder'
- }
- erpnext = service.files().insert(body=erpnext).execute()
- return erpnext['id']
-
-def create_folder(name, service, folder_id):
- database = {
- 'title': name,
- 'mimeType': 'application/vnd.google-apps.folder',
- 'parents': [{
- 'kind': 'drive#fileLink',
- 'id': folder_id
- }]
- }
- database = service.files().insert(body=database).execute()
- return database['id']
-
-if __name__=="__main__":
- backup_to_gdrive()
diff --git a/erpnext/setup/doctype/backup_manager/backup_manager.js b/erpnext/setup/doctype/backup_manager/backup_manager.js
deleted file mode 100644
index cb4104a..0000000
--- a/erpnext/setup/doctype/backup_manager/backup_manager.js
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-// License: GNU General Public License v3. See license.txt
-
-$.extend(cur_frm.cscript, {
- onload_post_render: function() {
- cur_frm.fields_dict.allow_dropbox_access.$input.addClass("btn-primary");
-
- if(cur_frm.doc.__onload && cur_frm.doc.__onload.files) {
- $(frappe.render_template("backup_files_list", {files:cur_frm.doc.__onload.files}))
- .appendTo(cur_frm.fields_dict.current_backups.$wrapper.empty());
- }
- },
- refresh: function() {
- cur_frm.disable_save();
- },
-
- validate_send_notifications_to: function() {
- if(!cur_frm.doc.send_notifications_to) {
- msgprint(__("Please specify") + ": " +
- __(frappe.meta.get_label(cur_frm.doctype, "send_notifications_to")));
- return false;
- }
-
- return true;
- },
-
- allow_dropbox_access: function() {
- if(cur_frm.cscript.validate_send_notifications_to()) {
- return frappe.call({
- method: "erpnext.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);
- cur_frm.set_value("dropbox_access_key", r.message.key);
- cur_frm.save(null, function() {
- window.open(r.message.url);
- });
- }
- }
- });
- }
- },
-
- allow_gdrive_access: function() {
- if(cur_frm.cscript.validate_send_notifications_to()) {
- return frappe.call({
- method: "erpnext.setup.doctype.backup_manager.backup_googledrive.get_gdrive_authorize_url",
- callback: function(r) {
- if(!r.exc) {
- window.open(r.message.authorize_url);
- }
- }
- });
- }
- },
-
- validate_gdrive: function() {
- return frappe.call({
- method: "erpnext.setup.doctype.backup_manager.backup_googledrive.gdrive_callback",
- args: {
- verification_code: cur_frm.doc.verification_code
- },
- });
- },
-
- upload_backups_to_dropbox: function() {
- cur_frm.save();
- },
-
- // upload_backups_to_gdrive: function() {
- // cur_frm.save();
- // },
-});
diff --git a/erpnext/setup/doctype/backup_manager/backup_manager.json b/erpnext/setup/doctype/backup_manager/backup_manager.json
deleted file mode 100644
index 487fe63..0000000
--- a/erpnext/setup/doctype/backup_manager/backup_manager.json
+++ /dev/null
@@ -1,482 +0,0 @@
-{
- "allow_copy": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "creation": "2013-04-30 12:58:38",
- "custom": 0,
- "description": "System for managing Backups",
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "System",
- "fields": [
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "setup",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Download Backups",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "current_backups",
- "fieldtype": "HTML",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Current Backups",
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "description": "",
- "fieldname": "sync_with_dropbox",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Sync with Dropbox",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "backup_right_now",
- "fieldtype": "Button",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Backup Right Now",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "send_backups_to_dropbox",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Send Backups to Dropbox",
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "depends_on": "send_backups_to_dropbox",
- "description": "Note: Backups and files are not deleted from Dropbox, you will have to delete them manually.",
- "fieldname": "upload_backups_to_dropbox",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Upload Backups to Dropbox",
- "no_copy": 0,
- "options": "Never\nWeekly\nDaily",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "depends_on": "send_backups_to_dropbox",
- "description": "Email ids separated by commas.",
- "fieldname": "send_notifications_to",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Send Notifications To",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "dropbox_access_key",
- "fieldtype": "Data",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Dropbox Access Key",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "dropbox_access_secret",
- "fieldtype": "Data",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Dropbox Access Secret",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "dropbox_access_allowed",
- "fieldtype": "Check",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Dropbox Access Allowed",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "depends_on": "send_backups_to_dropbox",
- "fieldname": "allow_dropbox_access",
- "fieldtype": "Button",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Allow Dropbox Access",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "description": "Note: Backups and files are not deleted from Google Drive, you will have to delete them manually.",
- "fieldname": "sync_with_gdrive",
- "fieldtype": "Section Break",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Sync with Google Drive",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "upload_backups_to_gdrive",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Upload Backups to Google Drive",
- "no_copy": 0,
- "options": "Never\nDaily\nWeekly",
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "allow_gdrive_access",
- "fieldtype": "Button",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Allow Google Drive Access",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "verification_code",
- "fieldtype": "Data",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Enter Verification Code",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "validate_gdrive",
- "fieldtype": "Button",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Validate",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "gdrive_access_allowed",
- "fieldtype": "Check",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Google Drive Access Allowed",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "gdrive_credentials",
- "fieldtype": "Text",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Credentials",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "database_folder_id",
- "fieldtype": "Data",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Database Folder ID",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "fieldname": "files_folder_id",
- "fieldtype": "Data",
- "hidden": 1,
- "ignore_user_permissions": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Files Folder ID",
- "no_copy": 0,
- "permlevel": 0,
- "print_hide": 0,
- "read_only": 1,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- }
- ],
- "hide_heading": 0,
- "hide_toolbar": 0,
- "icon": "icon-cloud-upload",
- "idx": 1,
- "in_create": 0,
- "in_dialog": 0,
- "is_submittable": 0,
- "issingle": 1,
- "istable": 0,
- "modified": "2015-05-26 04:54:10.193573",
- "modified_by": "Administrator",
- "module": "Setup",
- "name": "Backup Manager",
- "owner": "Administrator",
- "permissions": [
- {
- "amend": 0,
- "apply_user_permissions": 0,
- "cancel": 0,
- "create": 1,
- "delete": 0,
- "email": 1,
- "export": 0,
- "if_owner": 0,
- "import": 0,
- "permlevel": 0,
- "print": 1,
- "read": 1,
- "report": 0,
- "role": "System Manager",
- "set_user_permissions": 0,
- "share": 1,
- "submit": 0,
- "write": 1
- }
- ],
- "read_only": 0,
- "read_only_onload": 0
-}
\ No newline at end of file
diff --git a/erpnext/setup/doctype/backup_manager/backup_manager.py b/erpnext/setup/doctype/backup_manager/backup_manager.py
deleted file mode 100644
index 4ad64f6..0000000
--- a/erpnext/setup/doctype/backup_manager/backup_manager.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# License: GNU General Public License v3. See license.txt
-
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-from frappe.utils import get_site_path, cint, split_emails
-from frappe.utils.data import convert_utc_to_user_timezone
-import os
-import datetime
-import frappe
-
-from frappe.model.document import Document
-
-class BackupManager(Document):
- def onload(self):
- self.set_onload("files", get_files())
-
-def get_files():
- def get_time(path):
- dt = os.path.getmtime(path)
- return convert_utc_to_user_timezone(datetime.datetime.utcfromtimestamp(dt)).strftime('%Y-%m-%d %H:%M')
-
- def get_size(path):
- size = os.path.getsize(path)
- if size > 1048576:
- return "{0:.1f}M".format(float(size) / 1048576)
- else:
- return "{0:.1f}K".format(float(size) / 1024)
-
- path = get_site_path('private', 'backups')
- files = [x for x in os.listdir(path) if os.path.isfile(os.path.join(path, x))]
- files = [('/backups/' + _file,
- get_time(os.path.join(path, _file)),
- get_size(os.path.join(path, _file))) for _file in files]
- return files
-
-def take_backups_daily():
- take_backups_if("Daily")
-
-def take_backups_weekly():
- take_backups_if("Weekly")
-
-def take_backups_if(freq):
- if cint(frappe.db.get_value("Backup Manager", None, "send_backups_to_dropbox")):
- if frappe.db.get_value("Backup Manager", None, "upload_backups_to_dropbox")==freq:
- take_backups_dropbox()
-
- # if frappe.db.get_value("Backup Manager", None, "upload_backups_to_gdrive")==freq:
- # take_backups_gdrive()
-
-@frappe.whitelist()
-def take_backups_dropbox():
- did_not_upload, error_log = [], []
- try:
- from erpnext.setup.doctype.backup_manager.backup_dropbox import backup_to_dropbox
- did_not_upload, error_log = backup_to_dropbox()
- if did_not_upload: raise Exception
-
- send_email(True, "Dropbox")
- except Exception:
- file_and_error = [" - ".join(f) for f in zip(did_not_upload, error_log)]
- error_message = ("\n".join(file_and_error) + "\n" + frappe.get_traceback())
- frappe.errprint(error_message)
- send_email(False, "Dropbox", error_message)
-
-#backup to gdrive
-@frappe.whitelist()
-def take_backups_gdrive():
- did_not_upload, error_log = [], []
- try:
- from erpnext.setup.doctype.backup_manager.backup_googledrive import backup_to_gdrive
- did_not_upload, error_log = backup_to_gdrive()
- if did_not_upload: raise Exception
-
- send_email(True, "Google Drive")
- except Exception:
- file_and_error = [" - ".join(f) for f in zip(did_not_upload, error_log)]
- error_message = ("\n".join(file_and_error) + "\n" + frappe.get_traceback())
- frappe.errprint(error_message)
- send_email(False, "Google Drive", error_message)
-
-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
-
- else:
- 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)
-
- if not frappe.db:
- frappe.connect()
-
- recipients = split_emails(frappe.db.get_value("Backup Manager", None, "send_notifications_to"))
- frappe.sendmail(recipients=recipients, subject=subject, message=message)
diff --git a/erpnext/setup/doctype/email_digest/email_digest.py b/erpnext/setup/doctype/email_digest/email_digest.py
index 87a1043..599e9c5 100644
--- a/erpnext/setup/doctype/email_digest/email_digest.py
+++ b/erpnext/setup/doctype/email_digest/email_digest.py
@@ -84,8 +84,7 @@
common_msg)
if msg_for_this_receipient:
frappe.sendmail(recipients=user_id,
- subject="[ERPNext] [{frequency} Digest] {name}".format(
- frequency=self.frequency, name=self.name),
+ subject="{frequency} Digest".format(frequency=self.frequency),
message=msg_for_this_receipient, bulk=True)
def get_digest_msg(self):
diff --git a/erpnext/setup/doctype/naming_series/naming_series.py b/erpnext/setup/doctype/naming_series/naming_series.py
index 81a4c4e..a1f4879 100644
--- a/erpnext/setup/doctype/naming_series/naming_series.py
+++ b/erpnext/setup/doctype/naming_series/naming_series.py
@@ -69,12 +69,13 @@
# update in property setter
prop_dict = {'options': "\n".join(options), 'default': default}
+
for prop in prop_dict:
- ps_exists = frappe.db.sql("""SELECT name FROM `tabProperty Setter`
- WHERE doc_type = %s AND field_name = 'naming_series'
- AND property = %s""", (doctype, prop))
+ ps_exists = frappe.db.get_value("Property Setter",
+ {"field_name": 'naming_series', 'doc_type': doctype, 'property': prop})
+
if ps_exists:
- ps = frappe.get_doc('Property Setter', ps_exists[0][0])
+ ps = frappe.get_doc('Property Setter', ps_exists)
ps.value = prop_dict[prop]
ps.save()
else:
diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py
index 8ed6374..a1bcc16 100644
--- a/erpnext/setup/install.py
+++ b/erpnext/setup/install.py
@@ -11,7 +11,7 @@
def after_install():
frappe.get_doc({'doctype': "Role", "role_name": "Analytics"}).insert()
set_single_defaults()
- frappe.db.set_default('desktop:home_page', 'setup-wizard')
+ frappe.db.set_default('desktop:home_page', 'setup-wizard');
feature_setup()
from erpnext.setup.page.setup_wizard.setup_wizard import add_all_roles_to
add_all_roles_to("Administrator")
diff --git a/erpnext/setup/page/setup_wizard/setup_wizard.js b/erpnext/setup/page/setup_wizard/setup_wizard.js
index ac720c9..c588e74 100644
--- a/erpnext/setup/page/setup_wizard/setup_wizard.js
+++ b/erpnext/setup/page/setup_wizard/setup_wizard.js
@@ -2,7 +2,7 @@
frappe.pages['setup-wizard'].on_page_load = function(wrapper) {
if(sys_defaults.company) {
- frappe.set_route("desktop");
+ frappe.set_route("desk-home");
return;
}
$(".navbar:first").toggle(false);
diff --git a/erpnext/support/doctype/issue/issue.json b/erpnext/support/doctype/issue/issue.json
index 52f9caf..8335238 100644
--- a/erpnext/support/doctype/issue/issue.json
+++ b/erpnext/support/doctype/issue/issue.json
@@ -597,7 +597,7 @@
"is_submittable": 0,
"issingle": 0,
"istable": 0,
- "modified": "2015-09-07 15:51:26",
+ "modified": "2015-09-24 06:54:33.383186",
"modified_by": "Administrator",
"module": "Support",
"name": "Issue",
@@ -605,7 +605,7 @@
"permissions": [
{
"amend": 0,
- "apply_user_permissions": 0,
+ "apply_user_permissions": 1,
"cancel": 0,
"create": 1,
"delete": 0,
diff --git a/erpnext/support/doctype/issue/issue_list.js b/erpnext/support/doctype/issue/issue_list.js
index 7198b0c..355e21a 100644
--- a/erpnext/support/doctype/issue/issue_list.js
+++ b/erpnext/support/doctype/issue/issue_list.js
@@ -1,6 +1,10 @@
frappe.listview_settings['Issue'] = {
colwidths: {"subject": 6},
onload: function(listview) {
+ frappe.route_options = {
+ "status": "Open"
+ };
+
var method = "erpnext.support.doctype.issue.issue.set_multiple_status";
listview.page.add_menu_item(__("Set as Open"), function() {