[ui] data import tool
This commit is contained in:
parent
112887dc0e
commit
448d2c78bf
11 changed files with 245 additions and 349 deletions
|
|
@ -1,4 +0,0 @@
|
|||
<br>
|
||||
<p>
|
||||
<a class="btn btn-default btn-small" href="/api/method/frappe.core.page.data_import_tool.exporter.get_template?doctype={%= me.doctype %}&parent_doctype={%= me.doctype %}&with_data={% me.with_data %}&all_doctypes={% if(data.length > 1) { %}Yes{% } else { %}No{% } %}">{%= __("Download") %}</a>
|
||||
</p>
|
||||
|
|
@ -1,25 +1,69 @@
|
|||
<div class="data-import-tool">
|
||||
<div class="data-import-selector">
|
||||
<select class="form-control doctype" style="width: 200px" placeholder="{%= __("Select Type") %}">
|
||||
</select>
|
||||
<h6>{%= __("Select Type of Document to Import") %}</h6>
|
||||
<div>
|
||||
<select class="form-control doctype" style="width: 200px" placeholder="{%= __("Select Type") %}">
|
||||
<option value=""></option>
|
||||
{% for (var i=0, l= frappe.boot.user.can_import.length; i < l; i++) {
|
||||
var doctype = frappe.boot.user.can_import[i]; %}
|
||||
<option value="{%= doctype %}">{%= __(doctype) %}</option>
|
||||
{% } %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section export hide">
|
||||
<div class="export-import-section hide">
|
||||
<hr>
|
||||
<h3>{%= __("Export") %}</h3>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" name="dit-with-data"> <span>{%= __("Download with data") %}</span>
|
||||
</label>
|
||||
<p class="text-muted">{%= __("To import or update records, you must first download the template for importing.") %}</p>
|
||||
<div class="row" style="max-width: 700px;">
|
||||
<div class="col-sm-4">
|
||||
<p><a class="btn btn-default btn-sm btn-download-template">
|
||||
{%= __("Download Blank Template") %}</a></p>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<h6 class="text-muted">{%= __("Recommended for inserting new records.") %}</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="data-import-download">
|
||||
<div class="text-muted"><br>{%= __("Select type to export") %}</div>
|
||||
<div class="row" style="max-width: 700px;">
|
||||
<div class="col-sm-4">
|
||||
<p><a class="btn btn-default btn-sm btn-download-data">
|
||||
{%= __("Download with Data") %}</a></p>
|
||||
</div>
|
||||
<div class="col-sm-8">
|
||||
<h6 class="text-muted">{%= __("Recommended bulk editing records via import, or understanding the import format.") %}</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section import hide">
|
||||
<hr>
|
||||
<h3>{%= __("Import") %}</h3>
|
||||
|
||||
</div>
|
||||
<div class="section help hide">
|
||||
<h3>{%= __("Help") %}</h3>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="upload-area"></div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" name="always_insert">
|
||||
{%= __("Insert all records, even if ID matches.") %}
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" name="submit_after_import">
|
||||
{%= __("Submit after importing.") %}
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" name="ignore_encoding_errors">
|
||||
{%= __("Ignore encoding errors.") %}
|
||||
</label>
|
||||
</div>
|
||||
<p>
|
||||
<button class="btn btn-sm btn-primary btn-import">Import</button>
|
||||
</p>
|
||||
</div>
|
||||
<div class="import-log hide col-md-6">
|
||||
<h3>Import Log</h3>
|
||||
<div class="import-log-messages"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
<ul class="nav nav-pills nav-stacked" style="margin-right: -15px;">
|
||||
<li class="h6 module-sidebar-item" data-section="export">
|
||||
<a class="module-link">
|
||||
<i class="icon icon-chevron-right pull-right" style="display: none;"></i>
|
||||
{%= __("Export") %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="h6 module-sidebar-item" data-section="import">
|
||||
<a class="module-link">
|
||||
<i class="icon icon-chevron-right pull-right" style="display: none;"></i>
|
||||
{%= __("Import") %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="h6 module-sidebar-item" data-section="help">
|
||||
<a class="module-link">
|
||||
<i class="icon icon-chevron-right pull-right" style="display: none;"></i>
|
||||
{%= __("Help") %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -1,9 +1,7 @@
|
|||
.data-import-tool .section {
|
||||
.data-import-tool {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.data-import-selector {
|
||||
padding: 15px;
|
||||
border-bottom: 1px solid #d1d8dd;
|
||||
background-color: #F0F4F7;
|
||||
.data-import-tool hr {
|
||||
margin: 10px -15px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,203 +1,91 @@
|
|||
|
||||
|
||||
frappe.DataImportTool = Class.extend({
|
||||
init: function(page) {
|
||||
this.page = page;
|
||||
this.make_main();
|
||||
this.make_sidebar();
|
||||
this.setup_select();
|
||||
},
|
||||
make_main: function() {
|
||||
var me = this;
|
||||
this.page.main.html(frappe.render_template("data_import_main", {}));
|
||||
this.select = this.page.main.find("select.doctype");
|
||||
frappe.call({
|
||||
method: 'frappe.core.page.data_import_tool.data_import_tool.get_doctypes',
|
||||
callback: function(r) {
|
||||
me.select.add_options([""].concat(r.message));
|
||||
me.doctypes = r.message;
|
||||
if(frappe.route_options) {
|
||||
me.set_route_options();
|
||||
} else {
|
||||
me.select.focus();
|
||||
}
|
||||
}
|
||||
init: function(parent) {
|
||||
this.page = frappe.ui.make_app_page({
|
||||
parent: parent,
|
||||
title: __("Data Import Tool"),
|
||||
single_column: true
|
||||
});
|
||||
},
|
||||
make_sidebar: function() {
|
||||
var me = this;
|
||||
this.page.sidebar.html(frappe.render_template("data_import_sidebar", {}));
|
||||
// bind click
|
||||
this.page.sidebar.find("a").on("click", function() {
|
||||
var li = $(this).parents("li:first");
|
||||
if (li.hasClass("active"))
|
||||
return false;
|
||||
|
||||
var section = li.attr("data-section");
|
||||
|
||||
// active
|
||||
me.page.sidebar.find("li.active").removeClass("active");
|
||||
me.page.main.find(".section").addClass("hide");
|
||||
me.page.main.find("." + section).removeClass("hide");
|
||||
li.addClass("active");
|
||||
|
||||
});
|
||||
|
||||
$(me.page.sidebar.find("a")[0]).click();
|
||||
},
|
||||
setup_select: function() {
|
||||
var me = this;
|
||||
this.download_area = this.page.main.find(".data-import-download");
|
||||
this.select.on("change", function(){
|
||||
me.doctype = $(this).val();
|
||||
|
||||
if(!me.doctype) {
|
||||
return;
|
||||
}
|
||||
|
||||
me.download_area.empty();
|
||||
me.with_data = $('[name="dit-with-data"]:checked').length ? 'Yes' : 'No'
|
||||
|
||||
frappe.model.with_doctype(me.doctype, function() {
|
||||
// get options
|
||||
return frappe.call({
|
||||
btn: this,
|
||||
method: 'frappe.core.page.data_import_tool.data_import_tool.get_doctype_options',
|
||||
args: {doctype: me.doctype},
|
||||
callback: function(r) {
|
||||
$(frappe.render_template("data_import_download",
|
||||
{data:r.message, me: me})).appendTo(me.download_area);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
this.make();
|
||||
this.make_upload();
|
||||
},
|
||||
set_route_options: function() {
|
||||
if(frappe.route_options
|
||||
&& frappe.route_options.doctype
|
||||
&& in_list(this.doctypes, frappe.route_options.doctype)) {
|
||||
this.select.val(frappe.route_options.doctype).change();
|
||||
&& in_list(frappe.boot.user.can_import, frappe.route_options.doctype)) {
|
||||
me.select.val(frappe.route_options.doctype).change();
|
||||
frappe.route_options = null;
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
make: function() {
|
||||
var me = this;
|
||||
frappe.boot.user.can_import = frappe.boot.user.can_import.sort();
|
||||
|
||||
frappe.pages['data-import-tool'].onload = function(wrapper) {
|
||||
wrapper.app_page = frappe.ui.make_app_page({
|
||||
parent: wrapper,
|
||||
title: __("Data Import / Export Tool"),
|
||||
icon: "icon-upload"
|
||||
});
|
||||
$(frappe.render_template("data_import_main", this)).appendTo(this.page.main);
|
||||
|
||||
frappe.data_import_tool = new frappe.DataImportTool(wrapper.page);
|
||||
|
||||
|
||||
return;
|
||||
|
||||
|
||||
|
||||
// check permission for import
|
||||
if(!((frappe.boot.user.can_import && frappe.boot.user.can_import.length) ||
|
||||
user_roles.indexOf("System Manager")!==-1)) {
|
||||
frappe.show_not_permitted("data-import-tool");
|
||||
return false;
|
||||
}
|
||||
|
||||
$(wrapper).find('.layout-main-section').append('<h3>1. ' + __("Download Template") + '</h3>\
|
||||
<div style="min-height: 150px">\
|
||||
<p class="help">' + __("Download a template for importing a table.") + '</p>\
|
||||
<div class="row">\
|
||||
<div class="col-md-6">\
|
||||
<select class="form-control" style="width: 200px" name="dit-doctype">\
|
||||
</select><br><br>\
|
||||
<label>\
|
||||
<input type="checkbox" name="dit-with-data"> <span>'+ __("Download with data") + '</span>\
|
||||
</label>\
|
||||
<p class="text-muted">' + __("Export all rows in CSV fields for re-upload. This is ideal for bulk-editing.") + '</p>\
|
||||
</div>\
|
||||
<div class="col-md-6">\
|
||||
<div class="alert alert-warning hide" id="dit-download"></div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<hr>\
|
||||
<h3>2. '+ __("Import Data") + '</h3>\
|
||||
<p class="help">' + __("Attach .csv file to import data") + '</p>\
|
||||
<div id="dit-upload-area"></div><br>\
|
||||
<div class="dit-progress-area" style="display: None"></div>\
|
||||
<p id="dit-output"></p>\
|
||||
<div class="msg-box">\
|
||||
<h4>' + __("Help: Importing non-English data in Microsoft Excel") + '</h4>\
|
||||
<p>' + __("While uploading non English files ensure that the encoding is UTF-8.") + '</p>\
|
||||
<ol>\
|
||||
<li>' + __("In Excel, save the file in CSV (Comma Delimited) format") + '</li>\
|
||||
<li>' + __("Open this saved file in Notepad") + '</li>\
|
||||
<li>' + __("Click on File -> Save As") + '</li>\
|
||||
<li>' + __("File Name: <your filename>.csv<br />\
|
||||
Save as type: Text Documents (*.txt)<br />\
|
||||
Encoding: UTF-8") + '\
|
||||
</li>\
|
||||
<li>' + __("Click on Save") + '</li>\
|
||||
</ol>\
|
||||
</p>\
|
||||
</div>');
|
||||
|
||||
$select = $(wrapper).find('[name="dit-doctype"]');
|
||||
|
||||
frappe.messages.waiting($(wrapper).find(".dit-progress-area").toggle(false),
|
||||
__("Performing hardcore import process")+ "....", 100);
|
||||
|
||||
// check if template with_data is allowed
|
||||
var validate_download_with_data = function(doctype, verbose) {
|
||||
// if no export permission, uncheck with data
|
||||
var with_data = $('[name="dit-with-data"]').prop("checked");
|
||||
if(with_data && !frappe.model.can_export(doctype)) {
|
||||
$('[name="dit-with-data"]').prop("checked", false);
|
||||
with_data = false;
|
||||
|
||||
if(verbose) {
|
||||
msgprint(__("You are not allowed to export the data of: {0}. Downloading empty template.", [doctype]));
|
||||
this.select = this.page.main.find("select.doctype");
|
||||
this.select.on("change", function() {
|
||||
me.doctype = $(this).val();
|
||||
me.page.main.find(".export-import-section").toggleClass(!!me.doctype);
|
||||
if(me.doctype) {
|
||||
me.set_btn_links();
|
||||
// set button links
|
||||
}
|
||||
}
|
||||
return with_data;
|
||||
};
|
||||
});
|
||||
},
|
||||
set_btn_links: function() {
|
||||
var doctype = encodeURIComponent(this.doctype);
|
||||
this.page.main.find(".btn-download-template").attr("href",
|
||||
"/api/method/frappe.core.page.data_import_tool.exporter.get_template?"
|
||||
+ "doctype=" + doctype
|
||||
+ "&parent_doctype=" + doctype
|
||||
+ "&with_data=No&all_doctypes=Yes");
|
||||
|
||||
wrapper.add_template_download_link = function(doctype) {
|
||||
return $('<a style="cursor: pointer">')
|
||||
.html(doctype)
|
||||
.data('doctype', doctype)
|
||||
.data('all_doctypes', "No")
|
||||
.click(function() {
|
||||
var doctype = $(this).data('doctype');
|
||||
var parent_doctype = $('[name="dit-doctype"]').val();
|
||||
var with_data = validate_download_with_data(parent_doctype || doctype, true);
|
||||
window.location.href = repl(frappe.request.url
|
||||
+ '?cmd=%(cmd)s&doctype=%(doctype)s'
|
||||
+ '&parent_doctype=%(parent_doctype)s'
|
||||
+ '&with_data=%(with_data)s'
|
||||
+ '&all_doctypes=%(all_doctypes)s',
|
||||
{
|
||||
cmd: 'frappe.core.page.data_import_tool.exporter.get_template',
|
||||
doctype: doctype,
|
||||
parent_doctype: parent_doctype,
|
||||
with_data: with_data ? 'Yes' : 'No',
|
||||
all_doctypes: $(this).data('all_doctypes')
|
||||
});
|
||||
})
|
||||
.appendTo('#dit-download');
|
||||
}
|
||||
this.page.main.find(".btn-download-data").attr("href",
|
||||
"/api/method/frappe.core.page.data_import_tool.exporter.get_template?"
|
||||
+ "doctype=" + doctype
|
||||
+ "&parent_doctype=" + doctype
|
||||
+ "&with_data=Yes&all_doctypes=Yes");
|
||||
},
|
||||
make_upload: function() {
|
||||
var me = this;
|
||||
frappe.upload.make({
|
||||
parent: this.page.main.find(".upload-area"),
|
||||
btn: this.page.main.find(".btn-import"),
|
||||
get_params: function() {
|
||||
return {
|
||||
submit_after_import: me.page.main.find('[name="submit_after_import"]').prop("checked"),
|
||||
ignore_encoding_errors: me.page.main.find('[name="ignore_encoding_errors"]').prop("checked"),
|
||||
overwrite: !me.page.main.find('[name="always_insert"]').prop("checked")
|
||||
}
|
||||
},
|
||||
args: {
|
||||
method: 'frappe.core.page.data_import_tool.importer.upload',
|
||||
},
|
||||
onerror: function(r) {
|
||||
me.onerror(r);
|
||||
},
|
||||
callback: function(attachment, r) {
|
||||
if(r.message.error) {
|
||||
me.onerror(r);
|
||||
} else {
|
||||
// replace links if error has occured
|
||||
r.messages = ["<h5 style='color:green'>" + __("Import Successful!") + "</h5>"].
|
||||
concat(r.message.messages)
|
||||
|
||||
// load options
|
||||
$select.change(function() {
|
||||
});
|
||||
me.write_messages(r);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var write_messages = function(r) {
|
||||
$(wrapper).find(".dit-progress-area").toggle(false);
|
||||
$("#dit-output").empty();
|
||||
},
|
||||
write_messages: function(r) {
|
||||
this.page.main.find(".import-log").removeClass("hide");
|
||||
var parent = this.page.main.find(".import-log-messages").empty();
|
||||
|
||||
$.each(r.messages, function(i, v) {
|
||||
var $p = $('<p></p>').html(frappe.markdown(v)).appendTo('#dit-output');
|
||||
$("<hr>").appendTo('#dit-output');
|
||||
var $p = $('<p></p>').html(frappe.markdown(v)).appendTo(parent);
|
||||
if(v.substr(0,5)=='Error') {
|
||||
$p.css('color', 'red');
|
||||
} else if(v.substr(0,8)=='Inserted') {
|
||||
|
|
@ -208,73 +96,36 @@ frappe.pages['data-import-tool'].onload = function(wrapper) {
|
|||
$p.css('color', '#777');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var onerror = function(r) {
|
||||
$(wrapper).find(".dit-progress-area").toggle(false);
|
||||
r.messages = $.map(r.message.messages, function(v) {
|
||||
var msg = v.replace("Inserted", "Valid")
|
||||
.replace("Updated", "Valid").split("<");
|
||||
if (msg.length > 1) {
|
||||
v = msg[0] + (msg[1].split(">").slice(-1)[0]);
|
||||
} else {
|
||||
v = msg[0];
|
||||
}
|
||||
return v;
|
||||
});
|
||||
},
|
||||
onerror: function(r) {
|
||||
if(r.message) {
|
||||
// bad design: moves r.messages to r.message.messages
|
||||
r.messages = $.map(r.message.messages, function(v) {
|
||||
var msg = v.replace("Inserted", "Valid")
|
||||
.replace("Updated", "Valid").split("<");
|
||||
if (msg.length > 1) {
|
||||
v = msg[0] + (msg[1].split(">").slice(-1)[0]);
|
||||
} else {
|
||||
v = msg[0];
|
||||
}
|
||||
return v;
|
||||
});
|
||||
|
||||
r.messages = ["<h4 style='color:red'>" + __("Import Failed!") + "</h4>"]
|
||||
.concat(r.messages);
|
||||
r.messages = ["<h4 style='color:red'>" + __("Import Failed") + "</h4>"]
|
||||
.concat(r.messages);
|
||||
|
||||
write_messages(r);
|
||||
};
|
||||
r.messages.push("Please correct and import again.");
|
||||
|
||||
// upload
|
||||
frappe.upload.make({
|
||||
parent: $('#dit-upload-area'),
|
||||
args: {
|
||||
method: 'frappe.core.page.data_import_tool.importer.upload'
|
||||
},
|
||||
onerror: onerror,
|
||||
callback: function(attachment, r) {
|
||||
if(r.message.error) {
|
||||
onerror(r);
|
||||
} else {
|
||||
// replace links if error has occured
|
||||
r.messages = ["<h4 style='color:green'>" + __("Import Successful!") + "</h4>"].
|
||||
concat(r.message.messages)
|
||||
|
||||
write_messages(r);
|
||||
}
|
||||
this.write_messages(r);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// add overwrite option
|
||||
var $submit_btn = $('#dit-upload-area button.btn-upload')
|
||||
.html('<i class="icon-upload"></i> ' + __("Upload and Import"));
|
||||
|
||||
$('<label><input type="checkbox" name="overwrite"> <span>' + __("Overwrite") + '</span></label>\
|
||||
<p class="text-muted">' + __("If you are uploading a child table (for example Item Price), the all the entries of that table will be deleted (for that parent record) and new entries will be made.") + '</p><br>')
|
||||
.insertBefore($submit_btn);
|
||||
|
||||
// add submit option
|
||||
$('<label><input type="checkbox" name="_submit"> <span>' + __("Submit") + '</span></label>\
|
||||
<p class="text-muted">' + __("If you are inserting new records (overwrite not checked) \
|
||||
and if you have submit permission, the record will be submitted.") + '</p><br>')
|
||||
.insertBefore($submit_btn);
|
||||
|
||||
// add ignore option
|
||||
$('<label><input type="checkbox" name="ignore_encoding_errors"> <span>' + __("Ignore Encoding Errors") + '</span></label><br></br>')
|
||||
.insertBefore($submit_btn);
|
||||
|
||||
// rename button
|
||||
$('#dit-upload-area button.btn-upload')
|
||||
.click(function() {
|
||||
$('#dit-output').empty();
|
||||
$(wrapper).find(".dit-progress-area").toggle(true);
|
||||
});
|
||||
frappe.pages['data-import-tool'].onload = function(wrapper) {
|
||||
frappe.data_import_tool = new frappe.DataImportTool(wrapper);
|
||||
}
|
||||
|
||||
frappe.pages['data-import-tool'].onshow = function(wrapper) {
|
||||
wrapper.set_route_options && wrapper.set_route_options();
|
||||
frappe.data_import_tool && frappe.data_import_tool.set_route_options();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False,
|
|||
# extra input params
|
||||
params = json.loads(frappe.form_dict.get("params") or '{}')
|
||||
|
||||
if params.get("_submit"):
|
||||
if params.get("submit_after_import"):
|
||||
submit_after_import = True
|
||||
if params.get("ignore_encoding_errors"):
|
||||
ignore_encoding_errors = True
|
||||
|
|
@ -170,6 +170,7 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False,
|
|||
make_column_map()
|
||||
|
||||
frappe.db.begin()
|
||||
|
||||
if overwrite==None:
|
||||
overwrite = params.get('overwrite')
|
||||
|
||||
|
|
@ -201,7 +202,7 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False,
|
|||
ret.append('Inserted row for %s at #%s' % (getlink(parenttype,
|
||||
doc.parent), unicode(doc.idx)))
|
||||
else:
|
||||
if overwrite and frappe.db.exists(doctype, doc["name"]):
|
||||
if overwrite and doc["name"] and frappe.db.exists(doctype, doc["name"]):
|
||||
original = frappe.get_doc(doctype, doc["name"])
|
||||
original.update(doc)
|
||||
original.ignore_links = ignore_links
|
||||
|
|
@ -252,4 +253,5 @@ def get_parent_field(doctype, parenttype):
|
|||
def delete_child_rows(rows, doctype):
|
||||
"""delete child rows for all parents"""
|
||||
for p in list(set([r[1] for r in rows])):
|
||||
frappe.db.sql("""delete from `tab%s` where parent=%s""" % (doctype, '%s'), p)
|
||||
if p:
|
||||
frappe.db.sql("""delete from `tab{0}` where parent=%s""".format(doctype), p)
|
||||
|
|
|
|||
|
|
@ -7,212 +7,251 @@ from frappe.core.page.data_import_tool.data_import_tool import export_csv
|
|||
import unittest
|
||||
|
||||
class TestDataImportFixtures(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
print "\nTeste for export explicit fixtures"
|
||||
print "see fixtures csv test files in sites folder"
|
||||
|
||||
#start test for Custom Script
|
||||
def test_Custom_Script_fixture_simple(self):
|
||||
fixture = "Custom Script"
|
||||
path = frappe.scrub(fixture) + "_original_style.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Custom_Script_fixture_simple_name_equal_default(self):
|
||||
fixture = ["Custom Script", {"name":["Item-Client"]}]
|
||||
path = frappe.scrub(fixture[0]) + "_simple_name_equal_default.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Custom_Script_fixture_simple_name_equal(self):
|
||||
fixture = ["Custom Script", {"name":["Item-Client"],"op":"="}]
|
||||
path = frappe.scrub(fixture[0]) + "_simple_name_equal.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Custom_Script_fixture_simple_name_not_equal(self):
|
||||
fixture = ["Custom Script", {"name":["Item-Client"],"op":"!="}]
|
||||
path = frappe.scrub(fixture[0]) + "_simple_name_not_equal.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
#without [] around the name...
|
||||
def test_Custom_Script_fixture_simple_name_at_least_equal(self):
|
||||
fixture = ["Custom Script", {"name":"Item-Cli"}]
|
||||
path = frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Custom_Script_fixture_multi_name_equal(self):
|
||||
fixture = ["Custom Script", {"name":["Item-Client", "Customer-Client"],"op":"="}]
|
||||
path = frappe.scrub(fixture[0]) + "_multi_name_equal.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Custom_Script_fixture_multi_name_not_equal(self):
|
||||
fixture = ["Custom Script", {"name":["Item-Client", "Customer-Client"],"op":"!="}]
|
||||
path = frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Custom_Script_fixture_empty_object(self):
|
||||
fixture = ["Custom Script", {}]
|
||||
path = frappe.scrub(fixture[0]) + "_empty_object_should_be_all.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Custom_Script_fixture_just_list(self):
|
||||
fixture = ["Custom Script"]
|
||||
path = frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
# Custom Script regular expression
|
||||
def test_Custom_Script_fixture_rex_no_flags(self):
|
||||
fixture = ["Custom Script", {"name":r"^[i|A]"}]
|
||||
path = frappe.scrub(fixture[0]) + "_rex_no_flags.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Custom_Script_fixture_rex_with_flags(self):
|
||||
fixture = ["Custom Script", {"name":r"^[i|A]", "flags":"L,M"}]
|
||||
path = frappe.scrub(fixture[0]) + "_rex_with_flags.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
|
||||
|
||||
#start test for Custom Field
|
||||
def test_Custom_Field_fixture_simple(self):
|
||||
fixture = "Custom Field"
|
||||
path = frappe.scrub(fixture) + "_original_style.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Custom_Field_fixture_simple_name_equal_default(self):
|
||||
fixture = ["Custom Field", {"name":["Item-vat"]}]
|
||||
path = frappe.scrub(fixture[0]) + "_simple_name_equal_default.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Custom_Field_fixture_simple_name_equal(self):
|
||||
fixture = ["Custom Field", {"name":["Item-vat"],"op":"="}]
|
||||
path = frappe.scrub(fixture[0]) + "_simple_name_equal.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Custom_Field_fixture_simple_name_not_equal(self):
|
||||
fixture = ["Custom Field", {"name":["Item-vat"],"op":"!="}]
|
||||
path = frappe.scrub(fixture[0]) + "_simple_name_not_equal.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
#without [] around the name...
|
||||
def test_Custom_Field_fixture_simple_name_at_least_equal(self):
|
||||
fixture = ["Custom Field", {"name":"Item-va"}]
|
||||
path = frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Custom_Field_fixture_multi_name_equal(self):
|
||||
fixture = ["Custom Field", {"name":["Item-vat", "Bin-vat"],"op":"="}]
|
||||
path = frappe.scrub(fixture[0]) + "_multi_name_equal.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Custom_Field_fixture_multi_name_not_equal(self):
|
||||
fixture = ["Custom Field", {"name":["Item-vat", "Bin-vat"],"op":"!="}]
|
||||
path = frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Custom_Field_fixture_empty_object(self):
|
||||
fixture = ["Custom Field", {}]
|
||||
path = frappe.scrub(fixture[0]) + "_empty_object_should_be_all.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Custom_Field_fixture_just_list(self):
|
||||
fixture = ["Custom Field"]
|
||||
path = frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
# Custom Field regular expression
|
||||
def test_Custom_Field_fixture_rex_no_flags(self):
|
||||
fixture = ["Custom Field", {"name":r"^[r|L]"}]
|
||||
path = frappe.scrub(fixture[0]) + "_rex_no_flags.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Custom_Field_fixture_rex_with_flags(self):
|
||||
fixture = ["Custom Field", {"name":r"^[i|A]", "flags":"L,M"}]
|
||||
path = frappe.scrub(fixture[0]) + "_rex_with_flags.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
|
||||
|
||||
#start test for Doctype
|
||||
def test_Doctype_fixture_simple(self):
|
||||
fixture = "ToDo"
|
||||
path = "Doctype_" + frappe.scrub(fixture) + "_original_style_should_be_all.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Doctype_fixture_simple_name_equal_default(self):
|
||||
fixture = ["ToDo", {"name":["TDI00000008"]}]
|
||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_equal_default.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Doctype_fixture_simple_name_equal(self):
|
||||
fixture = ["ToDo", {"name":["TDI00000002"],"op":"="}]
|
||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_equal.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Doctype_simple_name_not_equal(self):
|
||||
fixture = ["ToDo", {"name":["TDI00000002"],"op":"!="}]
|
||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_not_equal.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
#without [] around the name...
|
||||
def test_Doctype_fixture_simple_name_at_least_equal(self):
|
||||
fixture = ["ToDo", {"name":"TDI"}]
|
||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_simple_name_at_least_equal.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Doctype_multi_name_equal(self):
|
||||
fixture = ["ToDo", {"name":["TDI00000002", "TDI00000008"],"op":"="}]
|
||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_multi_name_equal.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Doctype_multi_name_not_equal(self):
|
||||
fixture = ["ToDo", {"name":["TDI00000002", "TDI00000008"],"op":"!="}]
|
||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_multi_name_not_equal.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Doctype_fixture_empty_object(self):
|
||||
fixture = ["ToDo", {}]
|
||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_empty_object_should_be_all.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Doctype_fixture_just_list(self):
|
||||
fixture = ["ToDo"]
|
||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_just_list_should_be_all.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
# Doctype regular expression
|
||||
def test_Doctype_fixture_rex_no_flags(self):
|
||||
fixture = ["ToDo", {"name":r"^TDi"}]
|
||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_rex_no_flags_should_be_all.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
def test_Doctype_fixture_rex_with_flags(self):
|
||||
fixture = ["ToDo", {"name":r"^TDi", "flags":"L,M"}]
|
||||
path = "Doctype_" + frappe.scrub(fixture[0]) + "_rex_with_flags_should_be_none.csv"
|
||||
print "teste done {}".format(path)
|
||||
export_csv(fixture, path)
|
||||
self.assertTrue(True)
|
||||
|
||||
|
||||
|
||||
|
|
@ -391,7 +391,7 @@ class Document(BaseDocument):
|
|||
self._action = "submit"
|
||||
self.check_permission("submit")
|
||||
else:
|
||||
raise frappe.DocstatusTransitionError("Cannot change docstatus from 0 to 2")
|
||||
raise frappe.DocstatusTransitionError, _("Cannot change docstatus from 0 to 2")
|
||||
|
||||
elif docstatus==1:
|
||||
if self.docstatus==1:
|
||||
|
|
@ -401,10 +401,10 @@ class Document(BaseDocument):
|
|||
self._action = "cancel"
|
||||
self.check_permission("cancel")
|
||||
else:
|
||||
raise frappe.DocstatusTransitionError("Cannot change docstatus from 1 to 0")
|
||||
raise frappe.DocstatusTransitionError, _("Cannot change docstatus from 1 to 0")
|
||||
|
||||
elif docstatus==2:
|
||||
raise frappe.ValidationError
|
||||
raise frappe.ValidationError, _("Cannot edit cancelled document")
|
||||
|
||||
def set_parent_in_children(self):
|
||||
"""Updates `parent` and `parenttype` property in all children."""
|
||||
|
|
|
|||
2
frappe/public/css/bootstrap.css
vendored
2
frappe/public/css/bootstrap.css
vendored
File diff suppressed because one or more lines are too long
|
|
@ -16,7 +16,7 @@ frappe.ui.make_app_page = function(opts) {
|
|||
*/
|
||||
|
||||
opts.parent.page = new frappe.ui.Page(opts);
|
||||
|
||||
return opts.parent.page;
|
||||
}
|
||||
|
||||
frappe.ui.Page = Class.extend({
|
||||
|
|
|
|||
|
|
@ -22,24 +22,10 @@ frappe.upload = {
|
|||
// get the first file
|
||||
opts.btn.click(function() {
|
||||
// convert functions to values
|
||||
for(key in opts.args) {
|
||||
if(typeof val==="function")
|
||||
opt.args[key] = opts.args[key]();
|
||||
}
|
||||
|
||||
// add other inputs in the div as arguments
|
||||
opts.args.params = {};
|
||||
$upload.find("input[name]").each(function() {
|
||||
var key = $(this).attr("name");
|
||||
var type = $(this).attr("type");
|
||||
if(key!="filedata" && key!="file_url") {
|
||||
if(type === "checkbox") {
|
||||
opts.args.params[key] = $(this).is(":checked");
|
||||
} else {
|
||||
opts.args.params[key] = $(this).val();
|
||||
}
|
||||
}
|
||||
})
|
||||
if(opts.get_params) {
|
||||
opts.args.params = opts.get_params();
|
||||
}
|
||||
|
||||
opts.args.file_url = $upload.find('[name="file_url"]').val();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue