[cleanup]
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order_dashboard.py b/erpnext/buying/doctype/purchase_order/purchase_order_dashboard.py
new file mode 100644
index 0000000..4f1f576
--- /dev/null
+++ b/erpnext/buying/doctype/purchase_order/purchase_order_dashboard.py
@@ -0,0 +1,12 @@
+from frappe import _
+
+data = {
+ 'docstatus': 1,
+ 'fieldname': 'purchase_order',
+ 'transactions': [
+ {
+ 'label': _('Related Documents'),
+ 'items': ['Purchase Receipt', 'Purchase Invoice', 'Stock Entry']
+ },
+ ]
+}
\ No newline at end of file
diff --git a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
index 9bed98c..56ddd6b 100644
--- a/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
+++ b/erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
@@ -9,6 +9,7 @@
"docstatus": 0,
"doctype": "DocType",
"document_type": "Document",
+ "editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
@@ -1775,6 +1776,7 @@
"hide_toolbar": 0,
"icon": "icon-shopping-cart",
"idx": 29,
+ "image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 1,
@@ -1782,7 +1784,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2016-05-23 15:20:34.288790",
+ "modified": "2016-07-08 06:48:04.162164",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Quotation",
@@ -1845,7 +1847,7 @@
"role": "Purchase User",
"set_user_permissions": 0,
"share": 1,
- "submit": 0,
+ "submit": 1,
"write": 1
},
{
diff --git a/erpnext/demo/data/bom.json b/erpnext/demo/data/bom.json
index 145c0ba..1c3f7a9 100644
--- a/erpnext/demo/data/bom.json
+++ b/erpnext/demo/data/bom.json
@@ -1,145 +1,178 @@
[
{
- "item": "Bearing Assembly",
+ "item": "Bearing Assembly",
"items": [
{
- "item_code": "Base Bearing Plate",
- "qty": 1.0,
+ "item_code": "Base Bearing Plate",
+ "qty": 1.0,
"rate": 15.0
- },
+ },
{
- "item_code": "Bearing Block",
- "qty": 1.0,
+ "item_code": "Bearing Block",
+ "qty": 1.0,
"rate": 10.0
- },
+ },
{
- "item_code": "Bearing Collar",
- "qty": 2.0,
+ "item_code": "Bearing Collar",
+ "qty": 2.0,
"rate": 20.0
- },
+ },
{
- "item_code": "Bearing Pipe",
- "qty": 1.0,
+ "item_code": "Bearing Pipe",
+ "qty": 1.0,
"rate": 15.0
- },
+ },
{
- "item_code": "Upper Bearing Plate",
- "qty": 1.0,
+ "item_code": "Upper Bearing Plate",
+ "qty": 1.0,
"rate": 50.0
}
]
- },
+ },
{
- "item": "Wind Mill A Series",
+ "item": "Wind Mill A Series",
"items": [
{
- "item_code": "Base Bearing Plate",
- "qty": 1.0,
+ "item_code": "Base Bearing Plate",
+ "qty": 1.0,
"rate": 15.0
- },
+ },
{
- "item_code": "Base Plate",
- "qty": 1.0,
+ "item_code": "Base Plate",
+ "qty": 1.0,
"rate": 20.0
- },
+ },
{
- "item_code": "Bearing Block",
- "qty": 1.0,
+ "item_code": "Bearing Block",
+ "qty": 1.0,
"rate": 10.0
- },
+ },
{
- "item_code": "Bearing Pipe",
- "qty": 1.0,
+ "item_code": "Bearing Pipe",
+ "qty": 1.0,
"rate": 15.0
- },
+ },
{
- "item_code": "External Disc",
- "qty": 1.0,
+ "item_code": "External Disc",
+ "qty": 1.0,
"rate": 45.0
- },
+ },
{
- "item_code": "Shaft",
- "qty": 1.0,
+ "item_code": "Shaft",
+ "qty": 1.0,
"rate": 30.0
- },
+ },
{
- "item_code": "Wing Sheet",
- "qty": 4.0,
+ "item_code": "Wing Sheet",
+ "qty": 4.0,
"rate": 22.0
}
]
- },
+ },
{
- "item": "Wind MIll C Series",
+ "item": "Wind MIll C Series",
"items": [
{
- "item_code": "Base Plate",
- "qty": 2.0,
+ "item_code": "Base Plate",
+ "qty": 2.0,
"rate": 20.0
- },
+ },
{
- "item_code": "Internal Disc",
- "qty": 1.0,
+ "item_code": "Internal Disc",
+ "qty": 1.0,
"rate": 33.0
- },
+ },
{
- "item_code": "External Disc",
- "qty": 1.0,
+ "item_code": "External Disc",
+ "qty": 1.0,
"rate": 45.0
- },
+ },
{
- "item_code": "Bearing Assembly",
- "qty": 1.0,
+ "item_code": "Bearing Assembly",
+ "qty": 1.0,
"rate": 130.0
- },
+ },
{
- "item_code": "Wing Sheet",
- "qty": 3.0,
+ "item_code": "Wing Sheet",
+ "qty": 3.0,
"rate": 22.0
}
]
- },
+ },
{
- "item": "Wind Turbine",
+ "item": "Wind Turbine",
+ "with_operations": 1,
+ "operations": [
+ {
+ "operation": "Prepare Frame",
+ "time_in_mins": 30.0,
+ "workstation": "Drilling Machine 1"
+ },
+ {
+ "operation": "Setup Fixtures",
+ "time_in_mins": 15.0,
+ "workstation": "Assembly Station 1"
+ },
+ {
+ "operation": "Assembly Operation",
+ "time_in_mins": 30.0,
+ "workstation": "Assembly Station 1"
+ },
+ {
+ "operation": "Wiring",
+ "time_in_mins": 20.0,
+ "workstation": "Assembly Station 1"
+ },
+ {
+ "operation": "Testing",
+ "time_in_mins": 10.0,
+ "workstation": "Packing and Testing Station"
+ },
+ {
+ "operation": "Packing",
+ "time_in_mins": 25.0,
+ "workstation": "Packing and Testing Station"
+ }
+ ],
"items": [
{
- "item_code": "Base Bearing Plate",
- "qty": 1.0,
+ "item_code": "Base Bearing Plate",
+ "qty": 1.0,
"rate": 15.0
- },
+ },
{
- "item_code": "Base Plate",
- "qty": 1.0,
+ "item_code": "Base Plate",
+ "qty": 1.0,
"rate": 20.0
- },
+ },
{
- "item_code": "Bearing Collar",
- "qty": 1.0,
+ "item_code": "Bearing Collar",
+ "qty": 1.0,
"rate": 20.0
- },
+ },
{
- "item_code": "Blade Rib",
- "qty": 1.0,
+ "item_code": "Blade Rib",
+ "qty": 1.0,
"rate": 10.0
- },
+ },
{
- "item_code": "Shaft",
- "qty": 1.0,
+ "item_code": "Shaft",
+ "qty": 1.0,
"rate": 30.0
- },
+ },
{
- "item_code": "Wing Sheet",
- "qty": 2.0,
+ "item_code": "Wing Sheet",
+ "qty": 2.0,
"rate": 22.0
}
]
- },
+ },
{
- "item": "Base Plate",
+ "item": "Base Plate",
"items": [
{
- "item_code": "Base Plate Un Painted",
- "qty": 1.0,
+ "item_code": "Base Plate Un Painted",
+ "qty": 1.0,
"rate": 16.0
}
]
diff --git a/erpnext/demo/demo.py b/erpnext/demo/demo.py
index ff0f184..9aeea3a 100644
--- a/erpnext/demo/demo.py
+++ b/erpnext/demo/demo.py
@@ -4,7 +4,7 @@
import erpnext
import frappe.utils
from erpnext.demo.setup_data import setup_data
-from erpnext.demo.user import hr, sales, purchase
+from erpnext.demo.user import hr, sales, purchase, manufacturing, stock
def make(domain='Manufacturing'):
frappe.flags.domain = domain
@@ -43,7 +43,8 @@
hr.work()
sales.work()
purchase.work()
- # run_manufacturing()
+ manufacturing.work()
+ stock.work()
# run_stock()
# run_accounts()
# run_projects()
diff --git a/erpnext/demo/setup_data.py b/erpnext/demo/setup_data.py
index 6492152..f9bbd5d 100644
--- a/erpnext/demo/setup_data.py
+++ b/erpnext/demo/setup_data.py
@@ -14,6 +14,7 @@
setup_customer()
setup_supplier()
setup_item()
+ setup_warehouse()
import_json('Address')
import_json('Contact')
setup_workstation()
@@ -147,6 +148,11 @@
item.default_warehouse = frappe.get_all('Warehouse', filters={'warehouse_name': item.default_warehouse}, limit=1)[0].name
item.insert()
+def setup_warehouse():
+ w = frappe.new_doc('Warehouse')
+ w.warehouse_name = 'Supplier'
+ w.insert()
+
def setup_currency_exchange():
frappe.get_doc({
'doctype': 'Currency Exchange',
@@ -182,7 +188,7 @@
user.password = 'demo'
user.insert()
-def import_json(doctype, submit=False):
+def import_json(doctype, submit=False, values=None):
frappe.flags.in_import = True
data = json.loads(open(frappe.get_app_path('erpnext', 'demo', 'data',
frappe.scrub(doctype) + '.json')).read())
@@ -266,13 +272,14 @@
and e.date_of_joining > f.year_start_date) else f.year_start_date
ss.to_date = f.year_end_date
ss.append('earnings', {
- 'earning_type': 'Basic',
- 'modified_value': random.random() * 10000
+ 'salary_component': 'Basic',
+ 'amount': random.random() * 10000
})
ss.append('deductions', {
- 'deduction_type': 'Income Tax',
- 'd_modified_amt': random.random() * 1000
+ 'salary_component': 'Income Tax',
+ 'amount': random.random() * 1000
})
+
ss.insert()
def setup_account():
@@ -303,5 +310,16 @@
if not frappe.db.get_global('demo_purchase_user'):
user = frappe.get_doc('User', 'MichalSobczak@example.com')
- user.add_roles('Purchase User', 'Purchase Manager', 'Accounts User')
+ user.add_roles('Purchase User', 'Purchase Manager', 'Accounts User', 'Stock User')
frappe.db.set_global('demo_purchase_user', user.name)
+
+ if not frappe.db.get_global('demo_manufacturing_user'):
+ user = frappe.get_doc('User', 'NuranVerkleij@example.com')
+ user.add_roles('Manufacturing User', 'Stock User', 'Purchase User', 'Accounts User')
+ frappe.db.set_global('demo_manufacturing_user', user.name)
+
+ if not frappe.db.get_global('demo_stock_user'):
+ user = frappe.get_doc('User', 'HatsueKashiwagi@example.com')
+ user.add_roles('Manufacturing User', 'Stock User', 'Purchase User', 'Accounts User')
+ frappe.db.set_global('demo_stock_user', user.name)
+
diff --git a/erpnext/demo/user/manufacturing.py b/erpnext/demo/user/manufacturing.py
new file mode 100644
index 0000000..c91570c
--- /dev/null
+++ b/erpnext/demo/user/manufacturing.py
@@ -0,0 +1,77 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+
+import frappe, random, erpnext
+from frappe.utils.make_random import how_many
+from frappe.desk import query_report
+
+def work():
+ frappe.set_user(frappe.db.get_global('demo_manufacturing_user'))
+
+ from erpnext.projects.doctype.timesheet.timesheet import OverlapError
+
+ ppt = frappe.get_doc("Production Planning Tool", "Production Planning Tool")
+ ppt.company = erpnext.get_default_company()
+ ppt.use_multi_level_bom = 1
+ ppt.get_items_from = "Sales Order"
+ ppt.purchase_request_for_warehouse = "Stores - WPL"
+ ppt.run_method("get_open_sales_orders")
+ ppt.run_method("get_items")
+ ppt.run_method("raise_production_orders")
+ ppt.run_method("raise_material_requests")
+ frappe.db.commit()
+
+ # submit production orders
+ for pro in frappe.db.get_values("Production Order", {"docstatus": 0}, "name"):
+ b = frappe.get_doc("Production Order", pro[0])
+ b.wip_warehouse = "Work in Progress - WPL"
+ b.submit()
+ frappe.db.commit()
+
+ # submit material requests
+ for pro in frappe.db.get_values("Material Request", {"docstatus": 0}, "name"):
+ b = frappe.get_doc("Material Request", pro[0])
+ b.submit()
+ frappe.db.commit()
+
+ # stores -> wip
+ if random.random() < 0.3:
+ for pro in query_report.run("Open Production Orders")["result"][:how_many("Stock Entry for WIP")]:
+ make_stock_entry_from_pro(pro[0], "Material Transfer for Manufacture")
+
+ # wip -> fg
+ if random.random() < 0.3:
+ for pro in query_report.run("Production Orders in Progress")["result"][:how_many("Stock Entry for FG")]:
+ make_stock_entry_from_pro(pro[0], "Manufacture")
+
+ # submit time logs
+ for timesheet in frappe.get_all("Timesheet", ["name"], {"docstatus": 0,
+ "production_order": ("!=", ""), "to_time": ("<", frappe.flags.current_date)}):
+ timesheet = frappe.get_doc("Timesheet", timesheet.name)
+ try:
+ timesheet.submit()
+ frappe.db.commit()
+ except OverlapError:
+ pass
+
+def make_stock_entry_from_pro(pro_id, purpose):
+ from erpnext.manufacturing.doctype.production_order.production_order import make_stock_entry
+ from erpnext.stock.stock_ledger import NegativeStockError
+ from erpnext.stock.doctype.stock_entry.stock_entry import IncorrectValuationRateError, \
+ DuplicateEntryForProductionOrderError, OperationsNotCompleteError
+
+ try:
+ st = frappe.get_doc(make_stock_entry(pro_id, purpose))
+ st.posting_date = frappe.flags.current_date
+ st.fiscal_year = str(frappe.flags.current_date.year)
+ for d in st.get("items"):
+ d.cost_center = "Main - " + frappe.db.get_value('Company', st.company, 'abbr')
+ st.insert()
+ frappe.db.commit()
+ st.submit()
+ frappe.db.commit()
+ except (NegativeStockError, IncorrectValuationRateError, DuplicateEntryForProductionOrderError,
+ OperationsNotCompleteError):
+ frappe.db.rollback()
diff --git a/erpnext/demo/user/purchase.py b/erpnext/demo/user/purchase.py
index 58da9d3..9430677 100644
--- a/erpnext/demo/user/purchase.py
+++ b/erpnext/demo/user/purchase.py
@@ -27,6 +27,7 @@
for mr in frappe.get_all('Material Request',
filters={'material_request_type': 'Purchase', 'status': 'Open'},
limit=random.randint(1,6)):
+ print mr.name
if not frappe.get_all('Request for Quotation',
filters={'material_request': mr.name}, limit=1):
rfq = make_request_for_quotation(mr.name)
@@ -59,11 +60,11 @@
exchange_rate = get_exchange_rate(party_account_currency, company_currency)
# make supplier quotations
- if random.random() < 0.3:
+ if random.random() < 0.2:
from erpnext.stock.doctype.material_request.material_request import make_supplier_quotation
report = "Material Requests for which Supplier Quotations are not created"
- for row in query_report.run(report)["result"][:how_many("Supplier Quotation")]:
+ for row in query_report.run(report)["result"][:random.randint(1, 3)]:
if row[0] != "'Total'":
sq = frappe.get_doc(make_supplier_quotation(row[0]))
sq.transaction_date = frappe.flags.current_date
@@ -89,13 +90,15 @@
po.submit()
frappe.db.commit()
- if random.random() < 0.3:
+ if random.random() < 0.2:
make_subcontract()
def make_material_request(item_code, qty):
mr = frappe.new_doc("Material Request")
- if frappe.db.get_value('BOM', {'item': item_code, 'is_default': 1, 'is_active': 1}):
+ variant_of = frappe.db.get_value('Item', item_code, 'variant_of') or item_code
+
+ if frappe.db.get_value('BOM', {'item': variant_of, 'is_default': 1, 'is_active': 1}):
mr.material_request_type = 'Manufacture'
else:
mr.material_request_type = "Purchase"
@@ -143,6 +146,6 @@
# transfer material for sub-contract
stock_entry = frappe.get_doc(make_stock_entry(po.name, po.items[0].item_code))
- stock_entry.from_warehouse = "Stores - WP"
- stock_entry.to_warehouse = "Supplier - WP"
+ stock_entry.from_warehouse = "Stores - WPL"
+ stock_entry.to_warehouse = "Supplier - WPL"
stock_entry.insert()
diff --git a/erpnext/demo/user/stock.py b/erpnext/demo/user/stock.py
new file mode 100644
index 0000000..8266d7e
--- /dev/null
+++ b/erpnext/demo/user/stock.py
@@ -0,0 +1,97 @@
+# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+
+import frappe, random
+from frappe.desk import query_report
+from erpnext.stock.stock_ledger import NegativeStockError
+from erpnext.stock.doctype.serial_no.serial_no import SerialNoRequiredError, SerialNoQtyError
+
+def work():
+ frappe.set_user(frappe.db.get_global('demo_manufacturing_user'))
+
+ make_purchase_receipt()
+ make_delivery_note()
+ make_stock_reconciliation()
+ submit_draft_stock_entries()
+
+def make_purchase_receipt():
+ if random.random() < 0.6:
+ from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_receipt
+ report = "Purchase Order Items To Be Received"
+ po_list =list(set([r[0] for r in query_report.run(report)["result"] if r[0]!="'Total'"]))[:random.randint(1, 10)]
+ for po in po_list:
+ pr = frappe.get_doc(make_purchase_receipt(po))
+
+ if pr.is_subcontracted=="Yes":
+ pr.supplier_warehouse = "Supplier - WPL"
+
+ pr.posting_date = frappe.flags.current_date
+ pr.insert()
+ try:
+ pr.submit()
+ frappe.db.commit()
+ except (NegativeStockError):
+ frappe.db.rollback()
+
+def make_delivery_note():
+ # make purchase requests
+
+ # make delivery notes (if possible)
+ if random.random() < 0.3:
+ from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note
+ report = "Ordered Items To Be Delivered"
+ for so in list(set([r[0] for r in query_report.run(report)["result"]
+ if r[0]!="'Total'"]))[:random.randint(1, 3)]:
+ dn = frappe.get_doc(make_delivery_note(so))
+ dn.posting_date = frappe.flags.current_date
+ for d in dn.get("items"):
+ if not d.expense_account:
+ d.expense_account = ("Cost of Goods Sold - {0}".format(
+ frappe.db.get_value('Company', dn.company, 'abbr')))
+ dn.insert()
+ try:
+ dn.submit()
+ frappe.db.commit()
+ except (NegativeStockError, SerialNoRequiredError, SerialNoQtyError):
+ frappe.db.rollback()
+
+def make_stock_reconciliation():
+ # random set some items as damaged
+ from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation \
+ import OpeningEntryAccountError, EmptyStockReconciliationItemsError
+
+ if random.random() < 0.1:
+ stock_reco = frappe.new_doc("Stock Reconciliation")
+ stock_reco.posting_date = frappe.flags.current_date
+ stock_reco.get_items_for("Stores - WP")
+ if stock_reco.items:
+ for item in stock_reco.items:
+ if item.qty:
+ item.qty = item.qty - round(random.randint(1, item.qty))
+ try:
+ stock_reco.insert()
+ stock_reco.submit()
+ frappe.db.commit()
+ except OpeningEntryAccountError:
+ frappe.db.rollback()
+ except EmptyStockReconciliationItemsError:
+ frappe.db.rollback()
+
+def submit_draft_stock_entries():
+ from erpnext.stock.doctype.stock_entry.stock_entry import IncorrectValuationRateError, \
+ DuplicateEntryForProductionOrderError, OperationsNotCompleteError
+
+ # try posting older drafts (if exists)
+ for st in frappe.db.get_values("Stock Entry", {"docstatus":0}, "name"):
+ try:
+ ste = frappe.get_doc("Stock Entry", st[0])
+ ste.posting_date = frappe.flags.current_date
+ ste.save()
+ ste.submit()
+ frappe.db.commit()
+ except (NegativeStockError, IncorrectValuationRateError, DuplicateEntryForProductionOrderError,
+ OperationsNotCompleteError):
+ frappe.db.rollback()
+
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 287ee9b..580d1ba 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -41,8 +41,8 @@
self.validate_materials()
self.set_bom_material_details()
- self.calculate_cost()
self.validate_operations()
+ self.calculate_cost()
def on_update(self):
self.check_recursion()
@@ -64,7 +64,7 @@
self.manage_default_bom()
def get_item_det(self, item_code):
- item = frappe.db.sql("""select name, item_name, docstatus, description, image,
+ item = frappe.db.sql("""select name, item_name, docstatus, description, image,
is_sub_contracted_item, stock_uom, default_bom, last_purchase_rate
from `tabItem` where name=%s""", item_code, as_dict = 1)
@@ -370,7 +370,12 @@
def validate_operations(self):
if self.with_operations and not self.get('operations'):
- frappe.throw(_("Operations cannot be left blank."))
+ frappe.throw(_("Operations cannot be left blank"))
+
+ if self.with_operations:
+ for d in self.operations:
+ if not d.description:
+ d.description = frappe.db.get_value('Operation', d.operation, 'description')
def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1):
item_dict = {}
diff --git a/erpnext/manufacturing/doctype/bom_operation/bom_operation.json b/erpnext/manufacturing/doctype/bom_operation/bom_operation.json
index 0171c41..18ab251 100644
--- a/erpnext/manufacturing/doctype/bom_operation/bom_operation.json
+++ b/erpnext/manufacturing/doctype/bom_operation/bom_operation.json
@@ -2,10 +2,13 @@
"allow_copy": 0,
"allow_import": 0,
"allow_rename": 0,
+ "beta": 0,
"creation": "2013-02-22 01:27:49",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
+ "document_type": "Setup",
+ "editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
@@ -15,6 +18,7 @@
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Operation",
@@ -25,6 +29,7 @@
"options": "Operation",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
@@ -40,6 +45,7 @@
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Workstation",
@@ -50,6 +56,7 @@
"options": "Workstation",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -65,18 +72,20 @@
"fieldtype": "Text Editor",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
- "label": "Operation Description",
+ "label": "Description",
"length": 0,
"no_copy": 0,
"oldfieldname": "opn_description",
"oldfieldtype": "Text",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
- "reqd": 1,
+ "reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
@@ -89,12 +98,14 @@
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -110,6 +121,7 @@
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Hour Rate",
@@ -119,6 +131,7 @@
"oldfieldtype": "Currency",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -135,6 +148,7 @@
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Operation Time ",
@@ -145,6 +159,7 @@
"options": "",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
@@ -160,6 +175,7 @@
"fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Operating Cost",
@@ -169,6 +185,7 @@
"oldfieldtype": "Currency",
"permlevel": 0,
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 1,
"report_hide": 0,
"reqd": 0,
@@ -180,18 +197,21 @@
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 1,
+ "image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2015-11-16 06:29:42.924201",
+ "modified": "2016-07-08 08:42:17.903362",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM Operation",
"owner": "Administrator",
"permissions": [],
+ "quick_entry": 0,
"read_only": 0,
- "read_only_onload": 0
+ "read_only_onload": 0,
+ "track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/operation/operation.js b/erpnext/manufacturing/doctype/operation/operation.js
new file mode 100644
index 0000000..5c2aba6
--- /dev/null
+++ b/erpnext/manufacturing/doctype/operation/operation.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Operation', {
+ refresh: function(frm) {
+
+ }
+});
diff --git a/erpnext/manufacturing/doctype/operation/operation.json b/erpnext/manufacturing/doctype/operation/operation.json
index 66d0bb6..bf7f519 100644
--- a/erpnext/manufacturing/doctype/operation/operation.json
+++ b/erpnext/manufacturing/doctype/operation/operation.json
@@ -3,11 +3,13 @@
"allow_import": 1,
"allow_rename": 1,
"autoname": "Prompt",
+ "beta": 0,
"creation": "2014-11-07 16:20:30.683186",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
+ "editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
@@ -17,6 +19,7 @@
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 1,
"label": "Default Workstation",
@@ -26,6 +29,7 @@
"permlevel": 0,
"precision": "",
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -41,6 +45,7 @@
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
"length": 0,
@@ -48,6 +53,7 @@
"permlevel": 0,
"precision": "",
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -63,14 +69,16 @@
"fieldtype": "Text",
"hidden": 0,
"ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
"in_filter": 0,
"in_list_view": 0,
- "label": "Operation Description",
+ "label": "Description",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
+ "print_hide_if_no_value": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
@@ -82,13 +90,15 @@
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "icon-wrench",
+ "idx": 0,
+ "image_view": 0,
"in_create": 0,
"in_dialog": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2015-11-16 06:29:50.879598",
+ "modified": "2016-07-08 08:42:35.126397",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Operation",
@@ -136,8 +146,10 @@
"write": 1
}
],
+ "quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"sort_field": "modified",
- "sort_order": "DESC"
+ "sort_order": "DESC",
+ "track_seen": 0
}
\ No newline at end of file
diff --git a/erpnext/manufacturing/doctype/production_order/production_order.json b/erpnext/manufacturing/doctype/production_order/production_order.json
index 1a5415f..d1dc0c2 100644
--- a/erpnext/manufacturing/doctype/production_order/production_order.json
+++ b/erpnext/manufacturing/doctype/production_order/production_order.json
@@ -9,6 +9,7 @@
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
+ "editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
@@ -201,6 +202,32 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "description": "",
+ "fieldname": "sales_order",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_list_view": 0,
+ "label": "Sales Order",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Sales Order",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
"depends_on": "",
"fieldname": "qty",
"fieldtype": "Float",
@@ -952,32 +979,6 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
- "description": "Manufacture against Sales Order",
- "fieldname": "sales_order",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_list_view": 0,
- "label": "Sales Order",
- "length": 0,
- "no_copy": 0,
- "options": "Sales Order",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "unique": 0
- },
- {
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
"description": "Manufacture against Material Request",
"fieldname": "material_request",
"fieldtype": "Link",
@@ -1091,7 +1092,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-07-06 16:09:38.879785",
+ "modified": "2016-07-08 07:09:06.847763",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Production Order",
diff --git a/erpnext/projects/web_form/tasks/tasks.json b/erpnext/projects/web_form/tasks/tasks.json
index 912b4c4..1d952fc 100644
--- a/erpnext/projects/web_form/tasks/tasks.json
+++ b/erpnext/projects/web_form/tasks/tasks.json
@@ -11,7 +11,7 @@
"idx": 0,
"is_standard": 1,
"login_required": 1,
- "modified": "2016-06-24 16:11:10.935835",
+ "modified": "2016-07-07 06:04:30.979390",
"modified_by": "Administrator",
"module": "Projects",
"name": "tasks",
diff --git a/erpnext/setup/setup_wizard/install_fixtures.py b/erpnext/setup/setup_wizard/install_fixtures.py
index f2b72f4..3ea2539 100644
--- a/erpnext/setup/setup_wizard/install_fixtures.py
+++ b/erpnext/setup/setup_wizard/install_fixtures.py
@@ -183,7 +183,10 @@
{"doctype": "Offer Term", "offer_term": _("Incentives")},
{'doctype': "Print Heading", 'print_heading': _("Credit Note")},
- {'doctype': "Print Heading", 'print_heading': _("Debit Note")}
+ {'doctype': "Print Heading", 'print_heading': _("Debit Note")},
+
+ {"doctype": "Salary Component", "salary_component": _("Basic")},
+ {"doctype": "Salary Component", "salary_component": _("Income Tax")},
]
from erpnext.setup.setup_wizard.industry_type import get_industry_types
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 05435f4..9ed005e 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -5,7 +5,7 @@
import frappe
import frappe.defaults
from frappe import _
-from frappe.utils import cstr, cint, flt, comma_or, getdate, nowdate
+from frappe.utils import cstr, cint, flt, comma_or, getdate, nowdate, formatdate, format_time
from erpnext.stock.utils import get_incoming_rate
from erpnext.stock.stock_ledger import get_previous_sle, NegativeStockError
from erpnext.stock.get_item_details import get_bin_details, get_default_cost_center, get_conversion_factor
@@ -225,9 +225,12 @@
# validate qty during submit
if d.docstatus==1 and d.s_warehouse and not allow_negative_stock and d.actual_qty < d.transfer_qty:
- frappe.throw(_("""Row {0}: Qty not avalable in warehouse {1} on {2} {3}.
- Available Qty: {4}, Transfer Qty: {5}""").format(d.idx, d.s_warehouse,
- self.posting_date, self.posting_time, d.actual_qty, d.transfer_qty), NegativeStockError)
+ frappe.throw(_("Row {0}: Qty not available for {4} in warehouse {1} at posting time of the entry ({2} {3})".format(d.idx,
+ frappe.bold(d.s_warehouse), formatdate(self.posting_date),
+ format_time(self.posting_time), frappe.bold(d.item_code)))
+ + '<br><br>' + _("Available qty is {0}, you need {1}").format(frappe.bold(d.actual_qty),
+ frappe.bold(d.transfer_qty)),
+ NegativeStockError, title=_('Insufficient Stock'))
def get_stock_and_rate(self):
self.set_transfer_qty()
diff --git a/erpnext/stock/doctype/warehouse/warehouse.json b/erpnext/stock/doctype/warehouse/warehouse.json
index 86516ff..192afbb 100644
--- a/erpnext/stock/doctype/warehouse/warehouse.json
+++ b/erpnext/stock/doctype/warehouse/warehouse.json
@@ -9,6 +9,7 @@
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
+ "editable_grid": 0,
"fields": [
{
"allow_on_submit": 0,
@@ -428,7 +429,7 @@
"bold": 0,
"collapsible": 0,
"fieldname": "pin",
- "fieldtype": "Int",
+ "fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -588,7 +589,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2016-06-29 19:47:24.336215",
+ "modified": "2016-07-08 06:00:36.113988",
"modified_by": "Administrator",
"module": "Stock",
"name": "Warehouse",
diff --git a/erpnext/stock/doctype/warehouse/warehouse_tree.js b/erpnext/stock/doctype/warehouse/warehouse_tree.js
index 0134ca7..0baed4d 100644
--- a/erpnext/stock/doctype/warehouse/warehouse_tree.js
+++ b/erpnext/stock/doctype/warehouse/warehouse_tree.js
@@ -14,7 +14,7 @@
{fieldtype:'Data', fieldname: 'name_field',
label:__('New Warehouse Name'), reqd:true},
{fieldtype:'Check', fieldname:'is_group', label:__('Is Group'),
- description: __("Further nodes can be only created under 'Group' type nodes")}
+ description: __("Child nodes can be only created under 'Group' type nodes")}
],
onrender: function(node) {
if (node.data && node.data.balance!==undefined) {
diff --git a/erpnext/stock/report/material_requests_for_which_supplier_quotations_are_not_created/material_requests_for_which_supplier_quotations_are_not_created.json b/erpnext/stock/report/material_requests_for_which_supplier_quotations_are_not_created/material_requests_for_which_supplier_quotations_are_not_created.json
index 55583a9..8615684 100644
--- a/erpnext/stock/report/material_requests_for_which_supplier_quotations_are_not_created/material_requests_for_which_supplier_quotations_are_not_created.json
+++ b/erpnext/stock/report/material_requests_for_which_supplier_quotations_are_not_created/material_requests_for_which_supplier_quotations_are_not_created.json
@@ -1,17 +1,19 @@
{
- "apply_user_permissions": 1,
- "creation": "2013-08-09 12:20:58",
- "docstatus": 0,
- "doctype": "Report",
- "idx": 1,
- "is_standard": "Yes",
- "modified": "2015-03-30 05:46:11.917037",
- "modified_by": "Administrator",
- "module": "Stock",
- "name": "Material Requests for which Supplier Quotations are not created",
- "owner": "Administrator",
- "query": "select \n mr.name as \"Material Request:Link/Material Request:120\",\n mr.transaction_date as \"Date:Date:100\",\n\tmr_item.item_code as \"Item Code:Link/Item:120\",\n\tmr_item.qty as \"Qty:Float:100\",\n\tmr_item.item_name as \"Item Name::150\",\n\tmr_item.description as \"Description::200\",\n\tmr.company as \"Company:Link/Company:\"\nfrom\n\t`tabMaterial Request` mr, `tabMaterial Request Item` mr_item\nwhere\n\tmr_item.parent = mr.name\n\tand mr.material_request_type = \"Purchase\"\n\tand mr.docstatus = 1\n\tand mr.status != \"Stopped\"\n\tand not exists(select name from `tabSupplier Quotation Item` where prevdoc_docname=mr.name)\norder by mr.transaction_date asc",
- "ref_doctype": "Material Request",
- "report_name": "Material Requests for which Supplier Quotations are not created",
+ "add_total_row": 0,
+ "apply_user_permissions": 1,
+ "creation": "2013-08-09 12:20:58",
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 1,
+ "is_standard": "Yes",
+ "modified": "2016-07-08 05:43:10.236943",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Material Requests for which Supplier Quotations are not created",
+ "owner": "Administrator",
+ "query": "select \n mr.name as \"Material Request:Link/Material Request:120\",\n mr.transaction_date as \"Date:Date:100\",\n\tmr_item.item_code as \"Item Code:Link/Item:120\",\n\tmr_item.qty as \"Qty:Float:100\",\n\tmr_item.item_name as \"Item Name::150\",\n\tmr_item.description as \"Description::200\",\n\tmr.company as \"Company:Link/Company:\"\nfrom\n\t`tabMaterial Request` mr, `tabMaterial Request Item` mr_item\nwhere\n\tmr_item.parent = mr.name\n\tand mr.material_request_type = \"Purchase\"\n\tand mr.docstatus = 1\n\tand mr.status != \"Stopped\"\n\tand not exists(select name from `tabSupplier Quotation Item` where material_request=mr.name)\norder by mr.transaction_date asc",
+ "ref_doctype": "Material Request",
+ "report_name": "Material Requests for which Supplier Quotations are not created",
"report_type": "Query Report"
}
\ No newline at end of file
diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py
index 096a5e0..8d17a1e 100644
--- a/erpnext/stock/stock_ledger.py
+++ b/erpnext/stock/stock_ledger.py
@@ -229,7 +229,7 @@
# calculate new valuation rate only if stock value is positive
# else it remains the same as that of previous entry
self.valuation_rate = new_stock_value / new_stock_qty
-
+
def get_moving_average_values(self, sle):
actual_qty = flt(sle.actual_qty)
new_stock_qty = flt(self.qty_after_transaction) + actual_qty
@@ -303,7 +303,7 @@
break
else:
index = 0
-
+
# select first batch or the batch with same rate
batch = self.stock_queue[index]
if qty_to_pop >= batch[0]:
@@ -327,7 +327,7 @@
if stock_qty:
self.valuation_rate = stock_value / flt(stock_qty)
-
+
if not self.stock_queue:
self.stock_queue.append([0, sle.incoming_rate or sle.outgoing_rate or self.valuation_rate])
@@ -346,8 +346,9 @@
- if frappe.local.flags.currently_saving.doctype==self.exceptions[0]["voucher_type"] \
- and frappe.local.flags.currently_saving.name==self.exceptions[0]["voucher_no"]:
+ if (frappe.local.flags.currently_saving
+ and frappe.local.flags.currently_saving.doctype==self.exceptions[0]["voucher_type"]
+ and frappe.local.flags.currently_saving.name==self.exceptions[0]["voucher_no"]):
msg = _("{0} units of {1} needed in {2} to complete this transaction.").format(
abs(deficiency), frappe.get_desk_link('Item', self.item_code),
frappe.get_desk_link('Warehouse', self.warehouse))