Merge branch 'develop'
diff --git a/.travis.yml b/.travis.yml
index ace0f7c..f6c4eee 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,6 +6,10 @@
services:
- mysql
+before_install:
+ - "export DISPLAY=:99.0"
+ - "sh -e /etc/init.d/xvfb start"
+
install:
- sudo apt-get purge -y mysql-common
- wget https://raw.githubusercontent.com/frappe/bench/master/install_scripts/setup_frappe.sh
@@ -22,7 +26,9 @@
- bench use test_site
- bench reinstall
- bench build-website
- - bench --verbose run-tests
+ - bench serve &
+ - sleep 10
+ - bench --verbose run-tests --driver Firefox
before_script:
- mysql -e 'create database test_frappe'
@@ -33,6 +39,6 @@
webhooks:
urls:
- https://webhooks.gitter.im/e/92b3bea86d8c5397beef
- on_success: always
- on_failure: always
+ on_success: always
+ on_failure: always
on_start: never
diff --git a/erpnext/__version__.py b/erpnext/__version__.py
index b7b4607..75bd775 100644
--- a/erpnext/__version__.py
+++ b/erpnext/__version__.py
@@ -1,2 +1,2 @@
from __future__ import unicode_literals
-__version__ = '5.0.11'
+__version__ = '5.0.12'
diff --git a/erpnext/accounts/print_format/cheque_printing_format/cheque_printing_format.json b/erpnext/accounts/print_format/cheque_printing_format/cheque_printing_format.json
index 9421d45..8c9c266 100755
--- a/erpnext/accounts/print_format/cheque_printing_format/cheque_printing_format.json
+++ b/erpnext/accounts/print_format/cheque_printing_format/cheque_printing_format.json
@@ -1,15 +1,15 @@
{
- "creation": "2012-04-11 13:16:56",
- "doc_type": "Journal Entry",
- "docstatus": 0,
- "doctype": "Print Format",
- "html": "<div style=\"position: relative\">\n\n\t{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n<div class=\"page-break\">\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Payment Advice\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n{%- for label, value in (\n (_(\"Voucher Date\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Reference / Cheque No.\"), doc.cheque_no),\n (_(\"Reference / Cheque Date\"), frappe.utils.formatdate(doc.cheque_date))\n ) -%}\n <div class=\"row\">\n <div class=\"col-xs-4\"><label class=\"text-right\">{{ label }}</label></div>\n <div class=\"col-xs-8\">{{ value }}</div>\n </div>\n{%- endfor -%}\n\t<hr>\n\t<p>{{ _(\"This amount is in full / part settlement of the listed bills\") }}:</p>\n{%- for label, value in (\n (_(\"Amount\"), \"<strong>\" + doc.get_formatted(\"total_amount\") + \"</strong><br>\" + (doc.total_amount_in_words or \"\") + \"<br>\"),\n (_(\"References\"), doc.remark)\n ) -%}\n <div class=\"row\">\n <div class=\"col-xs-4\"><label class=\"text-right\">{{ label }}</label></div>\n <div class=\"col-xs-8\">{{ value }}</div>\n </div>\n {%- endfor -%}\n <hr>\n\t<div style=\"position: absolute; top: 14cm; left: 0cm;\">\n\t\tPrepared By</div>\n\t<div style=\"position: absolute; top: 14cm; left: 5.5cm;\">\n\t\tAuthorised Signatory</div>\n\t<div style=\"position: absolute; top: 14cm; left: 11cm;\">\n\t\tReceived Payment as Above</div>\n\t<div style=\"position: absolute; top: 16.4cm; left: 5.9cm;\">\n\t\t<strong>_____________</strong></div>\n\t<div style=\"position: absolute; top: 16.7cm; left: 6cm;\">\n\t\t<strong>A/C Payee</strong></div>\n\t<div style=\"position: absolute; top: 16.7cm; left: 5.9cm;\">\n\t\t<strong>_____________</strong></div>\n\t<div style=\"position: absolute; top: 16.9cm; left: 12cm;\">\n\t\t{{ frappe.utils.formatdate(doc.cheque_date) }}</div>\n\t<div style=\"position: absolute; top: 17.9cm; left: 1cm;\">\n\t\t{{ doc.pay_to_recd_from }}</div>\n\t<div style=\"position: absolute; top: 18.6cm; left: 1cm; width: 7cm;\">\n\t\t{{ doc.total_amount_in_words }}</div>\n\t<div style=\"position: absolute; top: 19.7cm; left: 12cm;\">\n\t\t{{ doc.total_amount }}</div>\n</div>",
- "idx": 1,
- "modified": "2015-01-12 11:03:17.032512",
- "modified_by": "Administrator",
- "module": "Accounts",
- "name": "Cheque Printing Format",
- "owner": "Administrator",
- "print_format_type": "Server",
+ "creation": "2012-04-11 13:16:56",
+ "custom_format": 1,
+ "doc_type": "Journal Entry",
+ "docstatus": 0,
+ "doctype": "Print Format",
+ "html": "<div style=\"position: relative\">\n\n\t{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n<div class=\"page-break\">\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Payment Advice\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n{%- for label, value in (\n (_(\"Voucher Date\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Reference / Cheque No.\"), doc.cheque_no),\n (_(\"Reference / Cheque Date\"), frappe.utils.formatdate(doc.cheque_date))\n ) -%}\n <div class=\"row\">\n <div class=\"col-xs-4\"><label class=\"text-right\">{{ label }}</label></div>\n <div class=\"col-xs-8\">{{ value }}</div>\n </div>\n{%- endfor -%}\n\t<hr>\n\t<p>{{ _(\"This amount is in full / part settlement of the listed bills\") }}:</p>\n{%- for label, value in (\n (_(\"Amount\"), \"<strong>\" + doc.get_formatted(\"total_amount\") + \"</strong><br>\" + (doc.total_amount_in_words or \"\") + \"<br>\"),\n (_(\"References\"), doc.remark)\n ) -%}\n <div class=\"row\">\n <div class=\"col-xs-4\"><label class=\"text-right\">{{ label }}</label></div>\n <div class=\"col-xs-8\">{{ value }}</div>\n </div>\n {%- endfor -%}\n <hr>\n\t<div style=\"position: absolute; top: 14cm; left: 0cm;\">\n\t\tPrepared By</div>\n\t<div style=\"position: absolute; top: 14cm; left: 5.5cm;\">\n\t\tAuthorised Signatory</div>\n\t<div style=\"position: absolute; top: 14cm; left: 11cm;\">\n\t\tReceived Payment as Above</div>\n\t<div style=\"position: absolute; top: 16.4cm; left: 5.9cm;\">\n\t\t<strong>_____________</strong></div>\n\t<div style=\"position: absolute; top: 16.7cm; left: 6cm;\">\n\t\t<strong>A/C Payee</strong></div>\n\t<div style=\"position: absolute; top: 16.7cm; left: 5.9cm;\">\n\t\t<strong>_____________</strong></div>\n\t<div style=\"position: absolute; top: 16.9cm; left: 12cm;\">\n\t\t{{ frappe.utils.formatdate(doc.cheque_date) }}</div>\n\t<div style=\"position: absolute; top: 17.9cm; left: 1cm;\">\n\t\t{{ doc.pay_to_recd_from }}</div>\n\t<div style=\"position: absolute; top: 18.6cm; left: 1cm; width: 7cm;\">\n\t\t{{ doc.total_amount_in_words }}</div>\n\t<div style=\"position: absolute; top: 19.7cm; left: 12cm;\">\n\t\t{{ doc.get_formatted(\"total_amount\") }}</div>\n</div>",
+ "idx": 1,
+ "modified": "2015-05-29 01:57:51.203850",
+ "modified_by": "Administrator",
+ "name": "Cheque Printing Format",
+ "owner": "Administrator",
+ "print_format_type": "Server",
"standard": "Yes"
-}
+}
\ No newline at end of file
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order_list.js b/erpnext/buying/doctype/purchase_order/purchase_order_list.js
index 08bf0fe..ee0c9bf 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order_list.js
+++ b/erpnext/buying/doctype/purchase_order/purchase_order_list.js
@@ -12,7 +12,6 @@
return [__("Completed"), "green", "per_received,=,100|per_billed,=,100|status,!=,Stopped"];
}
},
- order_by: "per_received asc, modified desc",
onload: function(listview) {
var method = "erpnext.buying.doctype.purchase_order.purchase_order.stop_or_unstop_purchase_orders";
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index c8bbeff..ec34b53 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -5,7 +5,7 @@
app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
app_icon = "icon-th"
app_color = "#e74c3c"
-app_version = "5.0.11"
+app_version = "5.0.12"
error_report_email = "support@erpnext.com"
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 813b1fc..f9590a9 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -160,3 +160,4 @@
erpnext.patches.v5_0.set_footer_address
execute:frappe.db.set_value("Backup Manager", None, "send_backups_to_dropbox", 1 if frappe.db.get_value("Backup Manager", None, "upload_backups_to_dropbox") in ("Daily", "Weekly") else 0)
execute:frappe.db.sql_list("delete from `tabDocPerm` where parent='Issue' and modified_by='Administrator' and role='Guest'")
+erpnext.patches.v5_0.update_item_and_description_again
diff --git a/erpnext/patches/v5_0/update_item_and_description_again.py b/erpnext/patches/v5_0/update_item_and_description_again.py
new file mode 100644
index 0000000..6222748
--- /dev/null
+++ b/erpnext/patches/v5_0/update_item_and_description_again.py
@@ -0,0 +1,49 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+import frappe
+from frappe.utils import cstr
+import re
+
+def execute():
+ item_details = frappe._dict()
+ for d in frappe.db.sql("select name, description from `tabItem`", as_dict=1):
+ description = cstr(d.description).strip()
+ new_desc = extract_description(description)
+
+ item_details.setdefault(d.name, frappe._dict({
+ "old_description": description,
+ "new_description": new_desc
+ }))
+
+
+ dt_list= ["Purchase Order Item","Supplier Quotation Item", "BOM", "BOM Explosion Item" , \
+ "BOM Item", "Opportunity Item" , "Quotation Item" , "Sales Order Item" , "Delivery Note Item" , \
+ "Material Request Item" , "Purchase Receipt Item" , "Stock Entry Detail"]
+ for dt in dt_list:
+ frappe.reload_doctype(dt)
+ records = frappe.db.sql("""select name, `{0}` as item_code, description from `tab{1}`
+ where description is not null and description like '%%<table%%'"""
+ .format("item" if dt=="BOM" else "item_code", dt), as_dict=1)
+
+ count = 1
+ for d in records:
+ if d.item_code and item_details.get(d.item_code) \
+ and cstr(d.description) == item_details.get(d.item_code).old_description:
+ desc = item_details.get(d.item_code).new_description
+ else:
+ desc = extract_description(cstr(d.description))
+
+ frappe.db.sql("""update `tab{0}` set description = %s
+ where name = %s """.format(dt), (desc, d.name))
+
+ count += 1
+ if count % 500 == 0:
+ frappe.db.commit()
+
+
+def extract_description(desc):
+ for tag in ("img", "table", "tr", "td"):
+ desc = re.sub("\</*{0}[^>]*\>".format(tag), "", desc)
+
+ return desc
diff --git a/erpnext/patches/v5_0/update_item_description_and_image.py b/erpnext/patches/v5_0/update_item_description_and_image.py
index 6b47052..a18df2f 100644
--- a/erpnext/patches/v5_0/update_item_description_and_image.py
+++ b/erpnext/patches/v5_0/update_item_description_and_image.py
@@ -11,23 +11,23 @@
for d in frappe.db.sql("select name, description_html, description from `tabItem`", as_dict=1):
description = cstr(d.description_html).strip() or cstr(d.description).strip()
image_url, new_desc = extract_image_and_description(description)
-
+
item_details.setdefault(d.name, frappe._dict({
"old_description": description,
"new_description": new_desc,
"image_url": image_url
}))
-
-
+
+
dt_list= ["Purchase Order Item","Supplier Quotation Item", "BOM", "BOM Explosion Item" , \
"BOM Item", "Opportunity Item" , "Quotation Item" , "Sales Order Item" , "Delivery Note Item" , \
"Material Request Item" , "Purchase Receipt Item" , "Stock Entry Detail"]
for dt in dt_list:
frappe.reload_doctype(dt)
- records = frappe.db.sql("""select name, `{0}` as item_code, description from `tab{1}`
+ records = frappe.db.sql("""select name, `{0}` as item_code, description from `tab{1}`
where description is not null and image is null and description like '%%<img%%'"""
.format("item" if dt=="BOM" else "item_code", dt), as_dict=1)
-
+
count = 1
for d in records:
if d.item_code and item_details.get(d.item_code) \
@@ -40,7 +40,7 @@
if image_url:
frappe.db.sql("""update `tab{0}` set description = %s, image = %s
where name = %s """.format(dt), (desc, image_url, d.name))
-
+
count += 1
if count % 500 == 0:
frappe.db.commit()
@@ -49,5 +49,5 @@
def extract_image_and_description(data):
image_url = find_first_image(data)
desc = re.sub("\<img[^>]+\>", "", data)
-
- return image_url, desc
\ No newline at end of file
+
+ return image_url, desc
diff --git a/erpnext/selling/doctype/sales_order/sales_order_list.js b/erpnext/selling/doctype/sales_order/sales_order_list.js
index 085d0e8..e0c75b6 100644
--- a/erpnext/selling/doctype/sales_order/sales_order_list.js
+++ b/erpnext/selling/doctype/sales_order/sales_order_list.js
@@ -14,7 +14,6 @@
return [__("Completed"), "green", "per_delivered,=,100|per_billed,=,100|status,!=,Stopped"];
}
},
- order_by: "per_delivered asc, modified desc",
onload: function(listview) {
var method = "erpnext.selling.doctype.sales_order.sales_order.stop_or_unstop_sales_orders";
diff --git a/erpnext/stock/doctype/serial_no/serial_no.json b/erpnext/stock/doctype/serial_no/serial_no.json
index 9d31f09..3ef2e15 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.json
+++ b/erpnext/stock/doctype/serial_no/serial_no.json
@@ -151,19 +151,20 @@
},
{
"fieldname": "purchase_document_type",
- "fieldtype": "Select",
+ "fieldtype": "Link",
"label": "Creation Document Type",
"no_copy": 1,
- "options": "\nPurchase Receipt\nStock Entry\nSerial No",
+ "options": "DocType",
"permlevel": 0,
"read_only": 1
},
{
"fieldname": "purchase_document_no",
- "fieldtype": "Data",
+ "fieldtype": "Dynamic Link",
"hidden": 0,
"label": "Creation Document No",
"no_copy": 1,
+ "options": "purchase_document_type",
"permlevel": 0,
"read_only": 1
},
@@ -417,7 +418,7 @@
"icon": "icon-barcode",
"idx": 1,
"in_create": 0,
- "modified": "2015-02-20 05:08:12.961403",
+ "modified": "2015-05-28 21:35:58.378231",
"modified_by": "Administrator",
"module": "Stock",
"name": "Serial No",
diff --git a/erpnext/stock/doctype/serial_no/serial_no.py b/erpnext/stock/doctype/serial_no/serial_no.py
index 59a0667..0b0246e 100644
--- a/erpnext/stock/doctype/serial_no/serial_no.py
+++ b/erpnext/stock/doctype/serial_no/serial_no.py
@@ -34,6 +34,9 @@
self.validate_item()
self.on_stock_ledger_entry()
+ valid_purchase_document_type = ("Purchase Receipt", "Stock Entry", "Serial No")
+ self.validate_value("purchase_document_type", "in", valid_purchase_document_type)
+
def set_maintenance_status(self):
if not self.warranty_expiry_date and not self.amc_expiry_date:
self.maintenance_status = None
diff --git a/erpnext/templates/print_formats/includes/item_table_description.html b/erpnext/templates/print_formats/includes/item_table_description.html
index e0824a2..34f95b9 100644
--- a/erpnext/templates/print_formats/includes/item_table_description.html
+++ b/erpnext/templates/print_formats/includes/item_table_description.html
@@ -1,5 +1,5 @@
{% if doc.in_format_data("image") and doc.get("image") and not doc.is_print_hide("image")-%}
-<div class="pull-left" style="max-width: 20%; margin-right: 10px;">
+<div class="pull-left" style="max-width: 38.2%; margin-right: 10px;">
<img src="{{ doc.image }}" style="max-width: 100%">
</div>
{%- endif %}
@@ -8,7 +8,7 @@
<div class="primary">{{ doc.item_code }}</div>
{%- endif %}
{% if (doc.in_format_data("item_name") and
- (not doc.in_format_data("item_code") or doc.is_print_hide("item_code")
+ (not doc.in_format_data("item_code") or doc.is_print_hide("item_code")
or doc.item_code != doc.item_name)) -%}
<div class="primary">{{ doc.get_formatted("item_name") }}</div>
{%- endif %}
diff --git a/erpnext/tests/test_client.py b/erpnext/tests/test_client.py
new file mode 100644
index 0000000..ef412bf
--- /dev/null
+++ b/erpnext/tests/test_client.py
@@ -0,0 +1,25 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+from __future__ import unicode_literals
+
+import unittest, frappe
+from frappe.utils import sel
+from frappe.utils import formatdate
+
+selenium_tests = True
+
+class TestLogin(unittest.TestCase):
+ def setUp(self):
+ sel.login()
+
+ def test_material_request(self):
+ sel.new_doc("Stock", "Material Request")
+ sel.set_field("company", "_Test Company")
+ sel.add_child("items")
+ sel.set_field("item_code", "_Test Item")
+ sel.set_field("qty", "1")
+ sel.set_field("warehouse", "_Test Warehouse - _TC")
+ sel.set_field("schedule_date", formatdate())
+ sel.done_add_child("items")
+ sel.primary_action()
+ sel.wait_for_state("clean")
diff --git a/setup.py b/setup.py
index 7fb8bcb..18f95df 100644
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,6 @@
from setuptools import setup, find_packages
-version = "5.0.11"
+version = "5.0.12"
with open("requirements.txt", "r") as f:
install_requires = f.readlines()
diff --git a/test_sites/test_site/site_config.json b/test_sites/test_site/site_config.json
index 96f3446..7d1194a 100644
--- a/test_sites/test_site/site_config.json
+++ b/test_sites/test_site/site_config.json
@@ -1,10 +1,12 @@
{
"db_name": "test_frappe",
"db_password": "test_frappe",
+ "auto_email_id": "test@example.com",
+ "mail_server": "smtp.example.com",
+ "mail_login": "test@example.com",
+ "mail_password": "test",
"admin_password": "admin",
- "auto_email_id": "admin@example.com",
- "host_name": "http://localhost:8888",
- "auto_email_id": "admin@example.com",
- "mute_emails": 1,
+ "run_selenium_tests": 1,
+ "host_name": "http://localhost:8000",
"install_apps": ["erpnext"]
}