Merge pull request #15356 from adityahase/coverage
feature(coverage): Add test coverage to erpnext travis builds
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
index cb11ece..3234e7a 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_methods.py
@@ -3,8 +3,12 @@
# For license information, please see license.txt
from __future__ import unicode_literals
-import frappe, time, dateutil, math, csv, StringIO
-import amazon_mws_api as mws
+import frappe, time, dateutil, math, csv
+try:
+ from StringIO import StringIO
+except ImportError:
+ from io import StringIO
+import erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_mws_api as mws
from frappe import _
#Get and Create Products
@@ -22,7 +26,7 @@
listings_response = reports.get_report(report_id=report_id)
#Get ASIN Codes
- string_io = StringIO.StringIO(listings_response.original)
+ string_io = StringIO(listings_response.original)
csv_rows = list(csv.reader(string_io, delimiter=str('\t')))
asin_list = list(set([row[1] for row in csv_rows[1:]]))
#break into chunks of 10
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_api.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_api.py
index 1e131e8..bf6d85b 100755
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_api.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_api.py
@@ -9,7 +9,7 @@
import hashlib
import hmac
import base64
-import xml_utils
+from erpnext.erpnext_integrations.doctype.amazon_mws_settings import xml_utils
import re
try:
from xml.etree.ElementTree import ParseError as XMLError
diff --git a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py
index c0a6b8d..249a73f 100644
--- a/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py
+++ b/erpnext/erpnext_integrations/doctype/amazon_mws_settings/amazon_mws_settings.py
@@ -7,7 +7,7 @@
from frappe.model.document import Document
import dateutil
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
-from amazon_methods import get_products_details, get_orders
+from erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_methods import get_products_details, get_orders
class AmazonMWSSettings(Document):
def validate(self):
diff --git a/erpnext/healthcare/utils.py b/erpnext/healthcare/utils.py
index 1045d49..1be82e2 100644
--- a/erpnext/healthcare/utils.py
+++ b/erpnext/healthcare/utils.py
@@ -307,8 +307,8 @@
fee_validity = create_fee_validity(appointment_doc.practitioner, appointment_doc.patient, appointment_doc.appointment_date, ref_invoice)
visited = fee_validity.visited
- print "do_not_update: ", do_not_update
- print "visited: ", visited
+ print("do_not_update: ", do_not_update)
+ print("visited: ", visited)
# Mark All Patient Appointment invoiced = True in the validity range do not cross the max visit
if (method == "on_cancel"):
@@ -410,7 +410,7 @@
lft > %s and rgt < %s""",
(each['lft'], each['rgt']))
for child in child_list:
- print child[0], child[1]
+ print(child[0], child[1])
if not occupied:
occupied = 0
if child[1] == "Occupied":
diff --git a/erpnext/hub_node/doctype/hub_tracked_item/hub_tracked_item.json b/erpnext/hub_node/doctype/hub_tracked_item/hub_tracked_item.json
index 9384adb..2e89887 100644
--- a/erpnext/hub_node/doctype/hub_tracked_item/hub_tracked_item.json
+++ b/erpnext/hub_node/doctype/hub_tracked_item/hub_tracked_item.json
@@ -120,7 +120,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-08-19 22:24:06.207307",
+ "modified": "2018-09-10 11:37:35.951019",
"modified_by": "Administrator",
"module": "Hub Node",
"name": "Hub Tracked Item",
@@ -145,6 +145,25 @@
"share": 1,
"submit": 0,
"write": 1
+ },
+ {
+ "amend": 0,
+ "cancel": 0,
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "if_owner": 0,
+ "import": 0,
+ "permlevel": 0,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "Item Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
}
],
"quick_entry": 1,
diff --git a/erpnext/patches/v10_0/remove_and_copy_fields_in_physician.py b/erpnext/patches/v10_0/remove_and_copy_fields_in_physician.py
index f632c94..0739671 100644
--- a/erpnext/patches/v10_0/remove_and_copy_fields_in_physician.py
+++ b/erpnext/patches/v10_0/remove_and_copy_fields_in_physician.py
@@ -5,7 +5,7 @@
frappe.reload_doc("healthcare", "doctype", "physician")
frappe.reload_doc("healthcare", "doctype", "physician_service_unit_schedule")
- if frappe.db.has_column('Physician', 'physician_schedule'):
+ if frappe.db.has_column('Physician', 'physician_schedules'):
for doc in frappe.get_all('Physician'):
_doc = frappe.get_doc('Physician', doc.name)
if _doc.physician_schedule:
diff --git a/erpnext/patches/v11_0/make_job_card.py b/erpnext/patches/v11_0/make_job_card.py
index 4604889..9c41c0b 100644
--- a/erpnext/patches/v11_0/make_job_card.py
+++ b/erpnext/patches/v11_0/make_job_card.py
@@ -11,10 +11,16 @@
frappe.reload_doc('manufacturing', 'doctype', 'job_card')
frappe.reload_doc('manufacturing', 'doctype', 'job_card_item')
- for d in frappe.db.sql("""select work_order, name from tabTimesheet
- where (work_order is not null and work_order != '') and docstatus = 0""", as_dict=1):
- if d.work_order:
- doc = frappe.get_doc('Work Order', d.work_order)
+ fieldname = frappe.db.get_value('DocField', {'fieldname': 'work_order', 'parent': 'Timesheet'}, 'fieldname')
+ if not fieldname:
+ fieldname = frappe.db.get_value('DocField', {'fieldname': 'production_order', 'parent': 'Timesheet'}, 'fieldname')
+ if not fieldname: return
+
+ for d in frappe.get_all('Timesheet',
+ filters={fieldname: ['!=', ""], 'docstatus': 0},
+ fields=[fieldname, 'name']):
+ if d[fieldname]:
+ doc = frappe.get_doc('Work Order', d[fieldname])
for row in doc.operations:
create_job_card(doc, row, auto_create=True)
- frappe.delete_doc('Timesheet', d.name)
\ No newline at end of file
+ frappe.delete_doc('Timesheet', d.name)
diff --git a/erpnext/public/js/hub/components/DetailView.vue b/erpnext/public/js/hub/components/DetailView.vue
index 2f1a941..cc09982 100644
--- a/erpnext/public/js/hub/components/DetailView.vue
+++ b/erpnext/public/js/hub/components/DetailView.vue
@@ -28,7 +28,7 @@
<div class="row margin-bottom">
<div class="col-md-3">
<div class="hub-item-image">
- <img v-img-src="image">
+ <base-image :src="image" :alt="title" />
</div>
</div>
<div class="col-md-8">
diff --git a/erpnext/public/js/hub/components/Image.vue b/erpnext/public/js/hub/components/Image.vue
new file mode 100644
index 0000000..9acf421
--- /dev/null
+++ b/erpnext/public/js/hub/components/Image.vue
@@ -0,0 +1,40 @@
+<template>
+ <div class="hub-image">
+ <img :src="src" :alt="alt" v-show="!is_loading && !is_broken"/>
+ <div class="hub-image-loading" v-if="is_loading">
+ <span class="octicon octicon-cloud-download"></span>
+ </div>
+ <div class="hub-image-broken" v-if="is_broken">
+ <span class="octicon octicon-file-media"></span>
+ </div>
+ </div>
+</template>
+<script>
+export default {
+ name: 'Image',
+ props: ['src', 'alt'],
+ data() {
+ return {
+ is_loading: true,
+ is_broken: false
+ }
+ },
+ created() {
+ this.handle_image();
+ },
+ methods: {
+ handle_image() {
+ let img = new Image();
+ img.src = this.src;
+
+ img.onload = () => {
+ this.is_loading = false;
+ };
+ img.onerror = () => {
+ this.is_loading = false;
+ this.is_broken = true;
+ };
+ }
+ }
+};
+</script>
diff --git a/erpnext/public/js/hub/components/ItemCard.vue b/erpnext/public/js/hub/components/ItemCard.vue
index f34fddc..675ad86 100644
--- a/erpnext/public/js/hub/components/ItemCard.vue
+++ b/erpnext/public/js/hub/components/ItemCard.vue
@@ -15,7 +15,7 @@
</i>
</div>
<div class="hub-card-body">
- <img class="hub-card-image" v-img-src="item.image"/>
+ <base-image class="hub-card-image" :src="item.image" :alt="title" />
<div class="hub-card-overlay">
<div v-if="is_local" class="hub-card-overlay-body">
<div class="hub-card-overlay-button">
diff --git a/erpnext/public/js/hub/components/ItemListCard.vue b/erpnext/public/js/hub/components/ItemListCard.vue
index 70cb566..7f6fb77 100644
--- a/erpnext/public/js/hub/components/ItemListCard.vue
+++ b/erpnext/public/js/hub/components/ItemListCard.vue
@@ -1,7 +1,7 @@
<template>
<div class="hub-list-item" :data-route="item.route">
<div class="hub-list-left">
- <img class="hub-list-image" v-img-src="item.image">
+ <base-image class="hub-list-image" :src="item.image" />
<div class="hub-list-body ellipsis">
<div class="hub-list-title">{{item.item_name}}</div>
<div class="hub-list-subtitle ellipsis">
diff --git a/erpnext/public/js/hub/vue-plugins.js b/erpnext/public/js/hub/vue-plugins.js
index 439c1f2..6e6a7cb 100644
--- a/erpnext/public/js/hub/vue-plugins.js
+++ b/erpnext/public/js/hub/vue-plugins.js
@@ -7,6 +7,7 @@
import DetailView from './components/DetailView.vue';
import DetailHeaderItem from './components/DetailHeaderItem.vue';
import EmptyState from './components/EmptyState.vue';
+import Image from './components/Image.vue';
Vue.prototype.__ = window.__;
Vue.prototype.frappe = window.frappe;
@@ -17,6 +18,7 @@
Vue.component('detail-view', DetailView);
Vue.component('detail-header-item', DetailHeaderItem);
Vue.component('empty-state', EmptyState);
+Vue.component('base-image', Image);
Vue.directive('route', {
bind(el, binding) {
@@ -51,16 +53,6 @@
img.src = src;
}
-Vue.directive('img-src', {
- bind(el, binding) {
- handleImage(el, binding.value);
- },
- update(el, binding) {
- if (binding.value === binding.oldValue) return;
- handleImage(el, binding.value);
- }
-});
-
Vue.filter('striphtml', function (text) {
return strip_html(text || '');
});
\ No newline at end of file
diff --git a/erpnext/public/less/hub.less b/erpnext/public/less/hub.less
index d40926b..089915d 100644
--- a/erpnext/public/less/hub.less
+++ b/erpnext/public/less/hub.less
@@ -1,4 +1,5 @@
-@import "../../../../frappe/frappe/public/less/variables.less";
+@import "variables.less";
+@import (reference) "desk.less";
body[data-route^="marketplace/"] {
.layout-side-section {
@@ -26,6 +27,22 @@
font-size: @text-medium;
}
+ .hub-image {
+ height: 200px;
+ }
+
+ .hub-image-loading, .hub-image-broken {
+ .img-background();
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ span {
+ font-size: 32px;
+ color: @text-extra-muted;
+ }
+ }
+
.progress-bar {
background-color: #89da28;
}
@@ -136,6 +153,7 @@
}
.hub-item-image {
+ position: relative;
border: 1px solid @border-color;
border-radius: 4px;
overflow: hidden;