Merge pull request #3708 from neilLasrado/material-request
Fetch items from Packing List if Exists in Sales Order while raising …
diff --git a/erpnext/accounts/report/accounts_payable/accounts_payable.json b/erpnext/accounts/report/accounts_payable/accounts_payable.json
index 71537a8..9be8d68 100644
--- a/erpnext/accounts/report/accounts_payable/accounts_payable.json
+++ b/erpnext/accounts/report/accounts_payable/accounts_payable.json
@@ -6,12 +6,12 @@
"doctype": "Report",
"idx": 1,
"is_standard": "Yes",
- "modified": "2014-06-03 07:18:10.985354",
+ "modified": "2015-07-23 01:08:20.996267",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Payable",
"owner": "Administrator",
"ref_doctype": "Purchase Invoice",
"report_name": "Accounts Payable",
- "report_type": "Report Builder"
+ "report_type": "Query Report"
}
\ No newline at end of file
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index a87c8f0..91ba19a 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -1,11 +1,34 @@
from __future__ import unicode_literals
app_name = "erpnext"
app_title = "ERPNext"
-app_publisher = "Frappe Technologies Pvt. Ltd. and Contributors"
-app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
+app_publisher = "Frappe Technologies Pvt. Ltd."
+app_description = """## ERPNext
+
+ERPNext is a fully featured ERP system designed for Small and Medium Sized
+business. ERPNext covers a wide range of features including Accounting, CRM,
+Inventory management, Selling, Purchasing, Manufacturing, Projects, HR &
+Payroll, Website, E-Commerce and much more.
+
+ERPNext is based on the Frappe Framework is highly customizable and extendable.
+You can create Custom Form, Fields, Scripts and can also create your own Apps
+to extend ERPNext functionality.
+
+ERPNext is Open Source under the GNU General Public Licence v3 and has been
+listed as one of the Best Open Source Softwares in the world by my online
+blogs.
+
+### Links
+
+- Website: [https://erpnext.com](https://erpnext.com)
+- GitHub: [https://github.com/frappe/erpnext](https://github.com/frappe/erpnext)
+- Forum: [https://discuss.erpnext.com](https://discuss.erpnext.com)
+- Frappe Framework: [https://frappe.io](https://frappe.io)
+
+"""
app_icon = "icon-th"
app_color = "#e74c3c"
app_version = "5.2.1"
+github_link = "https://github.com/frappe/erpnext"
error_report_email = "support@erpnext.com"
diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js
index 58b1adb..3bd5657 100644
--- a/erpnext/stock/doctype/item/item.js
+++ b/erpnext/stock/doctype/item/item.js
@@ -86,8 +86,12 @@
},
manage_variants: function(frm) {
- frappe.route_options = {"item_code": frm.doc.name };
- frappe.set_route("List", "Manage Variants");
+ if (cur_frm.doc.__unsaved==1) {
+ frappe.throw(__("You have unsaved changes. Please save."))
+ } else {
+ frappe.route_options = {"item_code": frm.doc.name };
+ frappe.set_route("List", "Manage Variants");
+ }
}
});
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index a2e0ade..d3d8e9c 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -325,7 +325,8 @@
for d in variants:
update_variant(self.name, d)
updated.append(d.item_code)
- frappe.msgprint(_("Item Variants {0} updated").format(", ".join(updated)))
+ if updated:
+ frappe.msgprint(_("Item Variants {0} updated").format(", ".join(updated)))
def validate_has_variants(self):
if not self.has_variants and frappe.db.get_value("Item", self.name, "has_variants"):
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
index 413f820..efa6a8a 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
@@ -11,6 +11,7 @@
from erpnext.stock.utils import get_stock_balance
class OpeningEntryAccountError(frappe.ValidationError): pass
+class EmptyStockReconciliationItemsError(frappe.ValidationError): pass
class StockReconciliation(StockController):
def __init__(self, arg1, arg2=None):
@@ -51,7 +52,11 @@
items = filter(lambda d: _changed(d), self.items)
- if len(items) != len(self.items):
+ if not items:
+ frappe.throw(_("None of the items have any change in quantity or value."),
+ EmptyStockReconciliationItemsError)
+
+ elif len(items) != len(self.items):
self.items = items
for i, item in enumerate(self.items):
item.idx = i + 1
diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.py b/erpnext/stock/report/stock_ledger/stock_ledger.py
index 0651ae8..c2c6d1a 100644
--- a/erpnext/stock/report/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/report/stock_ledger/stock_ledger.py
@@ -9,8 +9,13 @@
columns = get_columns()
sl_entries = get_stock_ledger_entries(filters)
item_details = get_item_details(filters)
-
+ opening_row = get_opening_balance(filters, columns)
+
data = []
+
+ if opening_row:
+ data.append(opening_row)
+
for sle in sl_entries:
item_detail = item_details[sle.item_code]
@@ -20,7 +25,7 @@
(sle.incoming_rate if sle.actual_qty > 0 else 0.0),
sle.valuation_rate, sle.stock_value, sle.voucher_type, sle.voucher_no,
sle.batch_no, sle.serial_no, sle.company])
-
+
return columns, data
def get_columns():
@@ -40,7 +45,7 @@
where company = %(company)s and
posting_date between %(from_date)s and %(to_date)s
{sle_conditions}
- order by posting_date desc, posting_time desc, name desc"""\
+ order by posting_date asc, posting_time asc, name asc"""\
.format(sle_conditions=get_sle_conditions(filters)), filters, as_dict=1)
def get_item_details(filters):
@@ -73,3 +78,22 @@
conditions.append("voucher_no=%(voucher_no)s")
return "and {}".format(" and ".join(conditions)) if conditions else ""
+
+def get_opening_balance(filters, columns):
+ if not (filters.item_code and filters.warehouse and filters.from_date):
+ return
+
+ from erpnext.stock.stock_ledger import get_previous_sle
+ last_entry = get_previous_sle({
+ "item_code": filters.item_code,
+ "warehouse": filters.warehouse,
+ "posting_date": filters.from_date,
+ "posting_time": "00:00:00"
+ })
+
+ row = [""]*len(columns)
+ row[1] = _("'Opening'")
+ for i, v in ((9, 'qty_after_transaction'), (11, 'valuation_rate'), (12, 'stock_value')):
+ row[i] = last_entry.get(v, 0)
+
+ return row
\ No newline at end of file
diff --git a/erpnext/templates/includes/macros.html b/erpnext/templates/includes/macros.html
index 0967e97..6748a5e 100644
--- a/erpnext/templates/includes/macros.html
+++ b/erpnext/templates/includes/macros.html
@@ -1,6 +1,6 @@
{% macro product_image_square(website_image, css_class="") %}
<div class="product-image product-image-square {% if not website_image -%} missing-image {%- endif %} {{ css_class }}"
- {% if website_image -%} style="background-image: url('{{ frappe.utils.quoted(website_image) }}');" {%- endif %}>
+ {% if website_image -%} style="background-image: url('{{ frappe.utils.quoted(website_image) | abs_url }}');" {%- endif %}>
{% if not website_image -%}<i class="centered octicon octicon-device-camera"></i>{%- endif %}
</div>
{% endmacro %}
@@ -8,7 +8,7 @@
{% macro product_image(website_image, css_class="") %}
<div class="product-image {% if not website_image -%} missing-image {%- endif %} {{ css_class }}">
{% if website_image -%}
- <img src="{{ frappe.utils.quoted(website_image) }}" class="img-responsive">
+ <img src="{{ frappe.utils.quoted(website_image) | abs_url }}" class="img-responsive">
{%- else -%}
<i class="centered octicon octicon-device-camera"></i>
{%- endif %}