Merge branch 'develop' of github.com:frappe/erpnext into general-ui-fixes
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 182ab42..e42f0d8 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -5,7 +5,7 @@
from erpnext.hooks import regional_overrides
from frappe.utils import getdate
-__version__ = '10.1.74'
+__version__ = '10.1.76'
def get_default_company(user=None):
'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
index 1bb7c97..bfdf451 100644
--- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
+++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
@@ -830,6 +830,10 @@
return
tax_withholding_details = get_party_tax_withholding_details(self)
+
+ if not tax_withholding_details:
+ return
+
accounts = []
for d in self.taxes:
if d.account_head == tax_withholding_details.get("account_head"):
@@ -839,6 +843,12 @@
if not accounts or tax_withholding_details.get("account_head") not in accounts:
self.append("taxes", tax_withholding_details)
+ to_remove = [d for d in self.taxes
+ if not d.tax_amount and d.account_head == tax_withholding_details.get("account_head")]
+
+ for d in to_remove:
+ self.remove(d)
+
# calculate totals again after applying TDS
self.calculate_taxes_and_totals()
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index f3ec775..6072fb8 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -324,7 +324,8 @@
return {
"print_format": print_format,
"allow_edit_rate": pos.get("allow_user_to_edit_rate"),
- "allow_edit_discount": pos.get("allow_user_to_edit_discount")
+ "allow_edit_discount": pos.get("allow_user_to_edit_discount"),
+ "campaign": pos.get("campaign")
}
def update_time_sheet(self, sales_invoice):
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 68cc500..f9364e2 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
+# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
@@ -762,6 +762,20 @@
set_perpetual_inventory(0)
frappe.db.sql("delete from `tabPOS Profile`")
+
+ def test_pos_si_without_payment(self):
+ set_perpetual_inventory()
+ make_pos_profile()
+
+ pos = copy.deepcopy(test_records[1])
+ pos["is_pos"] = 1
+ pos["update_stock"] = 1
+
+ si = frappe.copy_doc(pos)
+ si.insert()
+
+ # Check that the invoice cannot be submitted without payments
+ self.assertRaises(frappe.ValidationError, si.submit)
def test_sales_invoice_gl_entry_with_perpetual_inventory_no_item_code(self):
set_perpetual_inventory()
diff --git a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
index f553cc0..6c31e9e 100644
--- a/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
+++ b/erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
@@ -24,6 +24,7 @@
.format(tax_withholding_category, ref_doc.company))
tds_amount = get_tds_amount(ref_doc, tax_details, fy)
tax_row = get_tax_row(tax_details, tds_amount)
+
return tax_row
def get_tax_withholding_details(tax_withholding_category, fiscal_year, company):
@@ -62,46 +63,64 @@
def get_tds_amount(ref_doc, tax_details, fiscal_year_details):
fiscal_year, year_start_date, year_end_date = fiscal_year_details
tds_amount = 0
+ tds_deducted = 0
- def _get_tds():
- tds_amount = 0
- if not tax_details.threshold or ref_doc.net_total >= tax_details.threshold:
- tds_amount = ref_doc.net_total * tax_details.rate / 100
- return tds_amount
+ def _get_tds(amount):
+ if amount <= 0:
+ return 0
- if tax_details.cumulative_threshold:
- entries = frappe.db.sql("""
+ return amount * tax_details.rate / 100
+
+ entries = frappe.db.sql("""
select voucher_no, credit
from `tabGL Entry`
where party=%s and fiscal_year=%s and credit > 0
""", (ref_doc.supplier, fiscal_year), as_dict=1)
- supplier_credit_amount = flt(sum([d.credit for d in entries]))
+ vouchers = [d.voucher_no for d in entries]
+ advance_vouchers = get_advance_vouchers(ref_doc.supplier, fiscal_year)
- vouchers = [d.voucher_no for d in entries]
- vouchers += get_advance_vouchers(ref_doc.supplier, fiscal_year)
+ tds_vouchers = vouchers + advance_vouchers
- tds_deducted = 0
- if vouchers:
- tds_deducted = flt(frappe.db.sql("""
- select sum(credit)
- from `tabGL Entry`
- where account=%s and fiscal_year=%s and credit > 0
- and voucher_no in ({0})
- """.format(', '.join(["'%s'" % d for d in vouchers])),
- (tax_details.account_head, fiscal_year))[0][0])
+ if tds_vouchers:
+ tds_deducted = frappe.db.sql("""
+ SELECT sum(credit) FROM `tabGL Entry`
+ WHERE
+ account=%s and fiscal_year=%s and credit > 0
+ and voucher_no in ({0})""". format(','.join(['%s'] * len(tds_vouchers))),
+ ((tax_details.account_head, fiscal_year) + tuple(tds_vouchers)))
+
+ tds_deducted = tds_deducted[0][0] if tds_deducted and tds_deducted[0][0] else 0
+
+ if tds_deducted:
+ tds_amount = _get_tds(ref_doc.net_total)
+ else:
+ supplier_credit_amount = frappe.get_all('Purchase Invoice Item',
+ fields = ['sum(net_amount)'],
+ filters = {'parent': ('in', vouchers), 'docstatus': 1}, as_list=1)
+
+ supplier_credit_amount = (supplier_credit_amount[0][0]
+ if supplier_credit_amount and supplier_credit_amount[0][0] else 0)
+
+ jv_supplier_credit_amt = frappe.get_all('Journal Entry Account',
+ fields = ['sum(credit_in_account_currency)'],
+ filters = {
+ 'parent': ('in', vouchers), 'docstatus': 1,
+ 'party': ref_doc.supplier,
+ 'reference_type': ('not in', ['Purchase Invoice'])
+ }, as_list=1)
+
+ supplier_credit_amount += (jv_supplier_credit_amt[0][0]
+ if jv_supplier_credit_amt and jv_supplier_credit_amt[0][0] else 0)
+
+ supplier_credit_amount += ref_doc.net_total
debit_note_amount = get_debit_note_amount(ref_doc.supplier, year_start_date, year_end_date)
+ supplier_credit_amount -= debit_note_amount
- total_invoiced_amount = supplier_credit_amount + tds_deducted \
- + flt(ref_doc.net_total) - debit_note_amount
- if total_invoiced_amount >= tax_details.cumulative_threshold:
- total_applicable_tds = total_invoiced_amount * tax_details.rate / 100
- tds_amount = min(total_applicable_tds - tds_deducted, ref_doc.net_total)
- else:
- tds_amount = _get_tds()
- else:
- tds_amount = _get_tds()
+ if ((tax_details.get('threshold', 0) and supplier_credit_amount >= tax_details.threshold)
+ or (tax_details.get('cumulative_threshold', 0) and supplier_credit_amount >= tax_details.cumulative_threshold)):
+ tds_amount = _get_tds(supplier_credit_amount)
return tds_amount
@@ -114,7 +133,7 @@
select distinct voucher_no
from `tabGL Entry`
where party=%s and %s and debit > 0
- """, (supplier, condition))
+ """, (supplier, condition)) or []
def get_debit_note_amount(supplier, year_start_date, year_end_date, company=None):
condition = ""
@@ -126,4 +145,4 @@
from `tabPurchase Invoice`
where supplier=%s %s and is_return=1 and docstatus=1
and posting_date between %s and %s
- """, (supplier, condition, year_start_date, year_end_date)))
+ """, (supplier, condition, year_start_date, year_end_date)))
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py
index 20e1746..2530196 100644
--- a/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py
+++ b/erpnext/accounts/doctype/tax_withholding_category/test_tax_withholding_category.py
@@ -6,6 +6,7 @@
import frappe
import unittest
from frappe.utils import today
+from erpnext.accounts.utils import get_fiscal_year
test_dependencies = ["Supplier Group"]
@@ -14,65 +15,105 @@
def setUpClass(self):
# create relevant supplier, etc
create_records()
+ create_tax_with_holding_category()
- def test_single_threshold_tds(self):
- frappe.db.set_value("Supplier", "Test TDS Supplier", "tax_withholding_category", "TDS - 194D - Individual")
- pi = create_purchase_invoice()
+ def test_cumulative_threshold_tds(self):
+ frappe.db.set_value("Supplier", "Test TDS Supplier", "tax_withholding_category", "Cumulative Threshold TDS")
+ invoices = []
+
+ # create invoices for lower than single threshold tax rate
+ for _ in xrange(2):
+ pi = create_purchase_invoice(supplier = "Test TDS Supplier")
+ pi.submit()
+ invoices.append(pi)
+
+ # create another invoice whose total when added to previously created invoice,
+ # surpasses cumulative threshhold
+ pi = create_purchase_invoice(supplier = "Test TDS Supplier")
pi.submit()
- self.assertEqual(pi.taxes_and_charges_deducted, 800)
- self.assertEqual(pi.grand_total, 15200)
+ # assert equal tax deduction on total invoice amount uptil now
+ self.assertEqual(pi.taxes_and_charges_deducted, 3000)
+ self.assertEqual(pi.grand_total, 7000)
+ invoices.append(pi)
+
+ # TDS is already deducted, so from onward system will deduct the TDS on every invoice
+ pi = create_purchase_invoice(supplier = "Test TDS Supplier", rate=5000)
+ pi.submit()
+
+ # assert equal tax deduction on total invoice amount uptil now
+ self.assertEqual(pi.taxes_and_charges_deducted, 500)
+ invoices.append(pi)
+
+ #delete invoices to avoid clashing
+ for d in invoices:
+ d.cancel()
+ frappe.delete_doc("Purchase Invoice", d.name)
+
+ def test_single_threshold_tds(self):
+ invoices = []
+ frappe.db.set_value("Supplier", "Test TDS Supplier1", "tax_withholding_category", "Single Threshold TDS")
+ pi = create_purchase_invoice(supplier = "Test TDS Supplier1", rate = 20000)
+ pi.submit()
+ invoices.append(pi)
+
+ self.assertEqual(pi.taxes_and_charges_deducted, 2000)
+ self.assertEqual(pi.grand_total, 18000)
# check gl entry for the purchase invoice
gl_entries = frappe.db.get_all('GL Entry', filters={'voucher_no': pi.name}, fields=["*"])
self.assertEqual(len(gl_entries), 3)
for d in gl_entries:
if d.account == pi.credit_to:
- self.assertEqual(d.credit, 15200)
+ self.assertEqual(d.credit, 18000)
elif d.account == pi.items[0].get("expense_account"):
- self.assertEqual(d.debit, 16000)
+ self.assertEqual(d.debit, 20000)
elif d.account == pi.taxes[0].get("account_head"):
- self.assertEqual(d.credit, 800)
+ self.assertEqual(d.credit, 2000)
else:
raise ValueError("Account head does not match.")
- # delete purchase invoice to avoid it interefering in other tests
- pi.cancel()
- frappe.delete_doc('Purchase Invoice', pi.name)
-
- def test_cumulative_threshold_tds(self):
- frappe.db.set_value("Supplier", "Test TDS Supplier", "tax_withholding_category", "TDS - 194C - Individual")
- invoices = []
-
- # create invoices for lower than single threshold tax rate
- for _ in xrange(6):
- pi = create_purchase_invoice()
- pi.submit()
- invoices.append(pi)
-
- # create another invoice whose total when added to previously created invoice,
- # surpasses cumulative threshhold
- pi = create_purchase_invoice()
+ pi = create_purchase_invoice(supplier = "Test TDS Supplier1")
pi.submit()
-
- # assert equal tax deduction on total invoice amount uptil now
- self.assertEqual(pi.taxes_and_charges_deducted, 1120)
- self.assertEqual(pi.grand_total, 14880)
invoices.append(pi)
+ # TDS amount is 1000 because in previous invoices it's already deducted
+ self.assertEqual(pi.taxes_and_charges_deducted, 1000)
+
# delete invoices to avoid clashing
for d in invoices:
d.cancel()
frappe.delete_doc("Purchase Invoice", d.name)
-def create_purchase_invoice(qty=1):
+ def test_single_threshold_tds_with_previous_vouchers(self):
+ invoices = []
+ frappe.db.set_value("Supplier", "Test TDS Supplier2", "tax_withholding_category", "Single Threshold TDS")
+ pi = create_purchase_invoice(supplier="Test TDS Supplier2")
+ pi.submit()
+ invoices.append(pi)
+
+ pi = create_purchase_invoice(supplier="Test TDS Supplier2")
+ pi.submit()
+ invoices.append(pi)
+
+ self.assertEqual(pi.taxes_and_charges_deducted, 2000)
+ self.assertEqual(pi.grand_total, 8000)
+
+ # delete invoices to avoid clashing
+ for d in invoices:
+ d.cancel()
+ frappe.delete_doc("Purchase Invoice", d.name)
+
+def create_purchase_invoice(**args):
# return sales invoice doc object
item = frappe.get_doc('Item', {'item_name': 'TDS Item'})
+
+ args = frappe._dict(args)
pi = frappe.get_doc({
"doctype": "Purchase Invoice",
"posting_date": today(),
"apply_tds": 1,
- "supplier": frappe.get_doc('Supplier', {"supplier_name": "Test TDS Supplier"}).name,
+ "supplier": args.supplier,
"company": '_Test Company',
"taxes_and_charges": "",
"currency": "INR",
@@ -81,8 +122,8 @@
"items": [{
'doctype': 'Purchase Invoice Item',
'item_code': item.name,
- 'qty': qty,
- 'rate': 16000,
+ 'qty': args.qty or 1,
+ 'rate': args.rate or 10000,
'cost_center': 'Main - _TC',
'expense_account': 'Stock Received But Not Billed - _TC'
}]
@@ -92,20 +133,73 @@
return pi
def create_records():
- # create a new supplier
- frappe.get_doc({
- "supplier_group": "_Test Supplier Group",
- "supplier_name": "Test TDS Supplier",
- "doctype": "Supplier",
- "tax_withholding_category": "TDS - 194D - Individual"
- }).insert()
+ # create a new suppliers
+ for name in ['Test TDS Supplier', 'Test TDS Supplier1', 'Test TDS Supplier2']:
+ if frappe.db.exists('Supplier', name):
+ continue
+
+ frappe.get_doc({
+ "supplier_group": "_Test Supplier Group",
+ "supplier_name": name,
+ "doctype": "Supplier",
+ }).insert()
# create an item
- frappe.get_doc({
- "doctype": "Item",
- "item_code": "TDS Item",
- "item_name": "TDS Item",
- "item_group": "All Item Groups",
- "company": "_Test Company",
- "is_stock_item": 0,
- }).insert()
\ No newline at end of file
+ if not frappe.db.exists('Item', "TDS Item"):
+ frappe.get_doc({
+ "doctype": "Item",
+ "item_code": "TDS Item",
+ "item_name": "TDS Item",
+ "item_group": "All Item Groups",
+ "is_stock_item": 0,
+ }).insert()
+
+ # create an account
+ if not frappe.db.exists("Account", "TDS - _TC"):
+ frappe.get_doc({
+ 'doctype': 'Account',
+ 'company': '_Test Company',
+ 'account_name': 'TDS',
+ 'parent_account': 'Tax Assets - _TC',
+ 'report_type': 'Balance Sheet',
+ 'root_type': 'Asset'
+ }).insert()
+
+def create_tax_with_holding_category():
+ fiscal_year = get_fiscal_year(today(), company="_Test Company")[0]
+
+ # Cummulative thresold
+ if not frappe.db.exists("Tax Withholding Category", "Cumulative Threshold TDS"):
+ frappe.get_doc({
+ "doctype": "Tax Withholding Category",
+ "name": "Cumulative Threshold TDS",
+ "category_name": "10% TDS",
+ "rates": [{
+ 'fiscal_year': fiscal_year,
+ 'tax_withholding_rate': 10,
+ 'single_threshold': 0,
+ 'cumulative_threshold': 30000.00
+ }],
+ "accounts": [{
+ 'company': '_Test Company',
+ 'account': 'TDS - _TC'
+ }]
+ }).insert()
+
+ # Single thresold
+ if not frappe.db.exists("Tax Withholding Category", "Single Threshold TDS"):
+ frappe.get_doc({
+ "doctype": "Tax Withholding Category",
+ "name": "Single Threshold TDS",
+ "category_name": "10% TDS",
+ "rates": [{
+ 'fiscal_year': fiscal_year,
+ 'tax_withholding_rate': 10,
+ 'single_threshold': 20000.00,
+ 'cumulative_threshold': 0
+ }],
+ "accounts": [{
+ 'company': '_Test Company',
+ 'account': 'TDS - _TC'
+ }]
+ }).insert()
\ No newline at end of file
diff --git a/erpnext/accounts/page/pos/pos.js b/erpnext/accounts/page/pos/pos.js
index 91f3711..04c8718 100755
--- a/erpnext/accounts/page/pos/pos.js
+++ b/erpnext/accounts/page/pos/pos.js
@@ -1135,16 +1135,18 @@
},
apply_category: function() {
- var me = this;
- category = this.selected_item_group || "All Item Groups";
+ frappe.db.get_value("Item Group", {lft: 1, is_group: 1}, "name", (r) => {
+ category = this.selected_item_group || r.name;
- if(category == 'All Item Groups') {
- return this.item_data
- } else {
- return this.item_data.filter(function(element, index, array){
- return element.item_group == category;
- });
- }
+ if(category == r.name) {
+ return this.item_data
+ } else {
+ return this.item_data.filter(function(element, index, array){
+ return element.item_group == category;
+ });
+ }
+ })
+
},
bind_items_event: function() {
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index d446c5b..207e28b 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -5,7 +5,7 @@
import frappe, erpnext
from frappe import _, msgprint, scrub
-from frappe.defaults import get_user_permissions
+from frappe.core.doctype.user_permission.user_permission import get_permitted_documents
from frappe.model.utils import get_fetch_values
from frappe.utils import (add_days, getdate, formatdate, date_diff,
add_years, get_timestamp, nowdate, flt, add_months, get_last_day)
@@ -151,10 +151,7 @@
def set_price_list(out, party, party_type, given_price_list):
# price list
- price_list = filter(None, get_user_permissions()
- .get("Price List", {})
- .get("docs", []))
- price_list = list(price_list)
+ price_list = get_permitted_documents('Price List')
if price_list:
price_list = price_list[0]
diff --git a/erpnext/buying/doctype/purchase_order/purchase_order.py b/erpnext/buying/doctype/purchase_order/purchase_order.py
index 36200c7..e72f59a 100644
--- a/erpnext/buying/doctype/purchase_order/purchase_order.py
+++ b/erpnext/buying/doctype/purchase_order/purchase_order.py
@@ -91,6 +91,7 @@
self.party_account_currency = get_party_account_currency("Supplier", self.supplier, self.company)
def validate_minimum_order_qty(self):
+ if not self.get("items"): return
items = list(set([d.item_code for d in self.get("items")]))
itemwise_min_order_qty = frappe._dict(frappe.db.sql("""select name, min_order_qty
diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py
index 855b877..95ce1eb 100644
--- a/erpnext/config/accounts.py
+++ b/erpnext/config/accounts.py
@@ -563,10 +563,6 @@
"items": [
{
"type": "doctype",
- "name": "Subscriber",
- },
- {
- "type": "doctype",
"name": "Subscription Plan",
},
{
diff --git a/erpnext/config/desktop.py b/erpnext/config/desktop.py
index b9fa257..2202b9e 100644
--- a/erpnext/config/desktop.py
+++ b/erpnext/config/desktop.py
@@ -572,5 +572,12 @@
"type": "module",
"label": _("Non Profit"),
"hidden": 1
+ },
+ {
+ "module_name": "Quality Management",
+ "color": "blue",
+ "icon": "octicon octicon-package",
+ "type": "module",
+ "label": _("Quality Management")
}
]
diff --git a/erpnext/config/quality_management.py b/erpnext/config/quality_management.py
new file mode 100644
index 0000000..a17b9f5
--- /dev/null
+++ b/erpnext/config/quality_management.py
@@ -0,0 +1,69 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return [
+ {
+ "label": _("Goal and Procedure"),
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Quality Goal",
+ "description":_("Quality Goal."),
+ },
+ {
+ "type": "doctype",
+ "name": "Quality Procedure",
+ "description":_("Quality Procedure."),
+ },
+ {
+ "type": "doctype",
+ "name": "Quality Procedure",
+ "icon": "fa fa-sitemap",
+ "label": _("Tree of Procedures"),
+ "route": "Tree/Quality Procedure",
+ "description": _("Tree of Quality Procedures."),
+ },
+ ]
+ },
+ {
+ "label": _("Review and Action"),
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Quality Review",
+ "description":_("Quality Review"),
+ },
+ {
+ "type": "doctype",
+ "name": "Quality Action",
+ "description":_("Quality Action"),
+ }
+ ]
+ },
+ {
+ "label": _("Meeting"),
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Quality Meeting",
+ "description":_("Quality Meeting"),
+ }
+ ]
+ },
+ {
+ "label": _("Feedback"),
+ "items": [
+ {
+ "type": "doctype",
+ "name": "Customer Feedback",
+ "description":_("Customer Feedback"),
+ },
+ {
+ "type": "doctype",
+ "name": "Customer Feedback Template",
+ "description":_("Customer Feedback Template"),
+ }
+ ]
+ },
+ ]
\ No newline at end of file
diff --git a/erpnext/controllers/buying_controller.py b/erpnext/controllers/buying_controller.py
index 03e9645..19616c5 100644
--- a/erpnext/controllers/buying_controller.py
+++ b/erpnext/controllers/buying_controller.py
@@ -678,7 +678,7 @@
frappe.db.sql("delete from `tabSerial No` where purchase_document_no=%s", self.name)
def validate_schedule_date(self):
- if not self.schedule_date:
+ if not self.schedule_date and self.get("items"):
self.schedule_date = min([d.schedule_date for d in self.get("items")])
if self.schedule_date:
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index 7b3f740..63e89ab 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -12,6 +12,9 @@
from erpnext.stock.stock_ledger import get_valuation_rate
from erpnext.stock import get_warehouse_account_map
+class QualityInspectionRequiredError(frappe.ValidationError): pass
+class QualityInspectionRejectedError(frappe.ValidationError): pass
+
class StockController(AccountsController):
def validate(self):
super(StockController, self).validate()
@@ -317,7 +320,6 @@
def validate_inspection(self):
'''Checks if quality inspection is set for Items that require inspection.
On submit, throw an exception'''
-
inspection_required_fieldname = None
if self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
inspection_required_fieldname = "inspection_required_before_purchase"
@@ -330,17 +332,25 @@
return
for d in self.get('items'):
- raise_exception = False
+ qa_required = False
if (inspection_required_fieldname and not d.quality_inspection and
frappe.db.get_value("Item", d.item_code, inspection_required_fieldname)):
- raise_exception = True
+ qa_required = True
elif self.doctype == "Stock Entry" and not d.quality_inspection and d.t_warehouse:
- raise_exception = True
+ qa_required = True
- if raise_exception:
+ if qa_required:
frappe.msgprint(_("Quality Inspection required for Item {0}").format(d.item_code))
if self.docstatus==1:
- raise frappe.ValidationError
+ raise QualityInspectionRequiredError
+ elif self.docstatus == 1:
+ if d.quality_inspection:
+ qa_doc = frappe.get_doc("Quality Inspection", d.quality_inspection)
+ qa_failed = any([r.status=="Rejected" for r in qa_doc.readings])
+ if qa_failed:
+ frappe.throw(_("Row {0}: Quality Inspection rejected for item {1}")
+ .format(d.idx, d.item_code), QualityInspectionRejectedError)
+
def update_blanket_order(self):
blanket_orders = list(set([d.blanket_order for d in self.items if d.blanket_order]))
diff --git a/erpnext/hooks.py b/erpnext/hooks.py
index b3a2061..78db6d3 100644
--- a/erpnext/hooks.py
+++ b/erpnext/hooks.py
@@ -12,7 +12,7 @@
source_link = "https://github.com/frappe/erpnext"
develop_version = '12.x.x-develop'
-staging_version = '11.0.3-beta.31'
+staging_version = '11.0.3-beta.32'
error_report_email = "support@erpnext.com"
@@ -254,7 +254,8 @@
"erpnext.assets.doctype.asset.asset.update_maintenance_status",
"erpnext.assets.doctype.asset.asset.make_post_gl_entry",
"erpnext.crm.doctype.contract.contract.update_status_for_contracts",
- "erpnext.projects.doctype.project.project.update_project_sales_billing"
+ "erpnext.projects.doctype.project.project.update_project_sales_billing",
+ "erpnext.quality_management.doctype.quality_review.quality_review.review"
],
"daily_long": [
"erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_latest_price_in_all_boms"
diff --git a/erpnext/hr/doctype/employee/employee.py b/erpnext/hr/doctype/employee/employee.py
index cb4c190..66d9bad 100755
--- a/erpnext/hr/doctype/employee/employee.py
+++ b/erpnext/hr/doctype/employee/employee.py
@@ -62,8 +62,8 @@
def validate_user_details(self):
data = frappe.db.get_value('User',
self.user_id, ['enabled', 'user_image'], as_dict=1)
-
- self.image = data.get("user_image")
+ if data.get("user_image"):
+ self.image = data.get("user_image")
self.validate_for_enabled_user_id(data.get("enabled", 0))
self.validate_duplicate_user_id()
diff --git a/erpnext/hr/doctype/leave_application/leave_application.js b/erpnext/hr/doctype/leave_application/leave_application.js
index a77dd32..5bce348 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.js
+++ b/erpnext/hr/doctype/leave_application/leave_application.js
@@ -14,7 +14,7 @@
doctype: frm.doc.doctype
}
};
- });
+ });
frm.set_query("employee", erpnext.queries.employee);
},
@@ -83,7 +83,7 @@
if (!frm.doc.employee && frappe.defaults.get_user_permissions()) {
const perm = frappe.defaults.get_user_permissions();
if (perm && perm['Employee']) {
- frm.set_value('employee', perm['Employee']["docs"][0])
+ frm.set_value('employee', perm['Employee'].map(perm_doc => perm_doc.doc)[0]);
}
}
},
diff --git a/erpnext/hr/doctype/salary_structure/salary_structure.py b/erpnext/hr/doctype/salary_structure/salary_structure.py
index 7ead140..202ae9b 100644
--- a/erpnext/hr/doctype/salary_structure/salary_structure.py
+++ b/erpnext/hr/doctype/salary_structure/salary_structure.py
@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import flt, cint
+from frappe.utils import flt, cint, cstr
from frappe import _
from frappe.model.mapper import get_mapped_doc
from frappe.model.document import Document
@@ -22,7 +22,7 @@
overwritten_fields_if_missing = ["amount_based_on_formula", "formula", "amount"]
for table in ["earnings", "deductions"]:
for d in self.get(table):
- component_default_value = frappe.db.get_value("Salary Component", str(d.salary_component),
+ component_default_value = frappe.db.get_value("Salary Component", cstr(d.salary_component),
overwritten_fields + overwritten_fields_if_missing, as_dict=1)
if component_default_value:
for fieldname in overwritten_fields:
diff --git a/erpnext/manufacturing/doctype/bom/bom.js b/erpnext/manufacturing/doctype/bom/bom.js
index a01011a..2615b31 100644
--- a/erpnext/manufacturing/doctype/bom/bom.js
+++ b/erpnext/manufacturing/doctype/bom/bom.js
@@ -402,6 +402,8 @@
var toggle_operations = function(frm) {
frm.toggle_display("operations_section", cint(frm.doc.with_operations) == 1);
+ frm.toggle_display("transfer_material_against", cint(frm.doc.with_operations) == 1);
+ frm.toggle_reqd("transfer_material_against", cint(frm.doc.with_operations) == 1);
};
frappe.ui.form.on("BOM", "with_operations", function(frm) {
diff --git a/erpnext/manufacturing/doctype/bom/bom.json b/erpnext/manufacturing/doctype/bom/bom.json
index 8c5f2af..0cf7dc4 100644
--- a/erpnext/manufacturing/doctype/bom/bom.json
+++ b/erpnext/manufacturing/doctype/bom/bom.json
@@ -87,41 +87,6 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "default": "1",
- "description": "Quantity of item obtained after manufacturing / repacking from given quantities of raw materials",
- "fieldname": "quantity",
- "fieldtype": "Float",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Quantity",
- "length": 0,
- "no_copy": 0,
- "oldfieldname": "quantity",
- "oldfieldtype": "Currency",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "uom",
"fieldtype": "Link",
"hidden": 0,
@@ -154,8 +119,10 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "inspection_required",
- "fieldtype": "Check",
+ "default": "1",
+ "description": "Quantity of item obtained after manufacturing / repacking from given quantities of raw materials",
+ "fieldname": "quantity",
+ "fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -163,51 +130,18 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Inspection Required",
+ "label": "Quantity",
"length": 0,
"no_copy": 0,
+ "oldfieldname": "quantity",
+ "oldfieldtype": "Currency",
"permlevel": 0,
- "precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "inspection_required",
- "fieldname": "quality_inspection_template",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Quality Inspection Template",
- "length": 0,
- "no_copy": 0,
- "options": "Quality Inspection Template",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
+ "reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
@@ -346,77 +280,11 @@
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
- "allow_on_submit": 1,
+ "allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "rm_cost_as_per",
- "fieldtype": "Select",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Rate Of Materials Based On",
- "length": 0,
- "no_copy": 0,
- "options": "Valuation Rate\nLast Purchase Rate\nPrice List",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 1,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "depends_on": "eval:doc.rm_cost_as_per===\"Price List\"",
- "fieldname": "buying_price_list",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Price List",
- "length": 0,
- "no_copy": 0,
- "options": "Price List",
- "permlevel": 0,
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 1,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "1",
- "fieldname": "set_rate_of_sub_assembly_item_based_on_bom",
+ "fieldname": "inspection_required",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -425,7 +293,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Set rate of sub-assembly item based on BOM",
+ "label": "Inspection Required",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -481,7 +349,7 @@
"collapsible": 0,
"columns": 0,
"fieldname": "allow_same_item_multiple_times",
- "fieldtype": "Data",
+ "fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -508,12 +376,12 @@
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
- "allow_on_submit": 0,
+ "allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "depends_on": "with_operations",
- "fieldname": "transfer_material_against_job_card",
+ "default": "1",
+ "fieldname": "set_rate_of_sub_assembly_item_based_on_bom",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -522,7 +390,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Transfer Material Against Job Card",
+ "label": "Set rate of sub-assembly item based on BOM",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -545,6 +413,40 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "depends_on": "inspection_required",
+ "fieldname": "quality_inspection_template",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Quality Inspection Template",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Quality Inspection Template",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"fieldname": "currency_detail",
"fieldtype": "Section Break",
"hidden": 0,
@@ -610,6 +512,72 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "default": "",
+ "fieldname": "transfer_material_against",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Transfer Material Against",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nWork Order\nJob Card",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "conversion_rate",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Conversion Rate",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "9",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_12",
"fieldtype": "Column Break",
"hidden": 0,
@@ -670,12 +638,12 @@
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
- "allow_on_submit": 0,
+ "allow_on_submit": 1,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "conversion_rate",
- "fieldtype": "Float",
+ "fieldname": "rm_cost_as_per",
+ "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -683,17 +651,50 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Conversion Rate",
+ "label": "Rate Of Materials Based On",
"length": 0,
"no_copy": 0,
+ "options": "Valuation Rate\nLast Purchase Rate\nPrice List",
"permlevel": 0,
- "precision": "9",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 1,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 1,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.rm_cost_as_per===\"Price List\"",
+ "fieldname": "buying_price_list",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Price List",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Price List",
+ "permlevel": 0,
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
@@ -707,7 +708,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "",
- "description": "Specify the operations, operating cost and give a unique Operation no to your operations.",
+ "description": "",
"fieldname": "operations_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1976,7 +1977,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-10-24 02:07:21.618275",
+ "modified": "2018-12-13 17:45:44.843197",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM",
diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py
index 4de48e1..a8053cd 100644
--- a/erpnext/manufacturing/doctype/bom/bom.py
+++ b/erpnext/manufacturing/doctype/bom/bom.py
@@ -81,7 +81,7 @@
def get_item_det(self, item_code):
item = frappe.db.sql("""select name, item_name, docstatus, description, image,
- is_sub_contracted_item, stock_uom, default_bom, last_purchase_rate, allow_transfer_for_manufacture
+ is_sub_contracted_item, stock_uom, default_bom, last_purchase_rate, include_item_in_manufacturing
from `tabItem` where name=%s""", item_code, as_dict = 1)
if not item:
@@ -109,7 +109,7 @@
"item_name": item.item_name,
"bom_no": item.bom_no,
"stock_qty": item.stock_qty,
- "allow_transfer_for_manufacture": item.allow_transfer_for_manufacture
+ "include_item_in_manufacturing": item.include_item_in_manufacturing
})
for r in ret:
if not item.get(r):
@@ -128,8 +128,8 @@
self.validate_rm_item(item)
args['bom_no'] = args['bom_no'] or item and cstr(item[0]['default_bom']) or ''
- args['transfer_for_manufacture'] = (cstr(args.get('allow_transfer_for_manufacture', '')) or
- item and item[0].allow_transfer_for_manufacture or 0)
+ args['transfer_for_manufacture'] = (cstr(args.get('include_item_in_manufacturing', '')) or
+ item and item[0].include_item_in_manufacturing or 0)
args.update(item[0])
rate = self.get_rm_rate(args)
@@ -145,7 +145,7 @@
'qty' : args.get("qty") or args.get("stock_qty") or 1,
'stock_qty' : args.get("qty") or args.get("stock_qty") or 1,
'base_rate' : rate,
- 'allow_transfer_for_manufacture': cint(args['transfer_for_manufacture']) or 0
+ 'include_item_in_manufacturing': cint(args['transfer_for_manufacture']) or 0
}
return ret_item
@@ -479,7 +479,7 @@
'stock_uom' : d.stock_uom,
'stock_qty' : flt(d.stock_qty),
'rate' : d.base_rate,
- 'allow_transfer_for_manufacture': d.allow_transfer_for_manufacture
+ 'include_item_in_manufacturing': d.include_item_in_manufacturing
}))
def company_currency(self):
@@ -496,7 +496,7 @@
# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss
child_fb_items = frappe.db.sql("""select bom_item.item_code, bom_item.item_name,
bom_item.description, bom_item.source_warehouse, bom_item.operation,
- bom_item.stock_uom, bom_item.stock_qty, bom_item.rate, bom_item.allow_transfer_for_manufacture,
+ bom_item.stock_uom, bom_item.stock_qty, bom_item.rate, bom_item.include_item_in_manufacturing,
bom_item.stock_qty / ifnull(bom.quantity, 1) as qty_consumed_per_unit
from `tabBOM Explosion Item` bom_item, tabBOM bom
where bom_item.parent = bom.name and bom.name = %s and bom.docstatus = 1""", bom_no, as_dict = 1)
@@ -511,7 +511,7 @@
'stock_uom' : d['stock_uom'],
'stock_qty' : d['qty_consumed_per_unit'] * stock_qty,
'rate' : flt(d['rate']),
- 'allow_transfer_for_manufacture': d.get('allow_transfer_for_manufacture', 0)
+ 'include_item_in_manufacturing': d.get('include_item_in_manufacturing', 0)
}))
def add_exploded_items(self):
@@ -587,7 +587,7 @@
query = query.format(table="BOM Explosion Item",
where_conditions="",
is_stock_item=is_stock_item,
- select_columns = """, bom_item.source_warehouse, bom_item.operation, bom_item.allow_transfer_for_manufacture,
+ select_columns = """, bom_item.source_warehouse, bom_item.operation, bom_item.include_item_in_manufacturing,
(Select idx from `tabBOM Item` where item_code = bom_item.item_code and parent = %(parent)s ) as idx""")
items = frappe.db.sql(query, { "parent": bom, "qty": qty, "bom": bom, "company": company }, as_dict=True)
@@ -596,7 +596,7 @@
items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
else:
query = query.format(table="BOM Item", where_conditions="", is_stock_item=is_stock_item,
- select_columns = ", bom_item.source_warehouse, bom_item.idx, bom_item.operation, bom_item.allow_transfer_for_manufacture")
+ select_columns = ", bom_item.source_warehouse, bom_item.idx, bom_item.operation, bom_item.include_item_in_manufacturing")
items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
for item in items:
diff --git a/erpnext/manufacturing/doctype/bom/test_records.json b/erpnext/manufacturing/doctype/bom/test_records.json
index 1a7e594..25730f9 100644
--- a/erpnext/manufacturing/doctype/bom/test_records.json
+++ b/erpnext/manufacturing/doctype/bom/test_records.json
@@ -11,7 +11,7 @@
"uom": "_Test UOM",
"stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC",
- "allow_transfer_for_manufacture": 1
+ "include_item_in_manufacturing": 1
},
{
"amount": 2000.0,
@@ -23,7 +23,7 @@
"uom": "_Test UOM",
"stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC",
- "allow_transfer_for_manufacture": 1
+ "include_item_in_manufacturing": 1
}
],
"docstatus": 1,
@@ -57,7 +57,7 @@
"uom": "_Test UOM",
"stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC",
- "allow_transfer_for_manufacture": 1
+ "include_item_in_manufacturing": 1
},
{
"amount": 2000.0,
@@ -69,7 +69,7 @@
"uom": "_Test UOM",
"stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC",
- "allow_transfer_for_manufacture": 1
+ "include_item_in_manufacturing": 1
}
],
"docstatus": 1,
@@ -102,7 +102,7 @@
"uom": "_Test UOM",
"stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC",
- "allow_transfer_for_manufacture": 1
+ "include_item_in_manufacturing": 1
},
{
"amount": 3000.0,
@@ -115,7 +115,7 @@
"uom": "_Test UOM",
"stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC",
- "allow_transfer_for_manufacture": 1
+ "include_item_in_manufacturing": 1
}
],
"docstatus": 1,
@@ -150,7 +150,7 @@
"uom": "_Test UOM",
"stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC",
- "allow_transfer_for_manufacture": 1
+ "include_item_in_manufacturing": 1
}
],
"docstatus": 1,
diff --git a/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json b/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
index ab3c5a1..9fadbef 100644
--- a/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
+++ b/erpnext/manufacturing/doctype/bom_explosion_item/bom_explosion_item.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
@@ -573,7 +574,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "allow_transfer_for_manufacture",
+ "fieldname": "include_item_in_manufacturing",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -582,7 +583,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Allow Transfer for Manufacture",
+ "label": "Include Item In Manufacturing",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -609,7 +610,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2018-08-27 16:32:35.152139",
+ "modified": "2018-11-20 19:04:59.813773",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM Explosion Item",
diff --git a/erpnext/manufacturing/doctype/bom_item/bom_item.json b/erpnext/manufacturing/doctype/bom_item/bom_item.json
index cc69471..8a380f7 100644
--- a/erpnext/manufacturing/doctype/bom_item/bom_item.json
+++ b/erpnext/manufacturing/doctype/bom_item/bom_item.json
@@ -79,34 +79,67 @@
"unique": 0
},
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_3",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "operation",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Item operation",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Operation",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_3",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -932,8 +965,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fetch_from": "item_code.allow_transfer_for_manufacture",
- "fieldname": "allow_transfer_for_manufacture",
+ "fetch_from": "item_code.include_item_in_manufacturing",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -942,7 +974,6 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Allow Transfer for Manufacture",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -956,6 +987,29 @@
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
+ "fieldname": "include_item_in_manufacturing",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Include Item In Manufacturing",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -1023,6 +1077,38 @@
"set_only_once": 0,
"translatable": 0,
"unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "allow_alternative_item",
+ "fieldtype": "Check",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Allow Alternative Item",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
}
],
"has_web_view": 0,
@@ -1035,7 +1121,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2018-11-22 15:04:55.187136",
+ "modified": "2018-12-26 15:04:56.187136",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM Item",
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.js b/erpnext/manufacturing/doctype/job_card/job_card.js
index 6f5290e..3fe9b8a 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.js
+++ b/erpnext/manufacturing/doctype/job_card/job_card.js
@@ -3,7 +3,7 @@
frappe.ui.form.on('Job Card', {
refresh: function(frm) {
- if (frm.doc.items && frm.doc.docstatus==1) {
+ if(!frm.doc.__islocal && frm.doc.items && frm.doc.items.length) {
if (frm.doc.for_quantity != frm.doc.transferred_qty) {
frm.add_custom_button(__("Material Request"), () => {
frm.trigger("make_material_request");
@@ -31,6 +31,7 @@
frm.add_custom_button(__("Complete Job"), () => {
frm.set_value('actual_end_date', frappe.datetime.now_datetime());
frm.save();
+ frm.savesubmit();
});
}
}
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.json b/erpnext/manufacturing/doctype/job_card/job_card.json
index 443cad8..b020c89 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.json
+++ b/erpnext/manufacturing/doctype/job_card/job_card.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
@@ -53,6 +54,39 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "bom_no",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "BOM No",
+ "length": 0,
+ "no_copy": 0,
+ "options": "BOM",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"fieldname": "workstation",
"fieldtype": "Link",
"hidden": 0,
@@ -119,39 +153,6 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "wip_warehouse",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "WIP Warehouse",
- "length": 0,
- "no_copy": 0,
- "options": "Warehouse",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "column_break_4",
"fieldtype": "Column Break",
"hidden": 0,
@@ -281,9 +282,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "default": "0",
- "fieldname": "transferred_qty",
- "fieldtype": "Float",
+ "fieldname": "wip_warehouse",
+ "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -291,17 +291,18 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Transferred Qty",
+ "label": "WIP Warehouse",
"length": 0,
"no_copy": 0,
+ "options": "Warehouse",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 1,
+ "read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
- "reqd": 0,
+ "reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
@@ -635,8 +636,9 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "bom_no",
- "fieldtype": "Link",
+ "default": "0",
+ "fieldname": "transferred_qty",
+ "fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -644,10 +646,42 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "BOM No",
+ "label": "Transferred Qty",
"length": 0,
"no_copy": 0,
- "options": "BOM",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "0",
+ "fieldname": "requested_qty",
+ "fieldtype": "Float",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Requested Qty",
+ "length": 0,
+ "no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -701,8 +735,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "column_break_20",
- "fieldtype": "Column Break",
+ "fieldname": "remarks",
+ "fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -710,6 +744,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
+ "label": "Remarks",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -732,8 +767,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "remarks",
- "fieldtype": "Small Text",
+ "fieldname": "column_break_20",
+ "fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -741,7 +776,6 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Remarks",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -776,13 +810,13 @@
"in_standard_filter": 0,
"label": "Status",
"length": 0,
- "no_copy": 0,
- "options": "Open\nWork In Progress\nCancelled\nCompleted",
+ "no_copy": 1,
+ "options": "Open\nWork In Progress\nMaterial Transferred\nSubmitted\nCancelled\nCompleted",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
- "read_only": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -834,7 +868,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-08-28 16:50:43.576151",
+ "modified": "2018-12-13 17:23:57.986381",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Job Card",
diff --git a/erpnext/manufacturing/doctype/job_card/job_card.py b/erpnext/manufacturing/doctype/job_card/job_card.py
index bc74535..5343a28 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card.py
+++ b/erpnext/manufacturing/doctype/job_card/job_card.py
@@ -11,9 +11,9 @@
class JobCard(Document):
def validate(self):
- self.status = 'Open'
self.validate_actual_dates()
self.set_time_in_mins()
+ self.set_status()
def validate_actual_dates(self):
if get_datetime(self.actual_start_date) > get_datetime(self.actual_end_date):
@@ -48,7 +48,7 @@
return
doc = frappe.get_doc('Work Order', self.get('work_order'))
- if not doc.transfer_material_against_job_card and doc.skip_transfer:
+ if doc.transfer_material_against == 'Work Order' and doc.skip_transfer:
return
for d in doc.required_items:
@@ -104,20 +104,23 @@
wo.set_actual_dates()
wo.save()
- def set_transferred_qty(self):
+ def set_transferred_qty(self, update_status=False):
if not self.items:
self.transferred_qty = self.for_quantity if self.docstatus == 1 else 0
if self.items:
- self.transferred_qty = frappe.db.get_value('Stock Entry', {'job_card': self.name,
- 'work_order': self.work_order, 'docstatus': 1}, 'sum(fg_completed_qty)') or 0
+ self.transferred_qty = frappe.db.get_value('Stock Entry', {
+ 'job_card': self.name,
+ 'work_order': self.work_order,
+ 'docstatus': 1
+ }, 'sum(fg_completed_qty)') or 0
self.db_set("transferred_qty", self.transferred_qty)
qty = 0
if self.work_order:
doc = frappe.get_doc('Work Order', self.work_order)
- if doc.transfer_material_against_job_card and not doc.skip_transfer:
+ if doc.transfer_material_against == 'Job Card' and not doc.skip_transfer:
completed = True
for d in doc.operations:
if d.status != 'Completed':
@@ -131,15 +134,28 @@
doc.db_set('material_transferred_for_manufacturing', qty)
- self.set_status()
+ self.set_status(update_status)
- def set_status(self):
- status = 'Cancelled' if self.docstatus == 2 else 'Work In Progress'
+ def set_status(self, update_status=False):
+ self.status = {
+ 0: "Open",
+ 1: "Submitted",
+ 2: "Cancelled"
+ }[self.docstatus or 0]
- if self.for_quantity == self.transferred_qty:
- status = 'Completed'
+ if self.actual_start_date:
+ self.status = 'Work In Progress'
- self.db_set('status', status)
+ if (self.docstatus == 1 and
+ (self.for_quantity == self.transferred_qty or not self.items)):
+ self.status = 'Completed'
+
+ if self.status != 'Completed':
+ if self.for_quantity == self.transferred_qty:
+ self.status = 'Material Transferred'
+
+ if update_status:
+ self.db_set('status', self.status)
@frappe.whitelist()
def make_material_request(source_name, target_doc=None):
diff --git a/erpnext/manufacturing/doctype/job_card/job_card_list.js b/erpnext/manufacturing/doctype/job_card/job_card_list.js
index d40a9fa..ed851eb 100644
--- a/erpnext/manufacturing/doctype/job_card/job_card_list.js
+++ b/erpnext/manufacturing/doctype/job_card/job_card_list.js
@@ -6,6 +6,8 @@
return [__("Completed"), "green", "status,=,Completed"];
} else if (doc.docstatus == 2) {
return [__("Cancelled"), "red", "status,=,Cancelled"];
+ } else if (doc.status === "Material Transferred") {
+ return [__('Material Transferred'), "blue", "status,=,Material Transferred"];
} else {
return [__("Open"), "red", "status,=,Open"];
}
diff --git a/erpnext/manufacturing/doctype/work_order/test_work_order.py b/erpnext/manufacturing/doctype/work_order/test_work_order.py
index 431ad32..69381c5 100644
--- a/erpnext/manufacturing/doctype/work_order/test_work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/test_work_order.py
@@ -306,7 +306,7 @@
items = {'Finished Good Transfer Item': 1, '_Test FG Item': 1, '_Test FG Item 1': 0}
for item, allow_transfer in items.items():
make_item(item, {
- 'allow_transfer_for_manufacture': allow_transfer
+ 'include_item_in_manufacturing': allow_transfer
})
fg_item = 'Finished Good Transfer Item'
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.js b/erpnext/manufacturing/doctype/work_order/work_order.js
index 594a808..53fa485 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.js
+++ b/erpnext/manufacturing/doctype/work_order/work_order.js
@@ -112,11 +112,21 @@
frm.trigger('show_progress');
}
- if (frm.doc.docstatus === 1 && frm.doc.operations
+ if (frm.doc.docstatus === 1
+ && frm.doc.operations && frm.doc.operations.length
&& frm.doc.qty != frm.doc.material_transferred_for_manufacturing) {
- frm.add_custom_button(__('Create Job Card'), () => {
- frm.trigger("make_job_card");
- }).addClass('btn-primary');
+
+ const not_completed = frm.doc.operations.filter(d => {
+ if(d.status != 'Completed') {
+ return true;
+ }
+ });
+
+ if(not_completed && not_completed.length) {
+ frm.add_custom_button(__('Create Job Card'), () => {
+ frm.trigger("make_job_card")
+ }).addClass('btn-primary');
+ }
}
if(frm.doc.required_items && frm.doc.allow_alternative_item) {
@@ -294,7 +304,7 @@
frm.trigger('set_sales_order');
erpnext.in_production_item_onchange = true;
$.each(["description", "stock_uom", "project", "bom_no",
- "allow_alternative_item", "transfer_material_against_job_card"], function(i, field) {
+ "allow_alternative_item", "transfer_material_against"], function(i, field) {
frm.set_value(field, r.message[field]);
});
@@ -340,9 +350,8 @@
before_submit: function(frm) {
frm.toggle_reqd(["fg_warehouse", "wip_warehouse"], true);
frm.fields_dict.required_items.grid.toggle_reqd("source_warehouse", true);
- if (frm.doc.operations) {
- frm.fields_dict.operations.grid.toggle_reqd("workstation", true);
- }
+ frm.toggle_reqd("transfer_material_against", frm.doc.operations);
+ frm.fields_dict.operations.grid.toggle_reqd("workstation", frm.doc.operations);
},
set_sales_order: function(frm) {
@@ -425,7 +434,7 @@
}
const show_start_btn = (frm.doc.skip_transfer
- || frm.doc.transfer_material_against_job_card) ? 0 : 1;
+ || frm.doc.transfer_material_against == 'Job Card') ? 0 : 1;
if (show_start_btn){
if ((flt(doc.material_transferred_for_manufacturing) < flt(doc.qty))
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.json b/erpnext/manufacturing/doctype/work_order/work_order.json
index df9dd83..a65d04f 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.json
+++ b/erpnext/manufacturing/doctype/work_order/work_order.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1,
"allow_rename": 0,
@@ -190,6 +191,38 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "fieldname": "allow_alternative_item",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Allow Alternative Item",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"default": "1",
"description": "Plan material for sub-assemblies",
"fieldname": "use_multi_level_bom",
@@ -223,7 +256,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "allow_alternative_item",
+ "description": "Check if material transfer entry is not required",
+ "fieldname": "skip_transfer",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -232,7 +266,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Allow Alternative Item",
+ "label": "Skip Material Transfer",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -493,39 +527,6 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "description": "Check if material transfer entry is not required",
- "fieldname": "skip_transfer",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Skip Material Transfer",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"depends_on": "skip_transfer",
"fieldname": "from_wip_warehouse",
"fieldtype": "Check",
@@ -559,39 +560,6 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "depends_on": "operations",
- "fieldname": "transfer_material_against_job_card",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Transfer Material Against Job Card",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
- "unique": 0
- },
- {
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
"fieldname": "warehouses",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1077,6 +1045,41 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
+ "default": "Work Order",
+ "depends_on": "operations",
+ "fieldname": "transfer_material_against",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Transfer Material Against",
+ "length": 0,
+ "no_copy": 0,
+ "options": "\nWork Order\nJob Card",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
"depends_on": "",
"fieldname": "operations",
"fieldtype": "Table",
@@ -1672,7 +1675,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-09-05 06:28:22.983369",
+ "modified": "2018-12-13 15:33:12.490710",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Work Order",
diff --git a/erpnext/manufacturing/doctype/work_order/work_order.py b/erpnext/manufacturing/doctype/work_order/work_order.py
index e73328f..9873efa 100644
--- a/erpnext/manufacturing/doctype/work_order/work_order.py
+++ b/erpnext/manufacturing/doctype/work_order/work_order.py
@@ -191,7 +191,7 @@
for purpose, fieldname in (("Manufacture", "produced_qty"),
("Material Transfer for Manufacture", "material_transferred_for_manufacturing")):
if (purpose == 'Material Transfer for Manufacture' and
- self.operations and self.transfer_material_against_job_card):
+ self.operations and self.transfer_material_against == 'Job Card'):
continue
qty = flt(frappe.db.sql("""select sum(fg_completed_qty)
@@ -459,7 +459,7 @@
'allow_alternative_item': item.allow_alternative_item,
'required_qty': item.qty,
'source_warehouse': item.source_warehouse or item.default_warehouse,
- 'allow_transfer_for_manufacture': item.allow_transfer_for_manufacture
+ 'include_item_in_manufacturing': item.include_item_in_manufacturing
})
self.set_available_qty()
@@ -564,11 +564,11 @@
frappe.throw(_("Default BOM for {0} not found").format(item))
bom_data = frappe.db.get_value('BOM', res['bom_no'],
- ['project', 'allow_alternative_item', 'transfer_material_against_job_card'], as_dict=1)
+ ['project', 'allow_alternative_item', 'transfer_material_against'], as_dict=1)
res['project'] = project or bom_data.project
res['allow_alternative_item'] = bom_data.allow_alternative_item
- res['transfer_material_against_job_card'] = bom_data.transfer_material_against_job_card
+ res['transfer_material_against'] = bom_data.transfer_material_against
res.update(check_if_scrap_warehouse_mandatory(res["bom_no"]))
return res
@@ -682,7 +682,7 @@
'wip_warehouse': work_order.wip_warehouse
})
- if work_order.transfer_material_against_job_card and not work_order.skip_transfer:
+ if work_order.transfer_material_against == 'Job Card' and not work_order.skip_transfer:
doc.get_required_items()
if auto_create:
diff --git a/erpnext/manufacturing/doctype/work_order_item/work_order_item.json b/erpnext/manufacturing/doctype/work_order_item/work_order_item.json
index 1db11f7..4442162 100644
--- a/erpnext/manufacturing/doctype/work_order_item/work_order_item.json
+++ b/erpnext/manufacturing/doctype/work_order_item/work_order_item.json
@@ -1,5 +1,6 @@
{
"allow_copy": 0,
+ "allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
@@ -342,7 +343,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "fieldname": "allow_transfer_for_manufacture",
+ "fieldname": "include_item_in_manufacturing",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
@@ -351,7 +352,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Allow Transfer for Manufacture",
+ "label": "Include Item In Manufacturing",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@@ -506,7 +507,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2018-10-04 16:16:54.237829",
+ "modified": "2018-11-20 19:04:38.508839",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Work Order Item",
diff --git a/erpnext/modules.txt b/erpnext/modules.txt
index e38d66a..9ef8937 100644
--- a/erpnext/modules.txt
+++ b/erpnext/modules.txt
@@ -22,3 +22,4 @@
Non Profit
Hotels
Hub Node
+Quality Management
\ No newline at end of file
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 4ae3e6d..1da7eba 100755
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -495,7 +495,7 @@
erpnext.patches.v10_0.update_translatable_fields
erpnext.patches.v10_0.rename_offer_letter_to_job_offer
execute:frappe.delete_doc('DocType', 'Production Planning Tool', ignore_missing=True)
-erpnext.patches.v10_0.migrate_daily_work_summary_settings_to_daily_work_summary_group
+erpnext.patches.v10_0.migrate_daily_work_summary_settings_to_daily_work_summary_group # 24-12-2018
erpnext.patches.v10_0.add_default_cash_flow_mappers
erpnext.patches.v11_0.make_quality_inspection_template
erpnext.patches.v10_0.update_status_for_multiple_source_in_po
@@ -579,6 +579,7 @@
erpnext.patches.v11_0.update_delivery_trip_status
erpnext.patches.v10_0.repost_gle_for_purchase_receipts_with_rejected_items
erpnext.patches.v11_0.set_missing_gst_hsn_code
+erpnext.patches.v11_0.rename_bom_wo_fields
erpnext.patches.v12_0.rename_learn_to_help
erpnext.patches.v12_0.rename_accounts_desktop_icon_to_accounting
erpnext.patches.v12_0.replace_project_list_desktop_icon_with_projects_module_desktop_icon
diff --git a/erpnext/patches/v10_0/migrate_daily_work_summary_settings_to_daily_work_summary_group.py b/erpnext/patches/v10_0/migrate_daily_work_summary_settings_to_daily_work_summary_group.py
index 3d15bbc..102b6da 100644
--- a/erpnext/patches/v10_0/migrate_daily_work_summary_settings_to_daily_work_summary_group.py
+++ b/erpnext/patches/v10_0/migrate_daily_work_summary_settings_to_daily_work_summary_group.py
@@ -6,37 +6,36 @@
def execute():
- frappe.reload_doc("hr", "doctype", "daily_work_summary_group")
- frappe.reload_doc("hr", "doctype", "daily_work_summary_group_user")
+ if not frappe.db.table_exists('Daily Work Summary Group'):
+ frappe.reload_doc("hr", "doctype", "daily_work_summary_group")
+ frappe.reload_doc("hr", "doctype", "daily_work_summary_group_user")
- # check if Daily Work Summary Settings Company table exists
- try:
- frappe.db.sql('DESC `tabDaily Work Summary Settings Company`')
- except Exception:
- return
+ # check if Daily Work Summary Settings Company table exists
+ try:
+ frappe.db.sql('DESC `tabDaily Work Summary Settings Company`')
+ except Exception:
+ return
- # get the previously saved settings
- previous_setting = get_previous_setting()
- if previous_setting["companies"]:
- for d in previous_setting["companies"]:
- users = frappe.get_list("Employee", dict(
- company=d.company, user_id=("!=", " ")), "user_id as user")
- if(len(users)):
- # create new group entry for each company entry
- new_group = frappe.get_doc(dict(doctype="Daily Work Summary Group",
- name="Daily Work Summary for " + d.company,
- users=users,
- send_emails_at=d.send_emails_at,
- subject=previous_setting["subject"],
- message=previous_setting["message"]))
- new_group.flags.ignore_permissions = True
- new_group.flags.ignore_validate = True
- new_group.insert(ignore_if_duplicate = True)
- frappe.delete_doc("Daily Work Summary Settings")
- frappe.delete_doc("Daily Work Summary Settings Company")
+ # get the previously saved settings
+ previous_setting = get_previous_setting()
+ if previous_setting["companies"]:
+ for d in previous_setting["companies"]:
+ users = frappe.get_list("Employee", dict(
+ company=d.company, user_id=("!=", " ")), "user_id as user")
+ if(len(users)):
+ # create new group entry for each company entry
+ new_group = frappe.get_doc(dict(doctype="Daily Work Summary Group",
+ name="Daily Work Summary for " + d.company,
+ users=users,
+ send_emails_at=d.send_emails_at,
+ subject=previous_setting["subject"],
+ message=previous_setting["message"]))
+ new_group.flags.ignore_permissions = True
+ new_group.flags.ignore_validate = True
+ new_group.insert(ignore_if_duplicate = True)
-def get_setting_companies():
- return frappe.db.sql("select * from `tabDaily Work Summary Settings Company`", as_dict=True)
+ frappe.delete_doc("DocType", "Daily Work Summary Settings")
+ frappe.delete_doc("DocType", "Daily Work Summary Settings Company")
def get_previous_setting():
@@ -47,3 +46,6 @@
obj[field] = value
obj["companies"] = get_setting_companies()
return obj
+
+def get_setting_companies():
+ return frappe.db.sql("select * from `tabDaily Work Summary Settings Company`", as_dict=True)
\ No newline at end of file
diff --git a/erpnext/patches/v11_0/rename_bom_wo_fields.py b/erpnext/patches/v11_0/rename_bom_wo_fields.py
new file mode 100644
index 0000000..c8106a6
--- /dev/null
+++ b/erpnext/patches/v11_0/rename_bom_wo_fields.py
@@ -0,0 +1,36 @@
+# Copyright (c) 2018, Frappe and Contributors
+# License: GNU General Public License v3. See license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.utils.rename_field import rename_field
+
+def execute():
+ for doctype in ['BOM Explosion Item', 'BOM Item', 'Work Order Item', 'Item']:
+ if frappe.db.has_column(doctype, 'allow_transfer_for_manufacture'):
+ if doctype != 'Item':
+ frappe.reload_doc('manufacturing', 'doctype', frappe.scrub(doctype))
+ else:
+ frappe.reload_doc('stock', 'doctype', frappe.scrub(doctype))
+
+ rename_field(doctype, "allow_transfer_for_manufacture", "include_item_in_manufacturing")
+
+ if frappe.db.has_column('BOM', 'allow_same_item_multiple_times'):
+ frappe.db.sql(""" UPDATE tabBOM
+ SET
+ allow_same_item_multiple_times = 0
+ WHERE
+ trim(coalesce(allow_same_item_multiple_times, '')) = '' """)
+
+ for doctype in ['BOM', 'Work Order']:
+ frappe.reload_doc('manufacturing', 'doctype', frappe.scrub(doctype))
+
+ if frappe.db.has_column(doctype, 'transfer_material_against_job_card'):
+ frappe.db.sql(""" UPDATE `tab%s`
+ SET transfer_material_against = CASE WHEN
+ transfer_material_against_job_card = 1 then 'Job Card' Else 'Work Order' END
+ WHERE docstatus < 2""" % (doctype))
+ else:
+ frappe.db.sql(""" UPDATE `tab%s`
+ SET transfer_material_against = 'Work Order'
+ WHERE docstatus < 2""" % (doctype))
\ No newline at end of file
diff --git a/erpnext/patches/v11_0/skip_user_permission_check_for_department.py b/erpnext/patches/v11_0/skip_user_permission_check_for_department.py
index 123eed5..7f7cfc1 100644
--- a/erpnext/patches/v11_0/skip_user_permission_check_for_department.py
+++ b/erpnext/patches/v11_0/skip_user_permission_check_for_department.py
@@ -1,28 +1,60 @@
import frappe
+from frappe.desk.form.linked_with import get_linked_doctypes
# Skips user permission check for doctypes where department link field was recently added
# https://github.com/frappe/erpnext/pull/14121
def execute():
- user_permissions = frappe.get_all("User Permission",
- filters=[['allow', '=', 'Department']],
- fields=['name', 'skip_for_doctype'])
+ doctypes_to_skip = []
+ for doctype in ['Appraisal', 'Leave Allocation', 'Expense Claim', 'Instructor', 'Salary Slip',
+ 'Attendance', 'Training Feedback', 'Training Result Employee',
+ 'Leave Application', 'Employee Advance', 'Activity Cost', 'Training Event Employee',
+ 'Timesheet', 'Sales Person', 'Payroll Employee Detail']:
+ if frappe.db.exists('Custom Field', { 'dt': doctype, 'fieldname': 'department'}): continue
+ doctypes_to_skip.append(doctype)
- doctypes_to_skip = []
+ frappe.reload_doctype('User Permission')
- for doctype in ['Appraisal', 'Leave Allocation', 'Expense Claim', 'Instructor', 'Salary Slip',
- 'Attendance', 'Training Feedback', 'Training Result Employee',
- 'Leave Application', 'Employee Advance', 'Activity Cost', 'Training Event Employee',
- 'Timesheet', 'Sales Person', 'Payroll Employee Detail']:
- if frappe.db.exists('Custom Field', { 'dt': doctype, 'fieldname': 'department'}): continue
- doctypes_to_skip.append(doctype)
+ user_permissions = frappe.get_all("User Permission",
+ filters=[['allow', '=', 'Department'], ['applicable_for', 'in', [None] + doctypes_to_skip]],
+ fields=['name', 'applicable_for'])
- for perm in user_permissions:
- skip_for_doctype = perm.get('skip_for_doctype')
+ user_permissions_to_delete = []
+ new_user_permissions_list = []
- skip_for_doctype = skip_for_doctype.split('\n') + doctypes_to_skip
- skip_for_doctype = set(skip_for_doctype) # to remove duplicates
- skip_for_doctype = '\n'.join(skip_for_doctype) # convert back to string
+ for user_permission in user_permissions:
+ if user_permission.applicable_for:
+ # simply delete user permission record since it needs to be skipped.
+ user_permissions_to_delete.append(user_permission.name)
+ else:
+ # if applicable_for is `None` it means that user permission is applicable for every doctype
+ # to avoid this we need to create other user permission records and only skip the listed doctypes in this patch
+ linked_doctypes = get_linked_doctypes(user_permission.allow, True).keys()
+ applicable_for_doctypes = list(set(linked_doctypes) - set(doctypes_to_skip))
- frappe.set_value('User Permission', perm.name, 'skip_for_doctype', skip_for_doctype)
+ user_permissions_to_delete.append(user_permission.name)
+ for doctype in applicable_for_doctypes:
+ if doctype:
+ # Maintain sequence (name, user, allow, for_value, applicable_for, apply_to_all_doctypes)
+ new_user_permissions_list.append((
+ frappe.generate_hash("", 10),
+ user_permission.user,
+ user_permission.allow,
+ user_permission.for_value,
+ doctype,
+ 0
+ ))
+
+ if new_user_permissions_list:
+ frappe.db.sql('''
+ INSERT INTO `tabUser Permission`
+ (`name`, `user`, `allow`, `for_value`, `applicable_for`, `apply_to_all_doctypes`)
+ VALUES {}'''.format(', '.join(['%s'] * len(new_user_permissions_list))), # nosec
+ tuple(new_user_permissions_list)
+ )
+
+ if user_permissions_to_delete:
+ frappe.db.sql('DELETE FROM `tabUser Permission` WHERE `name` IN ({})'.format( # nosec
+ ','.join(['%s'] * len(user_permissions_to_delete))
+ ), tuple(user_permissions_to_delete))
\ No newline at end of file
diff --git a/erpnext/patches/v11_0/update_allow_transfer_for_manufacture.py b/erpnext/patches/v11_0/update_allow_transfer_for_manufacture.py
index 9c94dee..1b58c97 100644
--- a/erpnext/patches/v11_0/update_allow_transfer_for_manufacture.py
+++ b/erpnext/patches/v11_0/update_allow_transfer_for_manufacture.py
@@ -6,7 +6,7 @@
def execute():
frappe.reload_doc('stock', 'doctype', 'item')
- frappe.db.sql(""" update `tabItem` set allow_transfer_for_manufacture = 1
+ frappe.db.sql(""" update `tabItem` set include_item_in_manufacturing = 1
where ifnull(is_stock_item, 0) = 1""")
for doctype in ['BOM Item', 'Work Order Item', 'BOM Explosion Item']:
@@ -14,7 +14,7 @@
frappe.db.sql(""" update `tab{0}` child, tabItem item
set
- child.allow_transfer_for_manufacture = 1
+ child.include_item_in_manufacturing = 1
where
child.item_code = item.name and ifnull(item.is_stock_item, 0) = 1
""".format(doctype))
\ No newline at end of file
diff --git a/erpnext/projects/doctype/project/project.py b/erpnext/projects/doctype/project/project.py
index 942593a..de45ec3 100644
--- a/erpnext/projects/doctype/project/project.py
+++ b/erpnext/projects/doctype/project/project.py
@@ -16,7 +16,7 @@
class Project(Document):
def get_feed(self):
- return '{0}: {1}'.format(_(self.status), self.project_name)
+ return '{0}: {1}'.format(_(self.status), frappe.safe_decode(self.project_name))
def onload(self):
"""Load project tasks for quick view"""
@@ -76,7 +76,7 @@
def validate_project_name(self):
if self.get("__islocal") and frappe.db.exists("Project", self.project_name):
- frappe.throw(_("Project {0} already exists").format(self.project_name))
+ frappe.throw(_("Project {0} already exists").format(frappe.safe_decode(self.project_name)))
def validate_dates(self):
if self.expected_start_date and self.expected_end_date:
@@ -258,13 +258,13 @@
self.total_purchase_cost = total_purchase_cost and total_purchase_cost[0][0] or 0
def update_sales_amount(self):
- total_sales_amount = frappe.db.sql("""select sum(base_grand_total)
+ total_sales_amount = frappe.db.sql("""select sum(base_net_total)
from `tabSales Order` where project = %s and docstatus=1""", self.name)
self.total_sales_amount = total_sales_amount and total_sales_amount[0][0] or 0
def update_billed_amount(self):
- total_billed_amount = frappe.db.sql("""select sum(base_grand_total)
+ total_billed_amount = frappe.db.sql("""select sum(base_net_total)
from `tabSales Invoice` where project = %s and docstatus=1""", self.name)
self.total_billed_amount = total_billed_amount and total_billed_amount[0][0] or 0
diff --git a/erpnext/public/js/setup_wizard.js b/erpnext/public/js/setup_wizard.js
index 82d6f6e..9beba6a 100644
--- a/erpnext/public/js/setup_wizard.js
+++ b/erpnext/public/js/setup_wizard.js
@@ -97,6 +97,9 @@
if (!this.values.company_abbr) {
return false;
}
+ if (this.values.company_abbr.length > 5) {
+ return false;
+ }
return true;
}
},
diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js
index 4b332e9..35105ef 100755
--- a/erpnext/public/js/utils.js
+++ b/erpnext/public/js/utils.js
@@ -237,7 +237,7 @@
let unscrub_option = frappe.model.unscrub(option);
let user_permission = frappe.defaults.get_user_permissions();
if(user_permission && user_permission[unscrub_option]) {
- return user_permission[unscrub_option]["docs"];
+ return user_permission[unscrub_option].map(perm => perm.doc);
} else {
return $.map(locals[`:${unscrub_option}`], function(c) { return c.name; }).sort();
}
diff --git a/erpnext/quality_management/__init__.py b/erpnext/quality_management/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/__init__.py
diff --git a/erpnext/quality_management/doctype/__init__.py b/erpnext/quality_management/doctype/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/doctype/__init__.py
diff --git a/erpnext/quality_management/doctype/customer_feedback/__init__.py b/erpnext/quality_management/doctype/customer_feedback/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback/__init__.py
diff --git a/erpnext/quality_management/doctype/customer_feedback/customer_feedback.js b/erpnext/quality_management/doctype/customer_feedback/customer_feedback.js
new file mode 100644
index 0000000..16ae9a1
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback/customer_feedback.js
@@ -0,0 +1,29 @@
+// Copyright (c) 2018, Frappe and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Customer Feedback', {
+ onload: function(frm){
+ frm.set_value("date", frappe.datetime.get_today());
+ $(".grid-add-row").hide();
+ frm.refresh();
+ },
+ template: function(frm){ // Used to fetch the parameters of the selected feedback template
+ frm.fields_dict.feedback.grid.remove_all();
+ if(frm.doc.template){
+ frappe.call({
+ "method": "frappe.client.get",
+ args: {
+ doctype: "Customer Feedback Template",
+ name: frm.doc.template
+ },
+ callback: function (data) {
+ for (var i = 0; i < data.message.feedback_parameter.length; i++ ){
+ frm.add_child("feedback");
+ frm.fields_dict.feedback.get_value()[i].parameter = data.message.feedback_parameter[i].parameter;
+ }
+ frm.refresh();
+ }
+ });
+ }
+ }
+});
diff --git a/erpnext/quality_management/doctype/customer_feedback/customer_feedback.json b/erpnext/quality_management/doctype/customer_feedback/customer_feedback.json
new file mode 100644
index 0000000..ffa7e4d
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback/customer_feedback.json
@@ -0,0 +1,259 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "QMS-FDBK-.#####",
+ "beta": 0,
+ "creation": "2018-10-02 12:23:38.437696",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "customer",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Customer",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Customer",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "template",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Template",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Customer Feedback Template",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "feedback_section",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Feedback",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "template.feedback_values",
+ "fieldname": "feedback",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "feedback",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Customer Feedback Table",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2018-11-12 14:39:18.044191",
+ "modified_by": "Administrator",
+ "module": "Quality Management",
+ "name": "Customer Feedback",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "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": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/customer_feedback/customer_feedback.py b/erpnext/quality_management/doctype/customer_feedback/customer_feedback.py
new file mode 100644
index 0000000..6211c42
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback/customer_feedback.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class CustomerFeedback(Document):
+ pass
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/customer_feedback/customer_feedback_dashboard.py b/erpnext/quality_management/doctype/customer_feedback/customer_feedback_dashboard.py
new file mode 100644
index 0000000..44ae123
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback/customer_feedback_dashboard.py
@@ -0,0 +1,12 @@
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'feedback',
+ 'transactions': [
+ {
+ 'label': _('Action'),
+ 'items': ['Quality Action']
+ }
+ ],
+ }
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/customer_feedback/customer_feedback_list.js b/erpnext/quality_management/doctype/customer_feedback/customer_feedback_list.js
new file mode 100644
index 0000000..7c5f767
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback/customer_feedback_list.js
@@ -0,0 +1,11 @@
+frappe.listview_settings['Customer Feedback'] = {
+ add_fields: ["action"],
+ get_indicator: function(doc) {
+ if(doc.action == "No Action") {
+ return [__("No Action"), "green", "action,=,No Action"];
+ }
+ else if(doc.action == "Action Initialised") {
+ return [__("Action Initialised"), "red", "action,=,Action Initialised"];
+ }
+ }
+};
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/customer_feedback/test_customer_feedback.js b/erpnext/quality_management/doctype/customer_feedback/test_customer_feedback.js
new file mode 100644
index 0000000..1003ee5
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback/test_customer_feedback.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Customer Feedback", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Customer Survey
+ () => frappe.tests.make('Customer Feedback', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/quality_management/doctype/customer_feedback/test_customer_feedback.py b/erpnext/quality_management/doctype/customer_feedback/test_customer_feedback.py
new file mode 100644
index 0000000..2ac6525
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback/test_customer_feedback.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+from erpnext.quality_management.doctype.customer_feedback_template.test_customer_feedback_template import create_template
+class TestCustomerFeedback(unittest.TestCase):
+ def test_customer_feedback(self):
+ create_template()
+ test_create_feedback = create_feedback()
+ test_get_feedback = get_feedback()
+ self.assertEquals(test_create_feedback.name, test_get_feedback.name)
+
+def create_feedback():
+ feedback = frappe.get_doc({
+ "doctype": "Customer Feedback",
+ "template": "FDBK-TMPL-_Test Customer Feedback Template",
+ "date": ""+ frappe.utils.nowdate() +""
+ })
+ feedback_exist = frappe.get_list("Customer Feedback", filters={"date": ""+ feedback.date +""}, limit=1)
+ if len(feedback_exist) == 0:
+ feedback.insert()
+ return feedback
+ else:
+ return feedback_exist[0]
+
+def get_feedback():
+ feedback = frappe.get_list("Customer Feedback", limit=1)
+ return feedback[0]
+
+#def create_feedback_template():
+# template = frappe.get_doc({
+# "doctype": "Customer Feedback Template",
+# "template": "_Test Customer Feedback Template",
+# "scope": "Company",
+# "feedback_parameter": [
+# {
+# "parameter": "_Test Customer Feedback Template Parameter",
+# }
+# ]
+# })
+# template_exist = frappe.get_list("Customer Feedback Template", filters={"template": ""+ template.template +""}, fields=["name"])
+# if len(template_exist) == 0:
+# template.insert()
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/customer_feedback_table/__init__.py b/erpnext/quality_management/doctype/customer_feedback_table/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback_table/__init__.py
diff --git a/erpnext/quality_management/doctype/customer_feedback_table/customer_feedback_table.json b/erpnext/quality_management/doctype/customer_feedback_table/customer_feedback_table.json
new file mode 100644
index 0000000..b9516b2
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback_table/customer_feedback_table.json
@@ -0,0 +1,142 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2018-10-15 15:36:27.193355",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "parameter",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Parameter",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "rating",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Rating",
+ "length": 0,
+ "no_copy": 0,
+ "options": "1\n2\n3\n4\n5",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "",
+ "fieldname": "qualitative_feedback",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Qualitative Feedback",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2018-11-01 14:29:03.273927",
+ "modified_by": "Administrator",
+ "module": "Quality Management",
+ "name": "Customer Feedback Table",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/customer_feedback_table/customer_feedback_table.py b/erpnext/quality_management/doctype/customer_feedback_table/customer_feedback_table.py
new file mode 100644
index 0000000..ef1b183
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback_table/customer_feedback_table.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class CustomerFeedbackTable(Document):
+ pass
diff --git a/erpnext/quality_management/doctype/customer_feedback_template/__init__.py b/erpnext/quality_management/doctype/customer_feedback_template/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback_template/__init__.py
diff --git a/erpnext/quality_management/doctype/customer_feedback_template/customer_feedback_template.js b/erpnext/quality_management/doctype/customer_feedback_template/customer_feedback_template.js
new file mode 100644
index 0000000..e318bf7
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback_template/customer_feedback_template.js
@@ -0,0 +1,5 @@
+// Copyright (c) 2018, Frappe and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Customer Feedback Template', {
+});
diff --git a/erpnext/quality_management/doctype/customer_feedback_template/customer_feedback_template.json b/erpnext/quality_management/doctype/customer_feedback_template/customer_feedback_template.json
new file mode 100644
index 0000000..1d1e344
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback_template/customer_feedback_template.json
@@ -0,0 +1,259 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "format:FDBK-TMPL-{template}",
+ "beta": 0,
+ "creation": "2018-10-18 15:11:26.215480",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "template",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Template",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_3",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "scope",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Scope",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company\nDepartment",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.scope == 'Department'",
+ "fieldname": "department",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Department",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Department",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "feedback_section",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Feedback",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "feedback_parameter",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Feedback",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Customer Feedback Template Table",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2018-11-01 14:27:07.935761",
+ "modified_by": "Administrator",
+ "module": "Quality Management",
+ "name": "Customer Feedback Template",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "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": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/customer_feedback_template/customer_feedback_template.py b/erpnext/quality_management/doctype/customer_feedback_template/customer_feedback_template.py
new file mode 100644
index 0000000..7f2eb3d
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback_template/customer_feedback_template.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class CustomerFeedbackTemplate(Document):
+ pass
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/customer_feedback_template/test_customer_feedback_template.js b/erpnext/quality_management/doctype/customer_feedback_template/test_customer_feedback_template.js
new file mode 100644
index 0000000..77168e0
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback_template/test_customer_feedback_template.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Customer Feedback Template", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Customer Feedback Template
+ () => frappe.tests.make('Customer Feedback Template', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/quality_management/doctype/customer_feedback_template/test_customer_feedback_template.py b/erpnext/quality_management/doctype/customer_feedback_template/test_customer_feedback_template.py
new file mode 100644
index 0000000..2bc4334
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback_template/test_customer_feedback_template.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestCustomerFeedbackTemplate(unittest.TestCase):
+ def test_customer_feedback_template(self):
+ test_create_template = create_template()
+ test_get_template = get_template()
+ self.assertEquals(test_get_template.name, test_create_template.name)
+
+def create_template():
+ template = frappe.get_doc({
+ "doctype": "Customer Feedback Template",
+ "template": "_Test Customer Feedback Template",
+ "scope": "Company",
+ "feedback_parameter": [
+ {
+ "parameter": "_Test Customer Feedback Template Parameter",
+ }
+ ]
+ })
+ template_exist = frappe.get_list("Customer Feedback Template", filters={"template": ""+ template.template +""}, fields=["name"], limit=1)
+ if len(template_exist) == 0:
+ template.insert()
+ return template
+ else:
+ return template_exist[0]
+
+def get_template():
+ template = frappe.get_list("Customer Feedback Template", filters={"template": "_Test Customer Feedback Template"}, limit=1)
+ return template[0]
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/customer_feedback_template_table/__init__.py b/erpnext/quality_management/doctype/customer_feedback_template_table/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback_template_table/__init__.py
diff --git a/erpnext/quality_management/doctype/customer_feedback_template_table/customer_feedback_template_table.json b/erpnext/quality_management/doctype/customer_feedback_template_table/customer_feedback_template_table.json
new file mode 100644
index 0000000..d28bb5d
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback_template_table/customer_feedback_template_table.json
@@ -0,0 +1,75 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2018-10-18 15:23:03.854925",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "parameter",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Parameter",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2018-11-01 14:28:50.626709",
+ "modified_by": "Administrator",
+ "module": "Quality Management",
+ "name": "Customer Feedback Template Table",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/customer_feedback_template_table/customer_feedback_template_table.py b/erpnext/quality_management/doctype/customer_feedback_template_table/customer_feedback_template_table.py
new file mode 100644
index 0000000..082046d
--- /dev/null
+++ b/erpnext/quality_management/doctype/customer_feedback_template_table/customer_feedback_template_table.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class CustomerFeedbackTemplateTable(Document):
+ pass
diff --git a/erpnext/quality_management/doctype/quality_action/__init__.py b/erpnext/quality_management/doctype/quality_action/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_action/__init__.py
diff --git a/erpnext/quality_management/doctype/quality_action/quality_action.js b/erpnext/quality_management/doctype/quality_action/quality_action.js
new file mode 100644
index 0000000..8cf8aa9
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_action/quality_action.js
@@ -0,0 +1,87 @@
+// Copyright (c) 2018, Frappe and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Quality Action', {
+ onload: function(frm) {
+ frm.set_value("date", frappe.datetime.get_today());
+ frm.refresh();
+ $(".grid-add-row").hide();
+ if (frm.doc.review){
+ frm.set_value("type", "Quality Review");
+ }
+ else{
+ frm.set_value("type", "Customer Feedback");
+ }
+ },
+ review: function(frm){
+ frm.fields_dict.description.grid.remove_all();
+ if(frm.doc.review){
+ var problems = "";
+ frappe.call({
+ "method": "frappe.client.get",
+ args: {
+ doctype: "Quality Review",
+ name: frm.doc.review
+ },
+ callback: function (data) {
+ for (var i = 0; i < data.message.values.length; i++){
+ if (data.message.values[i].achieved < data.message.values[i].target){
+ problems += data.message.values[i].objective +"-"+ data.message.values[i].achieved + " " + data.message.values[i].unit + "\n";
+ }
+ }
+ problems= problems.replace(/\n$/, "").split("\n");
+ for (i = 0; i < problems.length; i++){
+ frm.add_child("description");
+ frm.fields_dict.description.get_value()[i].problem = problems[i];
+ }
+ frm.refresh();
+ }
+ });
+ frappe.call({
+ "method": "frappe.client.get",
+ args: {
+ doctype: "Quality Goal",
+ name: frm.doc.goal
+ },
+ callback: function (data) {
+ frm.doc.procedure = data.message.procedure;
+ frm.refresh();
+ }
+ });
+ }
+ else{
+ frm.doc.goal = '';
+ frm.doc.procedure = '';
+ frm.refresh();
+ }
+ },
+ feedback: function(frm) {
+ frm.fields_dict.description.grid.remove_all();
+ if(frm.doc.feedback){
+ frappe.call({
+ "method": "frappe.client.get",
+ args: {
+ doctype: "Customer Feedback",
+ name: frm.doc.feedback
+ },
+ callback: function(data){
+ for (var i = 0; i < data.message.feedback.length; i++ ){
+ frm.add_child("description");
+ frm.fields_dict.description.get_value()[i].problem = data.message.feedback[i].parameter +"-"+ data.message.feedback[i].qualitative_feedback;
+ }
+ frm.refresh();
+ }
+ });
+ }
+ },
+ type: function(frm){
+ if(frm.doc.description){
+ frm.fields_dict.description.grid.remove_all();
+ frm.doc.review = '';
+ frm.doc.feedback = '';
+ frm.doc.goal = '';
+ frm.doc.procedure = '';
+ frm.refresh();
+ }
+ }
+});
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_action/quality_action.json b/erpnext/quality_management/doctype/quality_action/quality_action.json
new file mode 100644
index 0000000..e564a56
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_action/quality_action.json
@@ -0,0 +1,493 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "format:QMS-ACTN-{#####}",
+ "beta": 0,
+ "creation": "2018-10-02 11:40:43.666100",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "action",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Corrective/Preventive",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Corrective\nPreventive",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.type == 'Quality Review'",
+ "fieldname": "review",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Review",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Quality Review",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.type == 'Customer Feedback'",
+ "fieldname": "feedback",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Feedback",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Customer Feedback",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.type == 'Quality Review'",
+ "fetch_from": "review.goal",
+ "fieldname": "goal",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Quality Goal",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Quality Goal",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_3",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "type",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Type",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Quality Review\nCustomer Feedback",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.type == 'Quality Review'",
+ "fetch_from": "",
+ "fieldname": "procedure",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Procedure",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Quality Procedure",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "status_section",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Status",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "Under Review",
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Status",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Under Review\nClose",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_10",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "problem_resolution",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Description",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "description",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Action Description",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Quality Action Table",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2018-11-12 14:27:07.724362",
+ "modified_by": "Administrator",
+ "module": "Quality Management",
+ "name": "Quality Action",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "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": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_action/quality_action.py b/erpnext/quality_management/doctype/quality_action/quality_action.py
new file mode 100644
index 0000000..620252e
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_action/quality_action.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class QualityAction(Document):
+ def validate(self):
+ status_flag = ''
+ for value in self.description:
+ if value.resolution == None:
+ value.status = 'Open'
+ status_flag = 'Under Review'
+ else:
+ value.status = 'Close'
+ if status_flag == 'Under Review':
+ self.status = 'Under Review'
+ else:
+ self.status = 'Close'
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_action/quality_action_list.js b/erpnext/quality_management/doctype/quality_action/quality_action_list.js
new file mode 100644
index 0000000..da6b65d
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_action/quality_action_list.js
@@ -0,0 +1,11 @@
+frappe.listview_settings['Quality Action'] = {
+ add_fields: ["status"],
+ get_indicator: function(doc) {
+ if(doc.status == "Planned") {
+ return [__("Planned"), "green", "status,=,Planned"];
+ }
+ else{
+ return [__("Under Review"), "red", "status,=,Under Review"];
+ }
+ }
+};
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_action/test_quality_action.js b/erpnext/quality_management/doctype/quality_action/test_quality_action.js
new file mode 100644
index 0000000..34a8c86
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_action/test_quality_action.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Quality Action", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Quality Actions
+ () => frappe.tests.make('Quality Actions', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/quality_management/doctype/quality_action/test_quality_action.py b/erpnext/quality_management/doctype/quality_action/test_quality_action.py
new file mode 100644
index 0000000..c47955c
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_action/test_quality_action.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+from erpnext.quality_management.doctype.quality_procedure.test_quality_procedure import create_procedure
+from erpnext.quality_management.doctype.quality_goal.test_quality_goal import create_unit
+from erpnext.quality_management.doctype.quality_goal.test_quality_goal import create_goal
+from erpnext.quality_management.doctype.quality_review.test_quality_review import create_review
+
+class TestQualityAction(unittest.TestCase):
+
+ def test_quality_action(self):
+ create_procedure()
+ create_unit()
+ create_goal()
+ create_review()
+ test_create_action = create_action()
+ test_get_action = get_action()
+ self.assertEquals(test_create_action.name, test_get_action.name)
+ self.assertEquals(test_create_action.goal, test_get_action.goal)
+
+def create_action():
+ review = frappe.get_list("Quality Review", limit=1)
+ action = frappe.get_doc({
+ 'doctype': 'Quality Action',
+ 'action': 'Corrective',
+ 'type': 'Quality Review',
+ 'review': ''+ review[0].name +'',
+ 'date': ''+ frappe.utils.nowdate() +'',
+ 'goal': '_Test Quality Goal',
+ 'procedure': '_Test Quality Procedure'
+ })
+ action_exist = frappe.get_list("Quality Action", filters={"review": ""+ review[0].name +""}, fields=["name", "goal"], limit=1)
+ if len(action_exist) == 0:
+ action.insert()
+ return action
+ else:
+ return action_exist[0]
+
+def get_action():
+ review = frappe.get_list("Quality Review", limit=1)
+ action = frappe.get_list("Quality Action", filters={"review": ""+ review[0].name +""}, fields=["name", "goal"], limit=1)
+ return action[0]
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_action_table/__init__.py b/erpnext/quality_management/doctype/quality_action_table/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_action_table/__init__.py
diff --git a/erpnext/quality_management/doctype/quality_action_table/quality_action_table.json b/erpnext/quality_management/doctype/quality_action_table/quality_action_table.json
new file mode 100644
index 0000000..a5f7fb6
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_action_table/quality_action_table.json
@@ -0,0 +1,205 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2018-10-15 15:36:53.624990",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "problem",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Problem",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "resolution",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Resolution",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Status",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Open\nClose",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "responsible",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Responsible",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Role",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "completion_date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Completion Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2018-11-12 14:33:46.260600",
+ "modified_by": "Administrator",
+ "module": "Quality Management",
+ "name": "Quality Action Table",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_action_table/quality_action_table.py b/erpnext/quality_management/doctype/quality_action_table/quality_action_table.py
new file mode 100644
index 0000000..9beb148
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_action_table/quality_action_table.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class QualityActionTable(Document):
+ pass
diff --git a/erpnext/quality_management/doctype/quality_goal/__init__.py b/erpnext/quality_management/doctype/quality_goal/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_goal/__init__.py
diff --git a/erpnext/quality_management/doctype/quality_goal/quality_goal.js b/erpnext/quality_management/doctype/quality_goal/quality_goal.js
new file mode 100644
index 0000000..3bb6e12
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_goal/quality_goal.js
@@ -0,0 +1,41 @@
+// Copyright (c) 2018, Frappe and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Quality Goal', {
+ onload: function(frm){
+ if(frm.doc.measurable == "No"){
+ hide_target_unit(frm);
+ }
+ else{
+ show_target_unit(frm);
+ }
+ },
+ revision: function(frm) {
+ if(!frm.doc.revised_on){
+ frm.set_value("revised_on", frappe.datetime.get_today());
+ }
+ },
+ measurable: function(frm) {
+ frm.fields_dict.objective.grid.remove_all();
+ if(frm.doc.measurable == "No"){
+ hide_target_unit(frm);
+ }
+ else{
+ show_target_unit(frm);
+ }
+ }
+});
+
+function hide_target_unit(frm){
+ // hides target and unit columns as the goal cannot be measured in numeric values
+ frm.fields_dict.objective.grid.docfields[1].hidden = 1;
+ frm.fields_dict.objective.grid.docfields[2].hidden = 1;
+ frm.refresh();
+}
+
+function show_target_unit(frm){
+ // shows target and unit columns as the goal can be measured in numeric values
+ frm.fields_dict.objective.grid.docfields[1].hidden = 0;
+ frm.fields_dict.objective.grid.docfields[2].hidden = 0;
+ frm.refresh();
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_goal/quality_goal.json b/erpnext/quality_management/doctype/quality_goal/quality_goal.json
new file mode 100644
index 0000000..93f1bd1
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_goal/quality_goal.json
@@ -0,0 +1,824 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "format:{goal}",
+ "beta": 0,
+ "creation": "2018-10-02 12:17:41.727541",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "goal",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Name",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 1
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "created_by",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Created By",
+ "length": 0,
+ "no_copy": 0,
+ "options": "User",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "None",
+ "fieldname": "frequency",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Monitoring Frequency",
+ "length": 0,
+ "no_copy": 0,
+ "options": "None\nDaily\nWeekly\nMonthly\nQuarterly\nHalf Yearly\nYearly",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "January-April-July-October",
+ "depends_on": "eval:doc.frequency == 'Quarterly'",
+ "fieldname": "quarterly",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Day",
+ "length": 0,
+ "no_copy": 0,
+ "options": "",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "January-July",
+ "depends_on": "eval:doc.frequency == 'Half Yearly'",
+ "fieldname": "half",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Day",
+ "length": 0,
+ "no_copy": 0,
+ "options": "",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "January",
+ "depends_on": "eval:doc.frequency == 'Yearly'",
+ "fieldname": "yearly",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Day",
+ "length": 0,
+ "no_copy": 0,
+ "options": "January\nFebruary\nMarch\nApril\nMay\nJune\nJuly\nAugust\nSeptember\nOctober\nNovember\nDecember",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "procedure",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Procedure",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Quality Procedure",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "scope",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Scope",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company\nDepartment",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.frequency == 'Daily'",
+ "fieldname": "daily",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Day",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Everyday",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.frequency == 'Weekly'",
+ "fieldname": "weekly",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Day",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Monday\nTuesday\nWednesday\nThursday\nFriday\nSaturday",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.frequency == 'Quarterly' || doc.frequency == 'Half Yearly' || doc.frequency == 'Yearly' || doc.frequency == 'Monthly'",
+ "fieldname": "date",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Date",
+ "length": 0,
+ "no_copy": 0,
+ "options": "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n27\n28\n29\n30",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.scope == 'Department'",
+ "fieldname": "department",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Department",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Department",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_8",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Revision and Revised On",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "revision",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Revision",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_10",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "revised_on",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Revised On",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "measurable_section",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Measurable Goal",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "Yes",
+ "fieldname": "measurable",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Measurable Goal",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Yes\nNo",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_20",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "Target and Unit are disabled",
+ "depends_on": "eval:doc.measurable == 'No'",
+ "fieldname": "measurable_display",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Measurable",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_11",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Goal Objectives",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "objective",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Objective",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Quality Objective",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2018-11-12 14:35:18.498549",
+ "modified_by": "Administrator",
+ "module": "Quality Management",
+ "name": "Quality Goal",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "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": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_goal/quality_goal.py b/erpnext/quality_management/doctype/quality_goal/quality_goal.py
new file mode 100644
index 0000000..236c72a
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_goal/quality_goal.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class QualityGoal(Document):
+ pass
+
diff --git a/erpnext/quality_management/doctype/quality_goal/quality_goal_dashboard.py b/erpnext/quality_management/doctype/quality_goal/quality_goal_dashboard.py
new file mode 100644
index 0000000..0acc1da
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_goal/quality_goal_dashboard.py
@@ -0,0 +1,16 @@
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'goal',
+ 'transactions': [
+ {
+ 'label': _('Review'),
+ 'items': ['Quality Review']
+ },
+ {
+ 'label': _('Action'),
+ 'items': ['Quality Action']
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_goal/test_quality_goal.js b/erpnext/quality_management/doctype/quality_goal/test_quality_goal.js
new file mode 100644
index 0000000..f8afe54
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_goal/test_quality_goal.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Quality Goal", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Quality Goal
+ () => frappe.tests.make('Quality Goal', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/quality_management/doctype/quality_goal/test_quality_goal.py b/erpnext/quality_management/doctype/quality_goal/test_quality_goal.py
new file mode 100644
index 0000000..19512d9
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_goal/test_quality_goal.py
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+from erpnext.quality_management.doctype.quality_procedure.test_quality_procedure import create_procedure
+
+class TestQualityGoal(unittest.TestCase):
+
+ def test_quality_goal(self):
+ create_procedure()
+ create_unit()
+ test_create_goal = create_goal()
+ test_get_goal = get_goal()
+ self.assertEquals(test_create_goal, test_get_goal)
+
+def create_goal():
+ goal = frappe.get_doc({
+ "doctype": "Quality Goal",
+ "goal": "_Test Quality Goal",
+ "revision": "1",
+ "procedure": "_Test Quality Procedure",
+ "frequency": "Daily",
+ "measureable": "Yes",
+ "objective": [
+ {
+ "objective": "_Test Quality Objective",
+ "target": "4",
+ "unit": "_Test UOM"
+ }
+ ]
+ })
+ goal_exist = frappe.db.exists("Quality Goal", ""+ goal.goal +"")
+ if not goal_exist:
+ goal.insert()
+ return goal.goal
+ else:
+ return goal_exist
+
+def get_goal():
+ goal = frappe.db.exists("Quality Goal", "_Test Quality Goal")
+ return goal
+
+def create_unit():
+ unit = frappe.get_doc({
+ "doctype": "UOM",
+ "uom_name": "_Test UOM",
+ })
+ unit_exist = frappe.db.exists("UOM", ""+ unit.uom_name +"")
+ if not unit_exist:
+ unit.insert()
diff --git a/erpnext/quality_management/doctype/quality_meeting/__init__.py b/erpnext/quality_management/doctype/quality_meeting/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_meeting/__init__.py
diff --git a/erpnext/quality_management/doctype/quality_meeting/quality_meeting.js b/erpnext/quality_management/doctype/quality_meeting/quality_meeting.js
new file mode 100644
index 0000000..32c7c33
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_meeting/quality_meeting.js
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, Frappe and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Quality Meeting', {
+ onload: function(frm){
+ frm.set_value("date", frappe.datetime.get_today());
+ frm.refresh();
+ }
+});
diff --git a/erpnext/quality_management/doctype/quality_meeting/quality_meeting.json b/erpnext/quality_management/doctype/quality_meeting/quality_meeting.json
new file mode 100644
index 0000000..45183c5
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_meeting/quality_meeting.json
@@ -0,0 +1,225 @@
+{
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "format:QMS-MTN-{date}",
+ "beta": 0,
+ "creation": "2018-10-15 16:25:41.548432",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Meeting Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "Open",
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Status",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Open\nClose",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "minutes_break",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Minutes",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "minutes",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Minutes",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Quality Meeting Table",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2018-10-18 14:44:04.494395",
+ "modified_by": "Administrator",
+ "module": "Quality Management",
+ "name": "Quality Meeting",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "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": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_meeting/quality_meeting.py b/erpnext/quality_management/doctype/quality_meeting/quality_meeting.py
new file mode 100644
index 0000000..88653a9
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_meeting/quality_meeting.py
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class QualityMeeting(Document):
+ def validate(self):
+ problem = ''
+ for data in self.minutes:
+ if data.status == 'Open':
+ problem = 'set'
+
+ if problem == 'set':
+ self.status = 'Open'
+ else:
+ self.status = 'Close'
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_meeting/quality_meeting_list.js b/erpnext/quality_management/doctype/quality_meeting/quality_meeting_list.js
new file mode 100644
index 0000000..ff85c84
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_meeting/quality_meeting_list.js
@@ -0,0 +1,11 @@
+frappe.listview_settings['Quality Meeting'] = {
+ add_fields: ["status"],
+ get_indicator: function(doc) {
+ if(doc.status == "Open") {
+ return [__("Open"), "red", "status=,Open"];
+ }
+ else if(doc.status == "Close") {
+ return [__("Close"), "green", ",status=,Close"];
+ }
+ }
+};
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_meeting/test_quality_meeting.js b/erpnext/quality_management/doctype/quality_meeting/test_quality_meeting.js
new file mode 100644
index 0000000..196cc85
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_meeting/test_quality_meeting.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Quality Meeting", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Quality Meeting
+ () => frappe.tests.make('Quality Meeting', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/quality_management/doctype/quality_meeting/test_quality_meeting.py b/erpnext/quality_management/doctype/quality_meeting/test_quality_meeting.py
new file mode 100644
index 0000000..b680a1b
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_meeting/test_quality_meeting.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestQualityMeeting(unittest.TestCase):
+ def test_quality_meeting(self):
+ test_create_meeting = create_meeting()
+ test_get_meeting = get_meeting()
+ self.assertEquals(test_create_meeting.name, test_get_meeting.name)
+
+def create_meeting():
+ meeting = frappe.get_doc({
+ "doctype": "Quality Meeting",
+ "scope": "Company",
+ "status": "Close",
+ "date": ""+ frappe.as_unicode(frappe.utils.nowdate()) +""
+ })
+ meeting_exist = frappe.get_list("Quality Meeting", filters={"date": ""+ meeting.date +""}, fields=["name"], limit=1)
+ if len(meeting_exist) == 0:
+ meeting.insert()
+ return meeting
+ else:
+ return meeting_exist[0]
+
+def get_meeting():
+ meeting = frappe.get_list("Quality Meeting", limit=1)
+ return meeting[0]
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_meeting_table/__init__.py b/erpnext/quality_management/doctype/quality_meeting_table/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_meeting_table/__init__.py
diff --git a/erpnext/quality_management/doctype/quality_meeting_table/quality_meeting_table.json b/erpnext/quality_management/doctype/quality_meeting_table/quality_meeting_table.json
new file mode 100644
index 0000000..8e34a62
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_meeting_table/quality_meeting_table.json
@@ -0,0 +1,175 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2018-10-15 16:28:59.840039",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "review",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Review",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Quality Review",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "action",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Action",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Under Review\nPlanned",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "responsible",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Responsible",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Role",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "status",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Status",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Open\nClose",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2018-11-01 14:34:53.964306",
+ "modified_by": "Administrator",
+ "module": "Quality Management",
+ "name": "Quality Meeting Table",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_meeting_table/quality_meeting_table.py b/erpnext/quality_management/doctype/quality_meeting_table/quality_meeting_table.py
new file mode 100644
index 0000000..2e39c24
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_meeting_table/quality_meeting_table.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class QualityMeetingTable(Document):
+ pass
diff --git a/erpnext/quality_management/doctype/quality_objective/__init__.py b/erpnext/quality_management/doctype/quality_objective/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_objective/__init__.py
diff --git a/erpnext/quality_management/doctype/quality_objective/quality_objective.json b/erpnext/quality_management/doctype/quality_objective/quality_objective.json
new file mode 100644
index 0000000..49ffde9
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_objective/quality_objective.json
@@ -0,0 +1,144 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "format:{####}",
+ "beta": 0,
+ "creation": "2018-10-02 16:47:59.600155",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "goal.objective",
+ "fieldname": "objective",
+ "fieldtype": "Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Objective",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fieldname": "target",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Target",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "",
+ "fieldname": "unit",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Unit",
+ "length": 0,
+ "no_copy": 0,
+ "options": "UOM",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2018-11-11 13:31:16.044780",
+ "modified_by": "Administrator",
+ "module": "Quality Management",
+ "name": "Quality Objective",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_objective/quality_objective.py b/erpnext/quality_management/doctype/quality_objective/quality_objective.py
new file mode 100644
index 0000000..9e6a8fd
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_objective/quality_objective.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class QualityObjective(Document):
+ pass
diff --git a/erpnext/quality_management/doctype/quality_procedure/__init__.py b/erpnext/quality_management/doctype/quality_procedure/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_procedure/__init__.py
diff --git a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.js b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.js
new file mode 100644
index 0000000..ded3a51
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.js
@@ -0,0 +1,5 @@
+// Copyright (c) 2018, Frappe and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Quality Procedure', {
+});
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.json b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.json
new file mode 100644
index 0000000..8733c7c
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.json
@@ -0,0 +1,386 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "format:{procedure}",
+ "beta": 0,
+ "creation": "2018-10-06 00:06:29.756804",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "procedure",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Procedure",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "parent_quality_procedure",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Parent Procedure",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Quality Procedure",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "is_group",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Is Group",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "department",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Department",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Department",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "procedure_steps_section",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Procedure Steps",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "procedure_step",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Procedure",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Quality Procedure Table",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "lft",
+ "fieldtype": "Int",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Lft",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "rgt",
+ "fieldtype": "Int",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Rgt",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "old_parent",
+ "fieldtype": "Data",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "old_parent",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2018-11-12 14:30:19.803693",
+ "modified_by": "Administrator",
+ "module": "Quality Management",
+ "name": "Quality Procedure",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "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": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py
new file mode 100644
index 0000000..126b8c7
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_procedure/quality_procedure.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.utils.nestedset import NestedSet
+from frappe import _
+
+class QualityProcedure(NestedSet):
+ nsm_parent_field = 'parent_quality_procedure'
+
+ def before_save(self):
+ for data in self.procedure_step:
+ if data.procedure == 'Procedure' and data.procedure_name:
+ data.step = data.procedure_name
+ doc = frappe.get_doc("Quality Procedure", data.procedure_name)
+ if(doc.parent_quality_procedure):
+ frappe.throw(_("'"+ data.procedure_name +"' already has a Parent Procedure '"+ doc.parent_quality_procedure +"'"))
+ self.is_group = 1
+
+ def on_update(self):
+ self.set_parent()
+
+ def after_insert(self):
+ self.set_parent()
+
+ def on_trash(self):
+ if self.parent_quality_procedure:
+ doc = frappe.get_doc("Quality Procedure", self.parent_quality_procedure)
+ for data in doc.procedure_step:
+ if data.procedure_name == self.name:
+ doc.procedure_step.remove(data)
+ doc.save()
+ flag_is_group = 0
+ doc.load_from_db()
+ for data in doc.procedure_step:
+ if data.procedure == "Procedure":
+ flag_is_group = 1
+ if flag_is_group == 0:
+ doc.is_group = 0
+ doc.save()
+
+ def set_parent(self):
+ for data in self.procedure_step:
+ if data.procedure == 'Procedure' and data.procedure_name:
+ doc = frappe.get_doc("Quality Procedure", data.procedure_name)
+ doc.parent_quality_procedure = self.name
+ doc.save()
+
+@frappe.whitelist()
+def get_children(doctype, parent=None, parent_quality_procedure=None, is_root=False):
+ if parent is None or parent == "All Quality Procedures":
+ parent = ""
+ return frappe.get_all(doctype, fields=["name as value", "is_group as expandable"], filters={"parent_quality_procedure": parent})
+
+@frappe.whitelist()
+def add_node():
+ from frappe.desk.treeview import make_tree_args
+ args = frappe.form_dict
+ args = make_tree_args(**args)
+ if args.parent_quality_procedure == 'All Quality Procedures':
+ args.parent_quality_procedure = None
+ frappe.get_doc(args).insert()
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_procedure/quality_procedure_dashboard.py b/erpnext/quality_management/doctype/quality_procedure/quality_procedure_dashboard.py
new file mode 100644
index 0000000..8eff33c
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_procedure/quality_procedure_dashboard.py
@@ -0,0 +1,20 @@
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'procedure',
+ 'transactions': [
+ {
+ 'label': _('Goal'),
+ 'items': ['Quality Goal']
+ },
+ {
+ 'label': _('Review'),
+ 'items': ['Quality Review']
+ },
+ {
+ 'label': _('Action'),
+ 'items': ['Quality Action']
+ }
+ ],
+ }
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js b/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js
new file mode 100644
index 0000000..15b7784
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_procedure/quality_procedure_tree.js
@@ -0,0 +1,39 @@
+frappe.provide("frappe.treeview_settings");
+
+frappe.treeview_settings["Quality Procedure"] = {
+ ignore_fields:["parent_quality_procedure"],
+ get_tree_nodes: 'erpnext.quality_management.doctype.quality_procedure.quality_procedure.get_children',
+ add_tree_node: 'erpnext.quality_management.doctype.quality_procedure.quality_procedure.add_node',
+ filters: [
+ {
+ fieldname: "Quality Procedure",
+ fieldtype:"Link",
+ options: "Quality Procedure",
+ label: __("Quality Procedure"),
+ get_query: function() {
+ return {
+ filters: [["Quality Procedure", 'is_group', '=', 1]]
+ };
+ }
+ },
+ ],
+ breadcrumb: "Setup",
+ root_label: "All Quality Procedures",
+ get_tree_root: false,
+ menu_items: [
+ {
+ label: __("New Quality Procedure"),
+ action: function() {
+ frappe.new_doc("Quality Procedure", true);
+ },
+ condition: 'frappe.boot.user.can_create.indexOf("Quality Procedure") !== -1'
+ }
+ ],
+ onload: function(treeview) {
+ treeview.make_tree();
+ },
+ onrender: function() {
+ $("button:contains('Add Child')").remove();
+ $("button:contains('New')").remove();
+ }
+};
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.js b/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.js
new file mode 100644
index 0000000..0a187eb
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Quality Procedure", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Quality Procedure
+ () => frappe.tests.make('Quality Procedure', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.py b/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.py
new file mode 100644
index 0000000..af7adec
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_procedure/test_quality_procedure.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+
+class TestQualityProcedure(unittest.TestCase):
+ def test_quality_procedure(self):
+ test_create_procedure = create_procedure()
+ test_create_nested_procedure = create_nested_procedure()
+ test_get_procedure, test_get_nested_procedure = get_procedure()
+ self.assertEquals(test_create_procedure, test_get_procedure.name)
+ self.assertEquals(test_create_nested_procedure, test_get_nested_procedure.name)
+ self.assertEquals(test_get_nested_procedure.name, test_get_procedure.parent_quality_procedure)
+
+def create_procedure():
+ procedure = frappe.get_doc({
+ "doctype": "Quality Procedure",
+ "procedure": "_Test Quality Procedure",
+ "procedure_step": [
+ {
+ "procedure": "Step",
+ "step": "_Test Quality Procedure Table",
+ }
+ ]
+ })
+ procedure_exist = frappe.db.exists("Quality Procedure",""+ procedure.procedure +"")
+ if not procedure_exist:
+ procedure.insert()
+ return procedure.procedure
+ else:
+ return procedure_exist
+
+def create_nested_procedure():
+ nested_procedure = frappe.get_doc({
+ "doctype": "Quality Procedure",
+ "procedure": "_Test Nested Quality Procedure",
+ "procedure_step": [
+ {
+ "procedure": "Procedure",
+ "procedure_name": "_Test Quality Procedure",
+ }
+ ]
+ })
+ nested_procedure_exist = frappe.db.exists("Quality Procedure",""+ nested_procedure.procedure +"")
+ if not nested_procedure_exist:
+ nested_procedure.insert()
+ return nested_procedure.procedure
+ else:
+ return nested_procedure_exist
+
+def get_procedure():
+ procedure = frappe.get_all("Quality Procedure", filters={"procedure": "_Test Quality Procedure"}, fields=["name", "parent_quality_procedure"], limit=1)
+ nested_procedure = frappe.get_all("Quality Procedure", filters={"procedure": "_Test Nested Quality Procedure"}, fields=["name", "parent_quality_procedure"], limit=1)
+ return procedure[0], nested_procedure[0]
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_procedure_table/__init__.py b/erpnext/quality_management/doctype/quality_procedure_table/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_procedure_table/__init__.py
diff --git a/erpnext/quality_management/doctype/quality_procedure_table/quality_procedure_table.json b/erpnext/quality_management/doctype/quality_procedure_table/quality_procedure_table.json
new file mode 100644
index 0000000..965edbc
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_procedure_table/quality_procedure_table.json
@@ -0,0 +1,176 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2018-10-17 15:48:57.617831",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 0,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "procedure",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Procedure",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Step\nProcedure",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.procedure == \"Procedure\"",
+ "fieldname": "procedure_name",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Procedure",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Quality Procedure",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.procedure == \"Step\"",
+ "fieldname": "step",
+ "fieldtype": "Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Step",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "responsible_individual",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Responsible Individual",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Role",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2018-11-01 14:26:33.558345",
+ "modified_by": "Administrator",
+ "module": "Quality Management",
+ "name": "Quality Procedure Table",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_procedure_table/quality_procedure_table.py b/erpnext/quality_management/doctype/quality_procedure_table/quality_procedure_table.py
new file mode 100644
index 0000000..6fe927a
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_procedure_table/quality_procedure_table.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class QualityProcedureTable(Document):
+ pass
diff --git a/erpnext/quality_management/doctype/quality_review/__init__.py b/erpnext/quality_management/doctype/quality_review/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_review/__init__.py
diff --git a/erpnext/quality_management/doctype/quality_review/quality_review.js b/erpnext/quality_management/doctype/quality_review/quality_review.js
new file mode 100644
index 0000000..48b5c88
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_review/quality_review.js
@@ -0,0 +1,72 @@
+// Copyright (c) 2018, Frappe and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Quality Review', {
+ onload: function(frm){
+ frm.set_value("date", frappe.datetime.get_today());
+ $(".grid-add-row").hide();
+ if(frm.doc.measurable == "Yes"){
+ show_target_achieved_unit(frm);
+ }
+ else{
+ hide_target_achieved_unit(frm);
+ }
+ frm.refresh();
+ },
+ goal: function(frm) {
+ frm.fields_dict.values.grid.remove_all();
+ if (frm.doc.goal){
+ frappe.call({
+ "method": "frappe.client.get",
+ args: {
+ doctype: "Quality Goal",
+ name: frm.doc.goal
+ },
+ callback: function (data) {
+ for (var i = 0; i < data.message.objective.length; i++ ){
+ frm.add_child("values");
+ frm.fields_dict.values.get_value()[i].objective = data.message.objective[i].objective;
+ if(frm.doc.measurable == "Yes"){
+ if(i < 1){
+ show_target_achieved_unit(frm);
+ }
+ frm.fields_dict.values.get_value()[i].target = data.message.objective[i].target;
+ frm.fields_dict.values.get_value()[i].achieved = 0;
+ frm.fields_dict.values.get_value()[i].unit = data.message.objective[i].unit;
+ }
+ if(frm.doc.measurable == "No"){
+ if(i < 1){
+ hide_target_achieved_unit(frm);
+ }
+ frm.fields_dict.values.get_value()[i].yes_no = "No";
+ }
+ }
+ frm.refresh();
+ }
+ });
+ }
+ else{
+ frm.doc.procedure = '';
+ frm.doc.scope = '';
+ frm.doc.action = '';
+ frm.doc.measurable = '';
+ frm.refresh();
+ }
+ },
+});
+
+function show_target_achieved_unit(frm){
+ // shows target, achieved and unit columns as the goal can be measured in numeric values
+ frm.fields_dict.values.grid.docfields[1].hidden = 0;
+ frm.fields_dict.values.grid.docfields[2].hidden = 0;
+ frm.fields_dict.values.grid.docfields[3].hidden = 0;
+ frm.fields_dict.values.grid.docfields[4].hidden = 1;
+}
+
+function hide_target_achieved_unit(frm){
+ // hides target and unit columns as the goal cannot be measured in numeric values
+ frm.fields_dict.values.grid.docfields[1].hidden = 1;
+ frm.fields_dict.values.grid.docfields[2].hidden = 1;
+ frm.fields_dict.values.grid.docfields[3].hidden = 1;
+ frm.fields_dict.values.grid.docfields[4].hidden = 0;
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_review/quality_review.json b/erpnext/quality_management/doctype/quality_review/quality_review.json
new file mode 100644
index 0000000..689c1c5
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_review/quality_review.json
@@ -0,0 +1,424 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "autoname": "QMS-REV-.#####",
+ "beta": 0,
+ "creation": "2018-10-02 11:45:16.301955",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "",
+ "fieldname": "goal",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Quality Goal",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Quality Goal",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "date",
+ "fieldtype": "Date",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Evaluation Date",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "goal.measurable",
+ "fieldname": "measurable",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Measurable Goal",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_4",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "goal.procedure",
+ "fieldname": "procedure",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Procedure",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Quality Procedure",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "goal.scope",
+ "fieldname": "scope",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Scope",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "depends_on": "eval:doc.scope == 'Department'",
+ "fetch_from": "goal.department",
+ "fieldname": "department",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Department",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "values_section",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Values",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "values",
+ "fieldtype": "Table",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Values",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Quality Review Table",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 1,
+ "columns": 0,
+ "fieldname": "additional_info_section",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Additional Information",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "additional_information",
+ "fieldtype": "Text",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Additional Information",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 0,
+ "max_attachments": 0,
+ "modified": "2018-11-12 14:25:02.383387",
+ "modified_by": "Administrator",
+ "module": "Quality Management",
+ "name": "Quality Review",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "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": "System Manager",
+ "set_user_permissions": 0,
+ "share": 1,
+ "submit": 0,
+ "write": 1
+ }
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_review/quality_review.py b/erpnext/quality_management/doctype/quality_review/quality_review.py
new file mode 100644
index 0000000..8a28335
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_review/quality_review.py
@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+import datetime
+class QualityReview(Document):
+ pass
+
+def review():
+ now = datetime.datetime.now()
+ day = now.day
+ day_name = now.strftime("%A")
+ month=now.strftime("%B")
+
+ for data in frappe.get_all("Quality Goal",fields=['name', 'frequency', 'date', 'weekly', 'measurable']):
+ if data.frequency == 'Daily':
+ create_review(data.name, data.measurable)
+
+ elif data.frequency == 'Weekly':
+ if data.weekly == day_name:
+ create_review(data.name, data.measurable)
+
+ elif data.frequency == 'Monthly':
+ if data.date == str(day):
+ create_review(data.name, data.measurable)
+
+ elif data.frequency == 'Quarterly':
+ if (month == 'January' or month == 'April' or month == 'July' or month == 'October') and str(day) == data.date:
+ create_review(data.name, data.measurable)
+
+ elif data.frequency == 'Half Yearly':
+ if (month == 'January' or month == 'July') and str(day) == data.date:
+ create_review(data.name, data.measurable)
+
+ elif data.frequency == 'Yearly':
+ if month == data.yearly and str(day) == data.date:
+ create_review(data.name, data.measurable)
+
+ else:
+ pass
+
+def create_review(name, measurable):
+ objectives = frappe.get_all("Quality Objective", filters={'parent': name }, fields=['objective', 'target', 'unit'])
+ doc = frappe.get_doc({
+ "doctype": "Quality Review",
+ "goal": name,
+ "date": frappe.as_unicode(frappe.utils.nowdate()),
+ "measurable": measurable,
+ })
+ if measurable == 'Yes':
+ for objective in objectives:
+ doc.append("values",{
+ 'objective': objective.objective,
+ 'target': objective.target,
+ 'achieved': 0,
+ 'unit': objective.unit
+ })
+ else:
+ for objective in objectives:
+ doc.append("values",{
+ 'objective': objective.objective,
+ })
+ doc.insert()
+ frappe.db.commit()
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_review/quality_review_dashboard.py b/erpnext/quality_management/doctype/quality_review/quality_review_dashboard.py
new file mode 100644
index 0000000..85e4ccc
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_review/quality_review_dashboard.py
@@ -0,0 +1,16 @@
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'review',
+ 'transactions': [
+ {
+ 'label': _('Action'),
+ 'items': ['Quality Action']
+ },
+ {
+ 'label': _('Meeting'),
+ 'items': ['Quality Meeting']
+ }
+ ],
+ }
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_review/quality_review_list.js b/erpnext/quality_management/doctype/quality_review/quality_review_list.js
new file mode 100644
index 0000000..e2eb31b
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_review/quality_review_list.js
@@ -0,0 +1,12 @@
+frappe.listview_settings['Quality Review'] = {
+ add_fields: ["action"],
+ get_indicator: function(doc)
+ {
+ if(doc.action == "No Action") {
+ return [__("No Action"), "green", "action,=,No Action"];
+ }
+ else if(doc.action == "Action Initialised") {
+ return [__("Action Initialised"), "red", "action,=,Action Initialised"];
+ }
+ }
+};
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_review/test_quality_review.js b/erpnext/quality_management/doctype/quality_review/test_quality_review.js
new file mode 100644
index 0000000..cf910b2
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_review/test_quality_review.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// rename this file from _test_[name] to test_[name] to activate
+// and remove above this line
+
+QUnit.test("test: Performance Monitoring", function (assert) {
+ let done = assert.async();
+
+ // number of asserts
+ assert.expect(1);
+
+ frappe.run_serially([
+ // insert a new Performance Monitoring
+ () => frappe.tests.make('Performance Monitoring', [
+ // values to be set
+ {key: 'value'}
+ ]),
+ () => {
+ assert.equal(cur_frm.doc.key, 'value');
+ },
+ () => done()
+ ]);
+
+});
diff --git a/erpnext/quality_management/doctype/quality_review/test_quality_review.py b/erpnext/quality_management/doctype/quality_review/test_quality_review.py
new file mode 100644
index 0000000..421d20d
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_review/test_quality_review.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and Contributors
+# See license.txt
+from __future__ import unicode_literals
+
+import frappe
+import unittest
+from erpnext.quality_management.doctype.quality_procedure.test_quality_procedure import create_procedure
+from erpnext.quality_management.doctype.quality_goal.test_quality_goal import create_unit
+from erpnext.quality_management.doctype.quality_goal.test_quality_goal import create_goal
+
+class TestQualityReview(unittest.TestCase):
+
+ def test_quality_review(self):
+ create_procedure()
+ create_unit()
+ create_goal()
+ test_create_review = create_review()
+ test_get_review = get_review()
+ self.assertEquals(test_create_review.name, test_get_review.name)
+
+def create_review():
+ review = frappe.get_doc({
+ "doctype": "Quality Review",
+ "goal": "_Test Quality Goal",
+ "procedure": "_Test Quality Procedure",
+ "scope": "Company",
+ "date": ""+ frappe.utils.nowdate() +"",
+ "values": [
+ {
+ "objective": "_Test Quality Objective",
+ "target": "100",
+ "achieved": "100",
+ "unit": "_Test UOM"
+ }
+ ]
+ })
+ review_exist = frappe.get_list("Quality Review", filters={"goal": "_Test Quality Goal"}, limit=1)
+ if len(review_exist) == 0:
+ review.insert()
+ return review
+ else:
+ return review_exist[0]
+
+def get_review():
+ review = frappe.get_list("Quality Review", filters={"goal": "_Test Quality Goal"}, limit=1)
+ return review[0]
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_review_table/__init__.py b/erpnext/quality_management/doctype/quality_review_table/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_review_table/__init__.py
diff --git a/erpnext/quality_management/doctype/quality_review_table/quality_review_table.json b/erpnext/quality_management/doctype/quality_review_table/quality_review_table.json
new file mode 100644
index 0000000..442c4c6
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_review_table/quality_review_table.json
@@ -0,0 +1,207 @@
+{
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2018-10-09 13:03:37.666929",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "fields": [
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "objective",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "objective",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "target",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Target",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "",
+ "fieldname": "achieved",
+ "fieldtype": "Int",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Achieved",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fetch_from": "target_unit",
+ "fieldname": "unit",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Unit",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "",
+ "fieldname": "yes_no",
+ "fieldtype": "Select",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Yes/No",
+ "length": 0,
+ "no_copy": 0,
+ "options": "No\nYes",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ }
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2018-11-03 11:10:53.818818",
+ "modified_by": "Administrator",
+ "module": "Quality Management",
+ "name": "Quality Review Table",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
+ "track_views": 0
+}
\ No newline at end of file
diff --git a/erpnext/quality_management/doctype/quality_review_table/quality_review_table.py b/erpnext/quality_management/doctype/quality_review_table/quality_review_table.py
new file mode 100644
index 0000000..5760cbc
--- /dev/null
+++ b/erpnext/quality_management/doctype/quality_review_table/quality_review_table.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2018, Frappe and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+from frappe.model.document import Document
+
+class QualityReviewTable(Document):
+ pass
diff --git a/erpnext/quality_management/report/__init__.py b/erpnext/quality_management/report/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/report/__init__.py
diff --git a/erpnext/quality_management/report/review/__init__.py b/erpnext/quality_management/report/review/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/quality_management/report/review/__init__.py
diff --git a/erpnext/quality_management/report/review/review.json b/erpnext/quality_management/report/review/review.json
new file mode 100644
index 0000000..7fce2d4
--- /dev/null
+++ b/erpnext/quality_management/report/review/review.json
@@ -0,0 +1,24 @@
+{
+ "add_total_row": 0,
+ "creation": "2018-10-16 12:28:43.651915",
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2018-10-16 15:23:25.667237",
+ "modified_by": "Administrator",
+ "module": "Quality Management",
+ "name": "Review",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "query": "SELECT\n `tabQuality Action`.name as \"Name:Data:200\",\n `tabQuality Action`.action as \"Action:Select/[corrective,Preventive]:200\",\n `tabQuality Action`.review as \"Review:Link/Quality Review:200\",\n `tabQuality Action`.date as \"Date:Date:120\",\n `tabQuality Action`.status as \"Status:Select/Planned:150\"\nFROM\n `tabQuality Action`\nWHERE\n `tabQuality Action`.type='Quality Review'\n \n ",
+ "ref_doctype": "Quality Action",
+ "report_name": "Review",
+ "report_type": "Query Report",
+ "roles": [
+ {
+ "role": "System Manager"
+ }
+ ]
+}
\ No newline at end of file
diff --git "a/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.js" "b/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.js"
index 8606a3b..a4c7640 100644
--- "a/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.js"
+++ "b/erpnext/regional/report/fichier_des_ecritures_comptables_\133fec\135/fichier_des_ecritures_comptables_\133fec\135.js"
@@ -1,85 +1,75 @@
-// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
-/* eslint-disable */
frappe.query_reports["Fichier des Ecritures Comptables [FEC]"] = {
- "filters": [{
- "fieldname": "company",
- "label": __("Company"),
- "fieldtype": "Link",
- "options": "Company",
- "default": frappe.defaults.get_user_default("Company"),
- "reqd": 1
- },
- {
- "fieldname": "fiscal_year",
- "label": __("Fiscal Year"),
- "fieldtype": "Link",
- "options": "Fiscal Year",
- "default": frappe.defaults.get_user_default("fiscal_year"),
- "reqd": 1
- }],
-
+ "filters": [
+ {
+ "fieldname": "company",
+ "label": __("Company"),
+ "fieldtype": "Link",
+ "options": "Company",
+ "default": frappe.defaults.get_user_default("Company"),
+ "reqd": 1
+ },
+ {
+ "fieldname": "fiscal_year",
+ "label": __("Fiscal Year"),
+ "fieldtype": "Link",
+ "options": "Fiscal Year",
+ "default": frappe.defaults.get_user_default("fiscal_year"),
+ "reqd": 1
+ }
+ ],
onload: function(query_report) {
query_report.page.add_inner_button(__("Export"), function() {
- var fiscal_year = query_report.get_values().fiscal_year;
- var company = query_report.get_values().company;
+ fec_export(query_report);
+ });
- frappe.call({
- method: "frappe.client.get_value",
- args: {
- 'doctype': "Company",
- 'fieldname': ['siren_number'],
- 'filters': {
- 'name': company
- }
- },
- callback: function(data) {
- var company_data = data.message.siren_number;
- if (company_data === null || company_data === undefined) {
- frappe.msgprint(__("Please register the SIREN number in the company information file"))
- } else {
- frappe.call({
- method: "frappe.client.get_value",
- args: {
- 'doctype': "Fiscal Year",
- 'fieldname': ['year_end_date'],
- 'filters': {
- 'name': fiscal_year
- }
- },
- callback: function(data) {
- var fy = data.message.year_end_date;
- var title = company_data + "FEC" + moment(fy).format('YYYYMMDD');
- var result = $.map(frappe.slickgrid_tools.get_view_data(query_report.columns, query_report.dataView),
- function(row) {
- return [row.splice(1)];
- });
- downloadify(result, null, title);
- }
- });
+ query_report.add_make_chart_button = function() {
+ //
+ };
- }
- }
+ query_report.export_report = function() {
+ fec_export(query_report);
+ };
+ }
+};
+
+let fec_export = function(query_report) {
+ const fiscal_year = query_report.get_values().fiscal_year;
+ const company = query_report.get_values().company;
+
+ frappe.db.get_value("Company", company, "siren_number", (value) => {
+ const company_data = value.siren_number;
+ if (company_data === null || company_data === undefined) {
+ frappe.msgprint(__("Please register the SIREN number in the company information file"));
+ } else {
+ frappe.db.get_value("Fiscal Year", fiscal_year, "year_end_date", (r) => {
+ const fy = r.year_end_date;
+ const title = company_data + "FEC" + moment(fy).format('YYYYMMDD');
+ const column_row = query_report.columns.map(col => col.label);
+ const column_data = query_report.get_data_for_csv(false);
+ const result = [column_row].concat(column_data);
+ downloadify(result, null, title);
});
- });
- }
-}
+ }
+ });
+};
-var downloadify = function(data, roles, title) {
+let downloadify = function(data, roles, title) {
if (roles && roles.length && !has_common(roles, roles)) {
frappe.msgprint(__("Export not allowed. You need {0} role to export.", [frappe.utils.comma_or(roles)]));
return;
}
- var filename = title + ".csv";
- var csv_data = to_tab_csv(data);
- var a = document.createElement('a');
+ const filename = title + ".txt";
+ let csv_data = to_tab_csv(data);
+ const a = document.createElement('a');
if ("download" in a) {
// Used Blob object, because it can handle large files
- var blob_object = new Blob([csv_data], {
+ let blob_object = new Blob([csv_data], {
type: 'text/csv;charset=UTF-8'
});
a.href = URL.createObjectURL(blob_object);
@@ -98,8 +88,8 @@
document.body.removeChild(a);
};
-var to_tab_csv = function(data) {
- var res = [];
+let to_tab_csv = function(data) {
+ let res = [];
$.each(data, function(i, row) {
res.push(row.join("\t"));
});
diff --git a/erpnext/selling/README.md b/erpnext/selling/README.md
index db05132..d186133 100644
--- a/erpnext/selling/README.md
+++ b/erpnext/selling/README.md
@@ -1,6 +1,11 @@
-Selling management module. Includes forms for capturing / managing the sales process.
+Selling management module. Includes forms for capturing / managing the sales process:
+
+- Customer
+- Campaign
+- Quotation
+- Sales Order
+
+Moved to CRM Module:
- Lead
- Opportunity
-- Quotation
-- Sales Order
\ No newline at end of file
diff --git a/erpnext/selling/doctype/quotation_item/quotation_item.json b/erpnext/selling/doctype/quotation_item/quotation_item.json
index 3b1c480..7ea8397 100644
--- a/erpnext/selling/doctype/quotation_item/quotation_item.json
+++ b/erpnext/selling/doctype/quotation_item/quotation_item.json
@@ -871,10 +871,12 @@
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -993,6 +995,7 @@
"label": "Net Rate",
"length": 0,
"no_copy": 0,
+ "options": "currency",
"permlevel": 0,
"precision": "",
"print_hide": 1,
@@ -1910,7 +1913,7 @@
"istable": 1,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2018-08-22 16:15:52.750381",
+ "modified": "2018-12-12 05:52:46.135944",
"modified_by": "Administrator",
"module": "Selling",
"name": "Quotation Item",
@@ -1925,4 +1928,4 @@
"track_changes": 1,
"track_seen": 0,
"track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index dd6eed8..1428ba4 100755
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -620,7 +620,7 @@
def update_item(source, target, source_parent):
target.amount = flt(source.amount) - flt(source.billed_amt)
target.base_amount = target.amount * flt(source_parent.conversion_rate)
- target.qty = target.amount / flt(source.rate) if (source.rate and source.billed_amt) else source.qty
+ target.qty = target.amount / flt(source.rate) if (source.rate and source.billed_amt) else source.qty - source.returned_qty
if source_parent.project:
target.cost_center = frappe.db.get_value("Project", source_parent.project, "cost_center")
diff --git a/erpnext/selling/page/point_of_sale/point_of_sale.js b/erpnext/selling/page/point_of_sale/point_of_sale.js
index a6f7a28..1ee5971 100644
--- a/erpnext/selling/page/point_of_sale/point_of_sale.js
+++ b/erpnext/selling/page/point_of_sale/point_of_sale.js
@@ -394,7 +394,7 @@
}
}
- frappe.prompt(this.get_promopt_fields(),
+ frappe.prompt(this.get_prompt_fields(),
on_submit,
__('Select POS Profile')
);
@@ -417,11 +417,12 @@
]);
}
- get_promopt_fields() {
+ get_prompt_fields() {
return [{
fieldtype: 'Link',
label: __('POS Profile'),
options: 'POS Profile',
+ fieldname: 'pos_profile',
reqd: 1,
get_query: () => {
return {
@@ -433,7 +434,8 @@
}
}, {
fieldtype: 'Check',
- label: __('Set as default')
+ label: __('Set as default'),
+ fieldname: 'set_as_default'
}];
}
@@ -522,6 +524,7 @@
this.frm.meta.default_print_format = r.message.print_format || "";
this.frm.allow_edit_rate = r.message.allow_edit_rate;
this.frm.allow_edit_discount = r.message.allow_edit_discount;
+ this.frm.doc.campaign = r.message.campaign;
}
}
@@ -1128,12 +1131,15 @@
this.events = events;
this.currency = this.frm.doc.currency;
- this.make_dom();
- this.make_fields();
+ frappe.db.get_value("Item Group", {lft: 1, is_group: 1}, "name", (r) => {
+ this.parent_item_group = r.name;
+ this.make_dom();
+ this.make_fields();
- this.init_clusterize();
- this.bind_events();
- this.load_items_data();
+ this.init_clusterize();
+ this.bind_events();
+ this.load_items_data();
+ })
}
load_items_data() {
@@ -1175,6 +1181,7 @@
make_fields() {
// Search field
+ const me = this;
this.search_field = frappe.ui.form.make_control({
df: {
fieldtype: 'Data',
@@ -1202,7 +1209,7 @@
fieldtype: 'Link',
label: 'Item Group',
options: 'Item Group',
- default: 'All Item Groups',
+ default: me.parent_item_group,
onchange: () => {
const item_group = this.item_group_field.get_value();
if (item_group) {
@@ -1258,7 +1265,7 @@
this.clusterize.update(row_items);
}
- filter_items({ search_term='', item_group='All Item Groups' }={}) {
+ filter_items({ search_term='', item_group=this.parent_item_group }={}) {
if (search_term) {
search_term = search_term.toLowerCase();
@@ -1271,7 +1278,7 @@
this.set_item_in_the_cart(items);
return;
}
- } else if (item_group == "All Item Groups") {
+ } else if (item_group == this.parent_item_group) {
this.items = this.all_items;
return this.render_items(this.all_items);
}
@@ -1376,7 +1383,7 @@
return template;
}
- get_items({start = 0, page_length = 40, search_value='', item_group="All Item Groups"}={}) {
+ get_items({start = 0, page_length = 40, search_value='', item_group=this.parent_item_group}={}) {
return new Promise(res => {
frappe.call({
method: "erpnext.selling.page.point_of_sale.point_of_sale.get_items",
diff --git a/erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.js b/erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.js
new file mode 100644
index 0000000..37634ef
--- /dev/null
+++ b/erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.js
@@ -0,0 +1,6 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Pending SO Items For Purchase Request"] = {
+}
diff --git a/erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.json b/erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.json
index 128544b..3cf3235 100644
--- a/erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.json
+++ b/erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.json
@@ -1,36 +1,35 @@
{
- "add_total_row": 0,
- "apply_user_permissions": 1,
- "creation": "2013-06-21 16:46:45",
- "disabled": 0,
- "docstatus": 0,
- "doctype": "Report",
- "idx": 3,
- "is_standard": "Yes",
- "modified": "2017-02-24 20:08:11.744036",
- "modified_by": "Administrator",
- "module": "Selling",
- "name": "Pending SO Items For Purchase Request",
- "owner": "Administrator",
- "query": "select so_item.item_code as \"Item Code:Link/Item:120\",\n so_item.item_name as \"Item Name::120\",\n so_item.description as \"Description::120\",\n so.`name` as \"S.O. No.:Link/Sales Order:120\",\n so.`transaction_date` as \"Date:Date:120\",\n mr.name as \"Material Request:Link/Material Request:120\",\n so.customer as \"Customer:Link/Customer:120\",\n so.territory as \"Terretory:Link/Territory:120\",\n sum(so_item.qty) as \"SO Qty:Float:100 \",\n sum(mr_item.qty) as \"Requested Qty:Float:100\",\n sum(so_item.qty) - sum(mr_item.qty) as \"Pending Qty:Float:100 \", \n so.company as \"Company:Link/Company:\"\nfrom\n `tabSales Order` so, `tabSales Order Item` so_item, \n `tabMaterial Request` mr, `tabMaterial Request Item` mr_item\nwhere \n so_item.`parent` = so.`name` \n and mr_item.parent = mr.name\n and mr_item.sales_order = so.name\n and mr_item.item_code = so_item.item_code\n and so.docstatus = 1 and so.status != \"Closed\" \n and mr.docstatus = 1 and mr.status != \"Stopped\"\ngroup by so.name, so_item.item_code\nhaving sum(so_item.qty) > sum(mr_item.qty)\norder by so.name desc, so_item.item_code asc",
- "ref_doctype": "Sales Order",
- "report_name": "Pending SO Items For Purchase Request",
- "report_type": "Query Report",
+ "add_total_row": 0,
+ "creation": "2018-11-12 14:08:27.241332",
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2018-11-12 14:08:27.241332",
+ "modified_by": "Administrator",
+ "module": "Selling",
+ "name": "Pending SO Items For Purchase Request",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "Sales Order",
+ "report_name": "Pending SO Items For Purchase Request",
+ "report_type": "Script Report",
"roles": [
{
- "role": "Sales User"
- },
+ "role": "Stock User"
+ },
{
"role": "Sales Manager"
- },
+ },
{
"role": "Maintenance User"
- },
+ },
{
"role": "Accounts User"
- },
+ },
{
- "role": "Stock User"
+ "role": "Sales User"
}
]
}
\ No newline at end of file
diff --git a/erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.py b/erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.py
new file mode 100644
index 0000000..8721651
--- /dev/null
+++ b/erpnext/selling/report/pending_so_items_for_purchase_request/pending_so_items_for_purchase_request.py
@@ -0,0 +1,148 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe import _
+from frappe.utils import cint,cstr
+
+def execute(filters=None):
+ columns = get_columns()
+ data = get_data()
+ return columns, data
+
+def get_columns():
+ columns = [
+ {
+ "label": _("Item Code"),
+ "options": "Item",
+ "fieldname": "item_code",
+ "fieldtype": "Link",
+ "width": 200
+ },
+ {
+ "label": _("Item Name"),
+ "fieldname": "item_name",
+ "fieldtype": "Data",
+ "width": 200
+ },
+ {
+ "label": _("Description"),
+ "fieldname": "description",
+ "fieldtype": "Data",
+ "width": 140
+ },
+ {
+ "label": _("S.O. No."),
+ "options": "Sales Order",
+ "fieldname": "sales_order_no",
+ "fieldtype": "Link",
+ "width": 140
+ },
+ {
+ "label": _("Date"),
+ "fieldname": "date",
+ "fieldtype": "Date",
+ "width": 140
+ },
+ {
+ "label": _("Material Request"),
+ "options": "Material Request",
+ "fieldname": "material_request",
+ "fieldtype": "Link",
+ "width": 140
+ },
+ {
+ "label": _("Customer"),
+ "fieldname": "customer",
+ "fieldtype": "Data",
+ "width": 140
+ },
+ {
+ "label": _("Territory"),
+ "fieldname": "territory",
+ "fieldtype": "Data",
+ "width": 140
+ },
+ {
+ "label": _("SO Qty"),
+ "fieldname": "so_qty",
+ "fieldtype": "Float",
+ "width": 140
+ },
+ {
+ "label": _("Requested Qty"),
+ "fieldname": "requested_qty",
+ "fieldtype": "Float",
+ "width": 140
+ },
+ {
+ "label": _("Pending Qty"),
+ "fieldname": "pending_qty",
+ "fieldtype": "Float",
+ "width": 140
+ },
+ {
+ "label": _("Company"),
+ "fieldname": "company",
+ "fieldtype": "Data",
+ "width": 140
+ }
+ ]
+ return columns
+
+def get_data():
+ sales_order_entry = frappe.db.sql("""
+ SELECT
+ so_item.item_code,
+ so_item.item_name,
+ so_item.description,
+ so.name,
+ so.transaction_date,
+ so.customer,
+ so.territory,
+ sum(so_item.qty) as net_qty,
+ so.company
+ FROM `tabSales Order` so, `tabSales Order Item` so_item
+ WHERE
+ so.docstatus = 1
+ and so.name = so_item.parent
+ and so.status not in ("Closed","Completed","Cancelled")
+ GROUP BY
+ so.name,so_item.item_code
+ """, as_dict = 1)
+
+ mr_records = frappe.get_all("Material Request Item",
+ {"sales_order_item": ("!=",""), "docstatus": 1},
+ ["parent", "qty", "sales_order", "item_code"])
+
+ grouped_records = {}
+
+ for record in mr_records:
+ grouped_records.setdefault(record.sales_order, []).append(record)
+
+ pending_so=[]
+ for so in sales_order_entry:
+ # fetch all the material request records for a sales order item
+ mr_list = grouped_records.get(so.name) or [{}]
+ mr_item_record = ([mr for mr in mr_list if mr.get('item_code') == so.item_code] or [{}])
+
+ for mr in mr_item_record:
+ # check for pending sales order
+ if cint(so.net_qty) > cint(mr.get('qty')):
+ so_record = {
+ "item_code": so.item_code,
+ "item_name": so.item_name,
+ "description": so.description,
+ "sales_order_no": so.name,
+ "date": so.transaction_date,
+ "material_request": cstr(mr.get('parent')),
+ "customer": so.customer,
+ "territory": so.territory,
+ "so_qty": so.net_qty,
+ "requested_qty": cint(mr.get('qty')),
+ "pending_qty": so.net_qty - cint(mr.get('qty')),
+ "company": so.company
+ }
+ pending_so.append(so_record)
+ return pending_so
\ No newline at end of file
diff --git a/erpnext/selling/report/pending_so_items_for_purchase_request/test_pending_so_items_for_purchase_request.py b/erpnext/selling/report/pending_so_items_for_purchase_request/test_pending_so_items_for_purchase_request.py
new file mode 100644
index 0000000..f2b7701
--- /dev/null
+++ b/erpnext/selling/report/pending_so_items_for_purchase_request/test_pending_so_items_for_purchase_request.py
@@ -0,0 +1,27 @@
+# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
+# For license information, please see license.txt
+
+import unittest
+from frappe.utils import nowdate, add_months
+from erpnext.selling.report.pending_so_items_for_purchase_request.pending_so_items_for_purchase_request\
+ import execute
+from erpnext.selling.doctype.sales_order.sales_order import make_material_request
+from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
+
+
+class TestPendingSOItemsForPurchaseRequest(unittest.TestCase):
+ def test_result_for_partial_material_request(self):
+ so = make_sales_order()
+ mr=make_material_request(so.name)
+ mr.items[0].qty = 4
+ mr.schedule_date = add_months(nowdate(),1)
+ mr.submit()
+ report = execute()
+ l = len(report[1])
+ self.assertEqual((so.items[0].qty - mr.items[0].qty), report[1][l-1]['pending_qty'])
+
+ def test_result_for_so_item(self):
+ so = make_sales_order()
+ report = execute()
+ l = len(report[1])
+ self.assertEqual(so.items[0].qty, report[1][l-1]['pending_qty'])
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.py b/erpnext/stock/doctype/delivery_note/delivery_note.py
index 4affad8..de6ebb3 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.py
@@ -394,8 +394,24 @@
return invoiced_qty_map
+def get_returned_qty_map(sales_orders):
+ """returns a map: {so_detail: returned_qty}"""
+ returned_qty_map = {}
+
+ for name, returned_qty in frappe.get_all('Sales Order Item', fields = ["name", "returned_qty"],
+ filters = {'parent': ('in', sales_orders), 'docstatus': 1}, as_list=1):
+ if not returned_qty_map.get(name):
+ returned_qty_map[name] = 0
+ returned_qty_map[name] += returned_qty
+
+ return returned_qty_map
+
@frappe.whitelist()
def make_sales_invoice(source_name, target_doc=None):
+ doc = frappe.get_doc('Delivery Note', source_name)
+ sales_orders = [d.against_sales_order for d in doc.items]
+ returned_qty_map = get_returned_qty_map(sales_orders)
+
invoiced_qty_map = get_invoiced_qty_map(source_name)
def set_missing_values(source, target):
@@ -415,7 +431,9 @@
target.update(get_fetch_values("Sales Invoice", 'company_address', target.company_address))
def update_item(source_doc, target_doc, source_parent):
- target_doc.qty = source_doc.qty - invoiced_qty_map.get(source_doc.name, 0)
+ target_doc.qty = (source_doc.qty -
+ invoiced_qty_map.get(source_doc.name, 0) - returned_qty_map.get(source_doc.so_detail, 0))
+
if source_doc.serial_no and source_parent.per_billed > 0:
target_doc.serial_no = get_delivery_note_serial_no(source_doc.item_code,
target_doc.qty, source_parent.name)
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note_list.js b/erpnext/stock/doctype/delivery_note/delivery_note_list.js
index 6a50c5a..6fc51ec 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note_list.js
+++ b/erpnext/stock/doctype/delivery_note/delivery_note_list.js
@@ -1,7 +1,8 @@
frappe.listview_settings['Delivery Note'] = {
- add_fields: ["grand_total", "is_return", "per_billed", "status", "currency"],
- get_indicator: function (doc) {
- if (cint(doc.is_return) == 1) {
+ add_fields: ["customer", "customer_name", "base_grand_total", "per_installed", "per_billed",
+ "transporter_name", "grand_total", "is_return", "status", "currency"],
+ get_indicator: function(doc) {
+ if(cint(doc.is_return)==1) {
return [__("Return"), "darkgrey", "is_return,=,Yes"];
} else if (doc.status === "Closed") {
return [__("Closed"), "green", "status,=,Closed"];
diff --git a/erpnext/stock/doctype/delivery_note/test_delivery_note.py b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
index 026d83c..0c5a71c 100644
--- a/erpnext/stock/doctype/delivery_note/test_delivery_note.py
+++ b/erpnext/stock/doctype/delivery_note/test_delivery_note.py
@@ -636,6 +636,24 @@
self.assertEqual(expected_values[gle.account]["cost_center"], gle.cost_center)
set_perpetual_inventory(0, company)
+
+ def test_make_sales_invoice_from_dn_for_returned_qty(self):
+ from erpnext.selling.doctype.sales_order.sales_order import make_delivery_note
+ from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
+
+ so = make_sales_order(qty=2)
+ so.submit()
+
+ dn = make_delivery_note(so.name)
+ dn.submit()
+
+ dn1 = create_delivery_note(is_return=1, return_against=dn.name, qty=-1, do_not_submit=True)
+ dn1.items[0].against_sales_order = so.name
+ dn1.items[0].so_detail = so.items[0].name
+ dn1.submit()
+
+ si = make_sales_invoice(dn.name)
+ self.assertEquals(si.items[0].qty, 1)
def create_delivery_note(**args):
dn = frappe.new_doc("Delivery Note")
diff --git a/erpnext/stock/doctype/item/item.json b/erpnext/stock/doctype/item/item.json
index b9c466d..e0d8b6c 100644
--- a/erpnext/stock/doctype/item/item.json
+++ b/erpnext/stock/doctype/item/item.json
@@ -445,38 +445,38 @@
"set_only_once": 0,
"translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "1",
- "fieldname": "allow_transfer_for_manufacture",
- "fieldtype": "Check",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Allow Transfer for Manufacture",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "default": "1",
+ "fieldname": "include_item_in_manufacturing",
+ "fieldtype": "Check",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Include Item In Manufacturing",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
},
{
@@ -4350,4 +4350,4 @@
"track_changes": 1,
"track_seen": 0,
"track_views": 0
-}
\ No newline at end of file
+}
diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py
index 2033bb4..4b1bf90 100644
--- a/erpnext/stock/doctype/item/test_item.py
+++ b/erpnext/stock/doctype/item/test_item.py
@@ -395,4 +395,3 @@
"company": "_Test Company"
})
item.save()
-
diff --git a/erpnext/stock/doctype/item_default/item_default.json b/erpnext/stock/doctype/item_default/item_default.json
index 21e9355..96b5dfd 100644
--- a/erpnext/stock/doctype/item_default/item_default.json
+++ b/erpnext/stock/doctype/item_default/item_default.json
@@ -1,463 +1,464 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 0,
- "creation": "2018-05-03 02:29:24.444341",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "",
- "editable_grid": 1,
- "engine": "InnoDB",
+ "allow_copy": 0,
+ "allow_events_in_timeline": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 0,
+ "allow_rename": 0,
+ "beta": 0,
+ "creation": "2018-05-03 02:29:24.444341",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "",
+ "editable_grid": 1,
+ "engine": "InnoDB",
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "company",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Company",
- "length": 0,
- "no_copy": 0,
- "options": "Company",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 1,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "company",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 1,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Company",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Company",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 1,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "default_warehouse",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Default Warehouse",
- "length": 0,
- "no_copy": 0,
- "options": "Warehouse",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "default_warehouse",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Default Warehouse",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Warehouse",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_3",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_3",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "default_price_list",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 1,
- "in_standard_filter": 0,
- "label": "Default Price List",
- "length": 0,
- "no_copy": 0,
- "options": "Price List",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "default_price_list",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 1,
+ "in_standard_filter": 0,
+ "label": "Default Price List",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Price List",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "purchase_defaults",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Purchase Defaults",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "purchase_defaults",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Purchase Defaults",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "buying_cost_center",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Buying Cost Center",
- "length": 0,
- "no_copy": 0,
- "options": "Cost Center",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "buying_cost_center",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Buying Cost Center",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Cost Center",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "default_supplier",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Supplier",
- "length": 0,
- "no_copy": 0,
- "options": "Supplier",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "default_supplier",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Supplier",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Supplier",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_8",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_8",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "expense_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Expense Account",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "expense_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Expense Account",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "selling_defaults",
- "fieldtype": "Section Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Sales Defaults",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "selling_defaults",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Sales Defaults",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "selling_cost_center",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Selling Cost Center",
- "length": 0,
- "no_copy": 0,
- "options": "Cost Center",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "selling_cost_center",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Selling Cost Center",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Cost Center",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "column_break_12",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_12",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "income_account",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Default Income Account",
- "length": 0,
- "no_copy": 0,
- "options": "Account",
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "income_account",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Default Income Account",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Account",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
}
- ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
- "istable": 1,
- "max_attachments": 0,
- "modified": "2018-09-19 16:17:52.562232",
- "modified_by": "Administrator",
- "module": "Stock",
- "name": "Item Default",
- "name_case": "",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0,
+ ],
+ "has_web_view": 0,
+ "hide_heading": 0,
+ "hide_toolbar": 0,
+ "idx": 0,
+ "image_view": 0,
+ "in_create": 0,
+ "is_submittable": 0,
+ "issingle": 0,
+ "istable": 1,
+ "max_attachments": 0,
+ "modified": "2018-12-07 11:48:07.638935",
+ "modified_by": "Administrator",
+ "module": "Stock",
+ "name": "Item Default",
+ "name_case": "",
+ "owner": "Administrator",
+ "permissions": [],
+ "quick_entry": 1,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "show_name_in_global_search": 0,
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "track_changes": 1,
+ "track_seen": 0,
"track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/stock/doctype/material_request/material_request.py b/erpnext/stock/doctype/material_request/material_request.py
index 401dfc8..34a86c9 100644
--- a/erpnext/stock/doctype/material_request/material_request.py
+++ b/erpnext/stock/doctype/material_request/material_request.py
@@ -456,31 +456,40 @@
errors =[]
work_orders = []
default_wip_warehouse = frappe.db.get_single_value("Manufacturing Settings", "default_wip_warehouse")
+
for d in mr.items:
if (d.qty - d.ordered_qty) >0:
- if frappe.db.get_value("BOM", {"item": d.item_code, "is_default": 1}):
+ if frappe.db.exists("BOM", {"item": d.item_code, "is_default": 1}):
wo_order = frappe.new_doc("Work Order")
- wo_order.production_item = d.item_code
- wo_order.qty = d.qty - d.ordered_qty
- wo_order.fg_warehouse = d.warehouse
- wo_order.wip_warehouse = default_wip_warehouse
- wo_order.description = d.description
- wo_order.stock_uom = d.stock_uom
- wo_order.expected_delivery_date = d.schedule_date
- wo_order.sales_order = d.sales_order
- wo_order.bom_no = get_item_details(d.item_code).bom_no
- wo_order.material_request = mr.name
- wo_order.material_request_item = d.name
- wo_order.planned_start_date = mr.transaction_date
- wo_order.company = mr.company
+ wo_order.update({
+ "production_item": d.item_code,
+ "qty": d.qty - d.ordered_qty,
+ "fg_warehouse": d.warehouse,
+ "wip_warehouse": default_wip_warehouse,
+ "description": d.description,
+ "stock_uom": d.stock_uom,
+ "expected_delivery_date": d.schedule_date,
+ "sales_order": d.sales_order,
+ "bom_no": get_item_details(d.item_code).bom_no,
+ "material_request": mr.name,
+ "material_request_item": d.name,
+ "planned_start_date": mr.transaction_date,
+ "company": mr.company
+ })
+
+ wo_order.set_work_order_operations()
wo_order.save()
+
work_orders.append(wo_order.name)
else:
errors.append(_("Row {0}: Bill of Materials not found for the Item {1}").format(d.idx, d.item_code))
+
if work_orders:
message = ["""<a href="#Form/Work Order/%s" target="_blank">%s</a>""" % \
(p, p) for p in work_orders]
msgprint(_("The following Work Orders were created:") + '\n' + new_line_sep(message))
+
if errors:
frappe.throw(_("Productions Orders cannot be raised for:") + '\n' + new_line_sep(errors))
+
return work_orders
diff --git a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
index e1d5b08..e81f323 100644
--- a/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
+++ b/erpnext/stock/doctype/purchase_receipt/purchase_receipt_list.js
@@ -1,7 +1,8 @@
frappe.listview_settings['Purchase Receipt'] = {
- add_fields: ["is_return", "grand_total", "status", "per_billed"],
- get_indicator: function (doc) {
- if (cint(doc.is_return) == 1) {
+ add_fields: ["supplier", "supplier_name", "base_grand_total", "is_subcontracted",
+ "transporter_name", "is_return", "status", "per_billed", "currency"],
+ get_indicator: function(doc) {
+ if(cint(doc.is_return)==1) {
return [__("Return"), "darkgrey", "is_return,=,Yes"];
} else if (doc.status === "Closed") {
return [__("Closed"), "green", "status,=,Closed"];
diff --git a/erpnext/stock/doctype/quality_inspection/test_quality_inspection.py b/erpnext/stock/doctype/quality_inspection/test_quality_inspection.py
index 1c8ec23..60cc9a0 100644
--- a/erpnext/stock/doctype/quality_inspection/test_quality_inspection.py
+++ b/erpnext/stock/doctype/quality_inspection/test_quality_inspection.py
@@ -3,8 +3,45 @@
import frappe
import unittest
+from frappe.utils import nowdate
+from erpnext.stock.doctype.item.test_item import create_item
+from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
+from erpnext.controllers.stock_controller import QualityInspectionRejectedError, QualityInspectionRequiredError
# test_records = frappe.get_test_records('Quality Inspection')
class TestQualityInspection(unittest.TestCase):
- pass
+ def setUp(self):
+ create_item("_Test Item with QA")
+ frappe.db.set_value("Item", "_Test Item with QA", "inspection_required_before_delivery", 1)
+
+ def test_qa_for_delivery(self):
+ dn = create_delivery_note(item_code="_Test Item with QA", do_not_submit=True)
+ self.assertRaises(QualityInspectionRequiredError, dn.submit)
+
+ qa = create_quality_inspection(reference_type="Delivery Note", reference_name=dn.name, status="Rejected")
+ dn.reload()
+ self.assertRaises(QualityInspectionRejectedError, dn.submit)
+
+ frappe.db.set_value("Quality Inspection Reading", {"parent": qa.name}, "status", "Accepted")
+ dn.reload()
+ dn.submit()
+
+def create_quality_inspection(**args):
+ args = frappe._dict(args)
+ qa = frappe.new_doc("Quality Inspection")
+ qa.report_date = nowdate()
+ qa.inspection_type = args.inspection_type or "Outgoing"
+ qa.reference_type = args.reference_type
+ qa.reference_name = args.reference_name
+ qa.item_code = args.item_code or "_Test Item with QA"
+ qa.sample_size = 1
+ qa.inspected_by = frappe.session.user
+ qa.append("readings", {
+ "specification": "Size",
+ "status": args.status
+ })
+ qa.save()
+ qa.submit()
+
+ return qa
diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py
index 40881e8..5f0b80e 100644
--- a/erpnext/stock/doctype/stock_entry/stock_entry.py
+++ b/erpnext/stock/doctype/stock_entry/stock_entry.py
@@ -609,7 +609,7 @@
if self.job_card:
job_doc = frappe.get_doc('Job Card', self.job_card)
- job_doc.set_transferred_qty()
+ job_doc.set_transferred_qty(update_status=True)
if self.work_order:
pro_doc = frappe.get_doc("Work Order", self.work_order)
@@ -1003,7 +1003,7 @@
for d in pro_order.get("required_items"):
if (flt(d.required_qty) > flt(d.transferred_qty) and
- (d.allow_transfer_for_manufacture or self.purpose != "Material Transfer for Manufacture")):
+ (d.include_item_in_manufacturing or self.purpose != "Material Transfer for Manufacture")):
item_row = d.as_dict()
if d.source_warehouse and not frappe.db.get_value("Warehouse", d.source_warehouse, "is_group"):
item_row["from_warehouse"] = d.source_warehouse
diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
index 4d34d96..ed9d770 100644
--- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
+++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.js
@@ -42,7 +42,7 @@
},
get_items: function(frm) {
- frappe.prompt({label:"Warehouse", fieldtype:"Link", options:"Warehouse", reqd: 1,
+ frappe.prompt({label:"Warehouse", fieldname: "warehouse", fieldtype:"Link", options:"Warehouse", reqd: 1,
"get_query": function() {
return {
"filters": {
diff --git a/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.js b/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.js
index 21884d8..39cfd72 100644
--- a/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.js
+++ b/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.js
@@ -10,7 +10,7 @@
"fieldtype": "Date",
"width": "80",
"reqd": 1,
- "default": frappe.sys_defaults.year_start_date,
+ "default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
},
{
"fieldname":"to_date",
diff --git a/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py b/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py
index 676cf54..ebcb106 100644
--- a/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py
+++ b/erpnext/stock/report/warehouse_wise_item_balance_age_and_value/warehouse_wise_item_balance_age_and_value.py
@@ -8,7 +8,8 @@
import frappe
from frappe import _
from frappe.utils import flt, cint, getdate
-from erpnext.stock.report.stock_balance.stock_balance import get_item_details, get_item_reorder_details, get_item_warehouse_map
+from erpnext.stock.report.stock_balance.stock_balance import (get_item_details,
+ get_item_reorder_details, get_item_warehouse_map, get_items, get_stock_ledger_entries)
from erpnext.stock.report.stock_ageing.stock_ageing import get_fifo_queue, get_average_age
from six import iteritems
@@ -18,8 +19,12 @@
validate_filters(filters)
columns = get_columns(filters)
- item_map = get_item_details(filters)
- iwb_map = get_item_warehouse_map(filters)
+
+ items = get_items(filters)
+ sle = get_stock_ledger_entries(filters, items)
+
+ item_map = get_item_details(items, sle, filters)
+ iwb_map = get_item_warehouse_map(filters, sle)
warehouse_list = get_warehouse_list(filters)
item_ageing = get_fifo_queue(filters)
data = []
@@ -27,6 +32,8 @@
item_value = {}
for (company, item, warehouse) in sorted(iwb_map):
+ if not item_map.get(item): continue
+
row = []
qty_dict = iwb_map[(company, item, warehouse)]
item_balance.setdefault((item, item_map[item]["item_group"]), [])
@@ -42,6 +49,8 @@
# sum bal_qty by item
for (item, item_group), wh_balance in iteritems(item_balance):
+ if not item_ageing.get(item): continue
+
total_stock_value = sum(item_value[(item, item_group)])
row = [item, item_group, total_stock_value]
@@ -85,11 +94,10 @@
filters["company"] = frappe.defaults.get_user_default("Company")
def get_warehouse_list(filters):
- from frappe.defaults import get_user_permissions
+ from frappe.core.doctype.user_permission.user_permission import get_permitted_documents
+
condition = ''
- user_permitted_warehouse = filter(None, get_user_permissions()
- .get("Warehouse", {})
- .get("docs", []))
+ user_permitted_warehouse = get_permitted_documents('Warehouse')
value = ()
if user_permitted_warehouse:
condition = "and name in %s"
diff --git a/erpnext/templates/includes/itemised_tax_breakup.html b/erpnext/templates/includes/itemised_tax_breakup.html
index 982397e..c27e4ce 100644
--- a/erpnext/templates/includes/itemised_tax_breakup.html
+++ b/erpnext/templates/includes/itemised_tax_breakup.html
@@ -16,7 +16,7 @@
<tr>
<td>{{ item }}</td>
<td class='text-right'>
- {{ frappe.utils.fmt_money(itemised_taxable_amount.get(item), None, currency) }}
+ {{ frappe.utils.fmt_money(itemised_taxable_amount.get(item, 0), None, currency) }}
</td>
{% for tax_account in tax_accounts %}
{% set tax_details = taxes.get(tax_account) %}