Merge branch 'develop' into develop
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..c145291
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,47 @@
+---
+name: Bug report
+about: Report a bug encountered while using ERPNext
+labels: bug
+---
+
+<!--
+Welcome to ERPNext issue tracker! Before creating an issue, please heed the following:
+
+1. This tracker should only be used to report bugs and request features / enhancements to ERPNext
+ - For questions and general support, checkout the manual https://erpnext.com/docs/user/manual/en or use https://discuss.erpnext.com
+ - For documentation issues, refer to https://github.com/frappe/erpnext_com
+2. Use the search function before creating a new issue. Duplicates will be closed and directed to
+ the original discussion.
+3. When making a bug report, make sure you provide all required information. The easier it is for
+ maintainers to reproduce, the faster it'll be fixed.
+4. If you think you know what the reason for the bug is, share it with us. Maybe put in a PR 😉
+-->
+
+## Description of the issue
+
+## Context information (for bug reports)
+
+**Output of `bench version`**
+```
+(paste here)
+```
+
+## Steps to reproduce the issue
+
+1.
+2.
+3.
+
+### Observed result
+
+### Expected result
+
+### Stacktrace / full error message
+
+```
+(paste here)
+```
+
+## Additional information
+
+OS version / distribution, `ERPNext` install method, etc.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..6cdad35
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,28 @@
+---
+name: Feature request
+about: Suggest an idea to improve ERPNext
+labels: feature-request
+---
+
+<!--
+Welcome to ERPNext issue tracker! Before creating an issue, please heed the following:
+
+1. This tracker should only be used to report bugs and request features / enhancements to ERPNext
+ - For questions and general support, checkout the manual https://erpnext.com/docs/user/manual/en or use https://discuss.erpnext.com
+ - For documentation issues, refer to https://github.com/frappe/erpnext_com
+2. Use the search function before creating a new issue. Duplicates will be closed and directed to
+ the original discussion.
+3. When making a feature request, make sure to be as verbose as possible. The better you convey your message, the greater the drive to make it happen.
+-->
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.github/ISSUE_TEMPLATE/question-about-using-erpnext.md b/.github/ISSUE_TEMPLATE/question-about-using-erpnext.md
new file mode 100644
index 0000000..455c20e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/question-about-using-erpnext.md
@@ -0,0 +1,17 @@
+---
+name: Question about using ERPNext
+about: This is not the appropriate channel
+labels: invalid
+---
+
+Please post on our forums:
+
+for questions about using `ERPNext`: https://discuss.erpnext.com
+
+for questions about using the `Frappe Framework`: https://discuss.frappe.io
+
+for questions about using `bench`, probably the best place to start is the [bench repo](https://github.com/frappe/bench)
+
+For documentation issues, use the [ERPNext Documentation](https://erpnext.com/docs/) or [Frappe Framework Documentation](https://frappe.io/docs/user/en) or the [developer cheetsheet](https://github.com/frappe/frappe/wiki/Developer-Cheatsheet)
+
+> **Posts that are not bug reports or feature requests will not be addressed on this issue tracker.**
\ No newline at end of file
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index c0e186d..091cf47 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,2 +1,33 @@
-Please read the pull request checklist to make sure your changes are merged: https://github.com/frappe/erpnext/wiki/Pull-Request-Checklist
+<!--
+Some key notes before you open a PR:
+
+ 1. Select which branch should this PR be merged in?
+ 2. PR name follows [convention](http://karma-runner.github.io/4.0/dev/git-commit-msg.html)
+ 3. All tests pass locally, UI and Unit tests
+ 4. All business logic and validations must be on the server-side
+ 5. Update necessary Documentation
+ 6. Put `closes #XXXX` in your comment to auto-close the issue that your PR fixes
+
+
+Also, if you're new here
+
+- Documentation Guidelines => https://github.com/frappe/erpnext/wiki/Updating-Documentation
+
+- Contribution Guide => https://github.com/frappe/erpnext/blob/develop/.github/CONTRIBUTING.md
+
+- Pull Request Checklist => https://github.com/frappe/erpnext/wiki/Pull-Request-Checklist
+
+-->
+
+> Please provide enough information so that others can review your pull request:
+
+<!-- You can skip this if you're fixing a typo or updating existing documentation -->
+
+> Explain the **details** for making this change. What existing problem does the pull request solve?
+
+<!-- Example: When "Adding a function to do X", explain why it is necessary to have a way to do X. -->
+
+> Screenshots/GIFs
+
+<!-- Add images/recordings to better visualize the change: expected/current behviour -->
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..46ed437
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,7 @@
+# Security Policy
+
+The ERPNext team and community take security issues seriously. To report a security issue, fill out the form at [https://erpnext.com/security/report](https://erpnext.com/security/report).
+
+You can help us make ERPNext and all it's users more secure by following the [Reporting guidelines](https://erpnext.com/security).
+
+We appreciate your efforts to responsibly disclose your findings. We'll endeavor to respond quickly, and will keep you updated throughout the process.
\ No newline at end of file
diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.json b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.json
index ae2aa54..b40243c 100644
--- a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.json
+++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.json
@@ -1,13 +1,13 @@
{
"add_total_row": 0,
"creation": "2019-09-23 16:35:02.836134",
- "disable_prepared_report": 0,
+ "disable_prepared_report": 1,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
- "modified": "2019-09-23 16:35:02.836134",
+ "modified": "2019-10-22 13:00:31.539726",
"modified_by": "Administrator",
"module": "Assets",
"name": "Fixed Asset Register",
diff --git a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py
index 2c9e48a..f395499 100644
--- a/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py
+++ b/erpnext/assets/report/fixed_asset_register/fixed_asset_register.py
@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe import _
+from frappe.utils import cstr
def execute(filters=None):
filters = frappe._dict(filters or {})
@@ -149,12 +150,12 @@
FROM `tabAsset Finance Book`
WHERE
parentfield='finance_books'
- AND finance_book=%s''', (finance_book)))
+ AND ifnull(finance_book, '')=%s''', cstr(finance_book)))
def get_purchase_receipt_supplier_map():
return frappe._dict(frappe.db.sql(''' Select
pr.name, pr.supplier
- FROM `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pri
+ FROM `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pri
WHERE
pri.parent = pr.name
AND pri.is_fixed_asset=1
@@ -164,7 +165,7 @@
def get_purchase_invoice_supplier_map():
return frappe._dict(frappe.db.sql(''' Select
pi.name, pi.supplier
- FROM `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pii
+ FROM `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pii
WHERE
pii.parent = pi.name
AND pii.is_fixed_asset=1
diff --git a/erpnext/erpnext_integrations/connectors/shopify_connection.py b/erpnext/erpnext_integrations/connectors/shopify_connection.py
index bd98037..3be08a2 100644
--- a/erpnext/erpnext_integrations/connectors/shopify_connection.py
+++ b/erpnext/erpnext_integrations/connectors/shopify_connection.py
@@ -29,7 +29,8 @@
validate_item(order, shopify_settings)
create_order(order, shopify_settings)
except Exception as e:
- make_shopify_log(status="Error", message=e.message, exception=False)
+ make_shopify_log(status="Error", exception=e)
+
else:
make_shopify_log(status="Success")
@@ -42,9 +43,9 @@
sales_order = get_sales_order(cstr(order['id']))
if sales_order:
create_sales_invoice(order, shopify_settings, sales_order)
- make_shopify_log(status="Success")
- except Exception:
- make_shopify_log(status="Error", exception=True)
+ make_shopify_log(status="Success")
+ except Exception as e:
+ make_shopify_log(status="Error", exception=e, rollback=True)
def prepare_delivery_note(order, request_id=None):
frappe.set_user('Administrator')
@@ -56,8 +57,8 @@
if sales_order:
create_delivery_note(order, shopify_settings, sales_order)
make_shopify_log(status="Success")
- except Exception:
- make_shopify_log(status="Error", exception=True)
+ except Exception as e:
+ make_shopify_log(status="Error", exception=e, rollback=True)
def get_sales_order(shopify_order_id):
sales_order = frappe.db.get_value("Sales Order", filters={"shopify_order_id": shopify_order_id})
@@ -97,7 +98,7 @@
message = 'Following items are exists in order but relevant record not found in Product master'
message += "\n" + ", ".join(product_not_exists)
- make_shopify_log(status="Error", message=message, exception=True)
+ make_shopify_log(status="Error", exception=e, rollback=True)
return ''
diff --git a/erpnext/erpnext_integrations/doctype/shopify_log/shopify_log.py b/erpnext/erpnext_integrations/doctype/shopify_log/shopify_log.py
index 0c821e0..7d3f572 100644
--- a/erpnext/erpnext_integrations/doctype/shopify_log/shopify_log.py
+++ b/erpnext/erpnext_integrations/doctype/shopify_log/shopify_log.py
@@ -12,23 +12,38 @@
pass
-def make_shopify_log(status="Queued", message=None, exception=False):
+def make_shopify_log(status="Queued", exception=None, rollback=False):
# if name not provided by log calling method then fetch existing queued state log
+ make_new = False
+
if not frappe.flags.request_id:
- return
+ make_new = True
- log = frappe.get_doc("Shopify Log", frappe.flags.request_id)
-
- if exception:
+ if rollback:
frappe.db.rollback()
- log = frappe.get_doc({"doctype":"Shopify Log"}).insert(ignore_permissions=True)
- log.message = message if message else ''
+ if make_new:
+ log = frappe.get_doc({"doctype":"Shopify Log"}).insert(ignore_permissions=True)
+ else:
+ log = log = frappe.get_doc("Shopify Log", frappe.flags.request_id)
+
+ log.message = get_message(exception)
log.traceback = frappe.get_traceback()
log.status = status
log.save(ignore_permissions=True)
frappe.db.commit()
+def get_message(exception):
+ message = None
+
+ if hasattr(exception, 'message'):
+ message = exception.message
+ elif hasattr(exception, '__str__'):
+ message = e.__str__()
+ else:
+ message = "Something went wrong while syncing"
+ return message
+
def dump_request_data(data, event="create/order"):
event_mapper = {
"orders/create": get_webhook_address(connector_name='shopify_connection', method="sync_sales_order", exclude_uri=True),
@@ -43,11 +58,11 @@
}).insert(ignore_permissions=True)
frappe.db.commit()
- frappe.enqueue(method=event_mapper[event], queue='short', timeout=300, is_async=True,
+ frappe.enqueue(method=event_mapper[event], queue='short', timeout=300, is_async=True,
**{"order": data, "request_id": log.name})
@frappe.whitelist()
def resync(method, name, request_data):
frappe.db.set_value("Shopify Log", name, "status", "Queued", update_modified=False)
- frappe.enqueue(method=method, queue='short', timeout=300, is_async=True,
+ frappe.enqueue(method=method, queue='short', timeout=300, is_async=True,
**{"order": json.loads(request_data), "request_id": name})
diff --git a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py
index e2f6d49..a4332b1 100644
--- a/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py
+++ b/erpnext/erpnext_integrations/doctype/shopify_settings/shopify_settings.py
@@ -30,13 +30,9 @@
# url = get_shopify_url('admin/webhooks.json', self)
created_webhooks = [d.method for d in self.webhooks]
url = get_shopify_url('admin/api/2019-04/webhooks.json', self)
- print('url', url)
for method in webhooks:
- print('method', method)
session = get_request_session()
- print('session', session)
try:
- print(get_header(self))
d = session.post(url, data=json.dumps({
"webhook": {
"topic": method,
@@ -44,7 +40,6 @@
"format": "json"
}
}), headers=get_header(self))
- print('d', d.json())
d.raise_for_status()
self.update_webhook_table(method, d.json())
except Exception as e:
@@ -67,7 +62,6 @@
self.remove(d)
def update_webhook_table(self, method, res):
- print('update')
self.append("webhooks", {
"webhook_id": res['webhook']['id'],
"method": method
@@ -75,7 +69,6 @@
def get_shopify_url(path, settings):
if settings.app_type == "Private":
- print(settings.api_key, settings.get_password('password'), settings.shopify_url, path)
return 'https://{}:{}@{}/{}'.format(settings.api_key, settings.get_password('password'), settings.shopify_url, path)
else:
return 'https://{}/{}'.format(settings.shopify_url, path)
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index eb01b8c..225ae29 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -35,7 +35,8 @@
# name can be BOM/ITEM/001, BOM/ITEM/001-1, BOM-ITEM-001, BOM-ITEM-001-1
# split by item
- names = [name.split(self.item)[-1][1:] for name in names]
+ names = [name.split(self.item, 1) for name in names]
+ names = [d[-1][1:] for d in filter(lambda x: len(x) > 1 and x[-1], names)]
# split by (-) if cancelled
names = [cint(name.split('-')[-1]) for name in names]
diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json
index 78e7b4a..ccc48e1 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.json
+++ b/erpnext/selling/doctype/sales_order/sales_order.json
@@ -682,10 +682,10 @@
"label": "Additional Discount and Coupon Code"
},
{
- "fieldname": "coupon_code",
- "fieldtype": "Link",
- "label": "Coupon Code",
- "options": "Coupon Code"
+ "fieldname": "coupon_code",
+ "fieldtype": "Link",
+ "label": "Coupon Code",
+ "options": "Coupon Code"
},
{
"default": "Grand Total",
@@ -1185,6 +1185,7 @@
"default": "0",
"fieldname": "skip_delivery_note",
"fieldtype": "Check",
+ "hidden": 1,
"label": "Skip Delivery Note",
"print_hide": 1
}
@@ -1192,7 +1193,7 @@
"icon": "fa fa-file-text",
"idx": 105,
"is_submittable": 1,
- "modified": "2019-10-14 08:46:07.540565",
+ "modified": "2019-10-22 14:26:42.767189",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order",
@@ -1269,4 +1270,4 @@
"title_field": "title",
"track_changes": 1,
"track_seen": 1
-}
+}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 758fb37..7fa7d3b 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -329,8 +329,8 @@
if total_completed_qty > flt(completed_qty):
job_card = frappe.db.get_value('Job Card', {'operation_id': d.name}, 'name')
if not job_card:
- frappe.throw(_("Work Order {0}: job card not found for the operation {1}")
- .format(self.work_order, job_card))
+ frappe.throw(_("Work Order {0}: Job Card not found for the operation {1}")
+ .format(self.work_order, d.operation))
work_order_link = frappe.utils.get_link_to_form('Work Order', self.work_order)
job_card_link = frappe.utils.get_link_to_form('Job Card', job_card)
diff --git a/erpnext/stock/report/total_stock_summary/total_stock_summary.py b/erpnext/stock/report/total_stock_summary/total_stock_summary.py
index 41e2f86..ed52393 100644
--- a/erpnext/stock/report/total_stock_summary/total_stock_summary.py
+++ b/erpnext/stock/report/total_stock_summary/total_stock_summary.py
@@ -30,7 +30,7 @@
if filters.get("group_by") == "Warehouse":
if filters.get("company"):
- conditions += " AND warehouse.company = '%s'" % frappe.db.escape(filters.get("company"), percent=False)
+ conditions += " AND warehouse.company = %s" % frappe.db.escape(filters.get("company"), percent=False)
conditions += " GROUP BY ledger.warehouse, item.item_code"
columns += "'' as company, ledger.warehouse"