diff --git a/README.md b/README.md index b9d5a6e5f77..efa3e330692 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,31 @@ -# ERPNext - Open Source ERP for small, medium sized businesses [![Build Status](https://travis-ci.org/frappe/erpnext.png)](https://travis-ci.org/frappe/erpnext) +# ERPNext - Open source ERP for small and medium-size business [![Build Status](https://travis-ci.org/frappe/erpnext.png)](https://travis-ci.org/frappe/erpnext) [https://erpnext.com](https://erpnext.com) -Includes Accounting, Inventory, CRM, Sales, Purchase, Projects, HRMS. Built on Python / MariaDB. +Includes: Accounting, Inventory, CRM, Sales, Purchase, Projects, HRMS. Requires MariaDB. -ERPNext is built on [frappe](https://github.com/frappe/frappe) Python Framework. +ERPNext is built on the [Frappe](https://github.com/frappe/frappe) Framework, a full-stack web app framework in Python & Javascript. -- [User Guide](http://erpnext.org/user-guide.html) +- [User Guide](https://erpnext.com/user-guide) - [Getting Help](http://erpnext.org/getting-help.html) -- [Developer Forum](http://groups.google.com/group/erpnext-developer-forum) -- [User Forum](http://groups.google.com/group/erpnext-user-forum) +- [Discussion Forum](https://discuss.frappe.io/) --- -### Install +### Full Install -Use the bench, https://github.com/frappe/bench +The Easy Way install script for bench will install all dependencies (e.g. MariaDB). See https://github.com/frappe/bench -### Admin Login +New passwords will be created for the ERPNext "Administrator" user, the MariaDB root user, and the frappe user (the script displays the passwords and saves them to ~/frappe_passwords.txt). -1. go to "/login" -1. Administrator user name: "Administrator" -1. Administrator password: "admin" +### Virtual Image -### Download and Install - -##### Virtual Image: +You can download a virtual image to run ERPNext in a virtual machine on your local system. - [ERPNext Download](http://erpnext.com/download) +System and user credentials are listed on the download page. + --- ## License diff --git a/erpnext/__version__.py b/erpnext/__version__.py index ebfb9bf6b49..1eef0c42ba9 100644 --- a/erpnext/__version__.py +++ b/erpnext/__version__.py @@ -1 +1 @@ -__version__ = '4.16.0' +__version__ = '4.17.0' 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 ce61fa1fc8c..5b4d2f891de 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 @@ -3,9 +3,9 @@ "doc_type": "Journal Voucher", "docstatus": 0, "doctype": "Print Format", - "html": "
\n\n\t{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n
\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
\n
\n
{{ value }}
\n
\n{%- endfor -%}\n\t
\n\t

{{ _(\"This amount is in full / part settlement of the listed bills\") }}:

\n{%- for label, value in (\n (_(\"Amount\"), \"\" + (doc.total_amount or \"\") + \"
\" + (doc.total_amount_in_words or \"\") + \"
\"),\n (_(\"References\"), doc.remark)\n ) -%}\n
\n
\n
{{ value }}
\n
\n {%- endfor -%}\n
\n\t
\n\t\tPrepared By
\n\t
\n\t\tAuthorised Signatory
\n\t
\n\t\tReceived Payment as Above
\n\t
\n\t\t_____________
\n\t
\n\t\tA/C Payee
\n\t
\n\t\t_____________
\n\t
\n\t\t{{ frappe.utils.formatdate(doc.cheque_date) }}
\n\t
\n\t\t{{ doc.pay_to_recd_from }}
\n\t
\n\t\t{{ doc.total_amount_in_words }}
\n\t
\n\t\t{{ doc.total_amount }}
\n
", + "html": "
\n\n\t{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n
\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
\n
\n
{{ value }}
\n
\n{%- endfor -%}\n\t
\n\t

{{ _(\"This amount is in full / part settlement of the listed bills\") }}:

\n{%- for label, value in (\n (_(\"Amount\"), \"\" + (doc.total_amount or \"\") + \"
\" + (doc.total_amount_in_words or \"\") + \"
\"),\n (_(\"References\"), doc.remark)\n ) -%}\n
\n
\n
{{ value }}
\n
\n {%- endfor -%}\n
\n\t
\n\t\tPrepared By
\n\t
\n\t\tAuthorised Signatory
\n\t
\n\t\tReceived Payment as Above
\n\t
\n\t\t_____________
\n\t
\n\t\tA/C Payee
\n\t
\n\t\t_____________
\n\t
\n\t\t{{ frappe.utils.formatdate(doc.cheque_date) }}
\n\t
\n\t\t{{ doc.pay_to_recd_from }}
\n\t
\n\t\t{{ doc.total_amount_in_words }}
\n\t
\n\t\t{{ doc.total_amount }}
\n
", "idx": 1, - "modified": "2014-09-09 03:27:13.708596", + "modified": "2015-01-12 11:03:17.032512", "modified_by": "Administrator", "module": "Accounts", "name": "Cheque Printing Format", diff --git a/erpnext/accounts/print_format/credit_note/credit_note.json b/erpnext/accounts/print_format/credit_note/credit_note.json index ac0de75037f..e6c9e8f7110 100644 --- a/erpnext/accounts/print_format/credit_note/credit_note.json +++ b/erpnext/accounts/print_format/credit_note/credit_note.json @@ -4,9 +4,9 @@ "doc_type": "Journal Voucher", "docstatus": 0, "doctype": "Print Format", - "html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n\n
\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Credit Note\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n {%- for label, value in (\n (_(\"Credit To\"), doc.pay_to_recd_from),\n (_(\"Date\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Amount\"), \"\" + frappe.utils.cstr(doc.total_amount) + \"
\" + (doc.total_amount_in_words or \"\") + \"
\"),\n (_(\"Remarks\"), doc.remark)\n ) -%}\n\n
\n
\n
{{ value }}
\n
\n\n {%- endfor -%}\n\n
\n
\n

\n {{ _(\"For\") }} {{ doc.company }},
\n
\n
\n
\n {{ _(\"Authorized Signatory\") }}\n

\n
\n\n\n", + "html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n\n
\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Credit Note\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n {%- for label, value in (\n (_(\"Credit To\"), doc.pay_to_recd_from),\n (_(\"Date\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Amount\"), \"\" + frappe.utils.cstr(doc.total_amount) + \"
\" + (doc.total_amount_in_words or \"\") + \"
\"),\n (_(\"Remarks\"), doc.remark)\n ) -%}\n\n
\n
\n
{{ value }}
\n
\n\n {%- endfor -%}\n\n
\n
\n

\n {{ _(\"For\") }} {{ doc.company }},
\n
\n
\n
\n {{ _(\"Authorized Signatory\") }}\n

\n
\n\n\n", "idx": 2, - "modified": "2014-10-17 17:20:02.740340", + "modified": "2015-01-12 11:02:25.716825", "modified_by": "Administrator", "module": "Accounts", "name": "Credit Note", diff --git a/erpnext/accounts/print_format/payment_receipt_voucher/payment_receipt_voucher.json b/erpnext/accounts/print_format/payment_receipt_voucher/payment_receipt_voucher.json index 5c0a72a8def..04fe7467800 100755 --- a/erpnext/accounts/print_format/payment_receipt_voucher/payment_receipt_voucher.json +++ b/erpnext/accounts/print_format/payment_receipt_voucher/payment_receipt_voucher.json @@ -3,9 +3,9 @@ "doc_type": "Journal Voucher", "docstatus": 0, "doctype": "Print Format", - "html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n
\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Payment Receipt Note\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n {%- for label, value in (\n (_(\"Received On\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Received From\"), doc.pay_to_recd_from),\n (_(\"Amount\"), \"\" + doc.total_amount or 0 + \"
\" + (doc.total_amount_in_words or \"\") + \"
\"),\n (_(\"Remarks\"), doc.remark)\n ) -%}\n
\n
\n
{{ value }}
\n
\n\n {%- endfor -%}\n\n
\n
\n

\n {{ _(\"For\") }} {{ doc.company }},
\n
\n
\n
\n {{ _(\"Authorized Signatory\") }}\n

\n
\n\n", + "html": "{%- from \"templates/print_formats/standard_macros.html\" import add_header -%}\n
\n {%- if not doc.get(\"print_heading\") and not doc.get(\"select_print_heading\") \n and doc.set(\"select_print_heading\", _(\"Payment Receipt Note\")) -%}{%- endif -%}\n {{ add_header(0, 1, doc, letter_head, no_letterhead) }}\n\n {%- for label, value in (\n (_(\"Received On\"), frappe.utils.formatdate(doc.voucher_date)),\n (_(\"Received From\"), doc.pay_to_recd_from),\n (_(\"Amount\"), \"\" + doc.total_amount or 0 + \"
\" + (doc.total_amount_in_words or \"\") + \"
\"),\n (_(\"Remarks\"), doc.remark)\n ) -%}\n
\n
\n
{{ value }}
\n
\n\n {%- endfor -%}\n\n
\n
\n

\n {{ _(\"For\") }} {{ doc.company }},
\n
\n
\n
\n {{ _(\"Authorized Signatory\") }}\n

\n
\n\n", "idx": 1, - "modified": "2014-11-04 11:25:57.560873", + "modified": "2015-01-12 11:03:22.893209", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Receipt Voucher", diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index a2ed86da15f..a546799a5d7 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -149,7 +149,7 @@ class AccountsReceivableReport(object): if not account_map: frappe.throw(_("No Customer Accounts found.")) else: - accounts_list = ['"{0}"'.format(ac.replace('"', '\"')) for ac in account_map] + accounts_list = ["'{0}'".format(frappe.db.escape(ac)) for ac in account_map] conditions.append("account in ({0})".format(", ".join(accounts_list))) return " and ".join(conditions), values diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 754a7d8ad7d..15355753ffb 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -245,7 +245,7 @@ def compare_existing_and_expected_gle(existing_gle, expected_gle): for entry in expected_gle: for e in existing_gle: if entry.account==e.account and entry.against_account==e.against_account \ - and entry.cost_center==e.cost_center \ + and (not entry.cost_center or not e.cost_center or entry.cost_center==e.cost_center) \ and (entry.debit != e.debit or entry.credit != e.credit): matched = False break diff --git a/erpnext/hooks.py b/erpnext/hooks.py index d8b8a2e0239..e3694532c16 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -4,7 +4,7 @@ app_publisher = "Web Notes Technologies Pvt. Ltd. and Contributors" app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations" app_icon = "icon-th" app_color = "#e74c3c" -app_version = "4.16.0" +app_version = "4.17.0" error_report_email = "support@erpnext.com" diff --git a/erpnext/manufacturing/doctype/production_order/test_production_order.py b/erpnext/manufacturing/doctype/production_order/test_production_order.py index a9975c1e6f3..59e56ef348f 100644 --- a/erpnext/manufacturing/doctype/production_order/test_production_order.py +++ b/erpnext/manufacturing/doctype/production_order/test_production_order.py @@ -10,7 +10,7 @@ from erpnext.manufacturing.doctype.production_order.production_order import make from erpnext.stock.doctype.stock_entry import test_stock_entry class TestProductionOrder(unittest.TestCase): - def test_planned_qty(self): + def check_planned_qty(self): set_perpetual_inventory(0) planned0 = frappe.db.get_value("Bin", {"item_code": "_Test FG Item", "warehouse": "_Test Warehouse 1 - _TC"}, "planned_qty") or 0 @@ -27,11 +27,15 @@ class TestProductionOrder(unittest.TestCase): s = frappe.get_doc(make_stock_entry(pro_doc.name, "Material Transfer", 4)) for d in s.get("mtn_details"): d.s_warehouse = "Stores - _TC" + s.fiscal_year = "_Test Fiscal Year 2013" + s.posting_date = "2013-01-02" s.insert() s.submit() # from wip to fg s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture", 4)) + s.fiscal_year = "_Test Fiscal Year 2013" + s.posting_date = "2013-01-03" s.insert() s.submit() @@ -44,12 +48,14 @@ class TestProductionOrder(unittest.TestCase): def test_over_production(self): from erpnext.manufacturing.doctype.production_order.production_order import StockOverProductionError - pro_doc = self.test_planned_qty() + pro_doc = self.check_planned_qty() test_stock_entry.make_stock_entry("_Test Item", None, "_Test Warehouse - _TC", 100, 100) test_stock_entry.make_stock_entry("_Test Item Home Desktop 100", None, "_Test Warehouse - _TC", 100, 100) s = frappe.get_doc(make_stock_entry(pro_doc.name, "Manufacture", 7)) + s.fiscal_year = "_Test Fiscal Year 2013" + s.posting_date = "2013-01-04" s.insert() self.assertRaises(StockOverProductionError, s.submit) diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js index e2192157c83..f0616dea686 100644 --- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js +++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.js @@ -24,6 +24,13 @@ cur_frm.cscript.item_code = function(doc,cdt,cdn) { } } +cur_frm.cscript.raise_purchase_request = function(doc, cdt, cdn) { + return frappe.call({ + method: "raise_purchase_request", + doc:doc + }) +} + cur_frm.cscript.download_materials_required = function(doc, cdt, cdn) { return $c_obj(doc, 'validate_data', '', function(r, rt) { if (!r['exc']) diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json index bdfab41fba7..c6ec1e2bea7 100644 --- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json +++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.json @@ -1,5 +1,5 @@ { - "creation": "2013-01-21 12:03:47.000000", + "creation": "2013-01-21 12:03:47", "default_print_format": "Standard", "docstatus": 0, "doctype": "DocType", @@ -20,6 +20,7 @@ { "fieldname": "fg_item", "fieldtype": "Link", + "in_list_view": 1, "label": "Filter based on item", "options": "Item", "permlevel": 0 @@ -27,6 +28,7 @@ { "fieldname": "customer", "fieldtype": "Link", + "in_list_view": 1, "label": "Filter based on customer", "options": "Customer", "permlevel": 0 @@ -34,6 +36,7 @@ { "fieldname": "company", "fieldtype": "Link", + "in_list_view": 1, "label": "Company", "options": "Company", "permlevel": 0, @@ -140,7 +143,7 @@ "fieldname": "raise_purchase_request", "fieldtype": "Button", "label": "Create Material Requests", - "options": "raise_purchase_request", + "options": "", "permlevel": 0 }, { @@ -155,7 +158,7 @@ "idx": 1, "in_create": 1, "issingle": 1, - "modified": "2013-12-20 19:23:25.000000", + "modified": "2015-01-11 21:53:21.253556", "modified_by": "Administrator", "module": "Manufacturing", "name": "Production Planning Tool", diff --git a/erpnext/selling/doctype/opportunity/test_records.json b/erpnext/selling/doctype/opportunity/test_records.json index 39709036358..43ab55de4fc 100644 --- a/erpnext/selling/doctype/opportunity/test_records.json +++ b/erpnext/selling/doctype/opportunity/test_records.json @@ -5,6 +5,8 @@ "enquiry_from": "Lead", "enquiry_type": "Sales", "lead": "_T-Lead-00001", + "transaction_date": "2013-12-12", + "fiscal_year": "_Test Fiscal Year 2013", "enquiry_details": [{ "item_name": "Test Item", "description": "Some description" diff --git a/erpnext/stock/doctype/stock_entry/test_stock_entry.py b/erpnext/stock/doctype/stock_entry/test_stock_entry.py index e010bd19b9d..73f1d0a92e0 100644 --- a/erpnext/stock/doctype/stock_entry/test_stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/test_stock_entry.py @@ -936,6 +936,8 @@ def make_stock_entry(item, source, target, qty, incoming_rate=None): "incoming_rate": incoming_rate, "conversion_factor": 1.0 }) + s.posting_date= "2013-01-01" + s.fiscal_year= "_Test Fiscal Year 2013" s.insert() s.submit() return s diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 530ab9af807..9c85277a322 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -153,8 +153,8 @@ class StockReconciliation(StockController): if row.valuation_rate in ("", None): row.valuation_rate = previous_sle.get("valuation_rate") - # if row.qty and not row.valuation_rate: - # frappe.throw(_("Valuation Rate required for Item {0}").format(row.item_code)) + if row.qty and not row.valuation_rate: + frappe.throw(_("Valuation Rate required for Item {0}").format(row.item_code)) self.insert_entries(row) diff --git a/erpnext/utilities/repost_stock.py b/erpnext/utilities/repost_stock.py index b63493e1307..29857254a05 100644 --- a/erpnext/utilities/repost_stock.py +++ b/erpnext/utilities/repost_stock.py @@ -240,7 +240,7 @@ def repost_all_stock_vouchers(): doc.validate() doc.update_stock_ledger() - doc.make_gl_entries(repost_future_gle=False, allow_negative_stock=True) + doc.make_gl_entries(repost_future_gle=False) frappe.db.commit() except Exception, e: print frappe.get_traceback() diff --git a/setup.py b/setup.py index 4df95668d41..eb280084355 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import os -version = "4.16.0" +version = "4.17.0" with open("requirements.txt", "r") as f: install_requires = f.readlines()