Merge branch 'develop' of github.com:frappe/erpnext into general-ui-fixes

This commit is contained in:
Suraj Shetty 2018-12-27 09:05:25 +05:30
commit 3de12db2b1
142 changed files with 7011 additions and 1132 deletions

View File

@ -5,7 +5,7 @@ import frappe
from erpnext.hooks import regional_overrides from erpnext.hooks import regional_overrides
from frappe.utils import getdate from frappe.utils import getdate
__version__ = '10.1.74' __version__ = '10.1.76'
def get_default_company(user=None): def get_default_company(user=None):
'''Get default company for user''' '''Get default company for user'''

View File

@ -830,6 +830,10 @@ class PurchaseInvoice(BuyingController):
return return
tax_withholding_details = get_party_tax_withholding_details(self) tax_withholding_details = get_party_tax_withholding_details(self)
if not tax_withholding_details:
return
accounts = [] accounts = []
for d in self.taxes: for d in self.taxes:
if d.account_head == tax_withholding_details.get("account_head"): if d.account_head == tax_withholding_details.get("account_head"):
@ -839,6 +843,12 @@ class PurchaseInvoice(BuyingController):
if not accounts or tax_withholding_details.get("account_head") not in accounts: if not accounts or tax_withholding_details.get("account_head") not in accounts:
self.append("taxes", tax_withholding_details) 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 # calculate totals again after applying TDS
self.calculate_taxes_and_totals() self.calculate_taxes_and_totals()

View File

@ -324,7 +324,8 @@ class SalesInvoice(SellingController):
return { return {
"print_format": print_format, "print_format": print_format,
"allow_edit_rate": pos.get("allow_user_to_edit_rate"), "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): def update_time_sheet(self, sales_invoice):

View File

@ -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 # License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals from __future__ import unicode_literals
@ -762,6 +762,20 @@ class TestSalesInvoice(unittest.TestCase):
set_perpetual_inventory(0) set_perpetual_inventory(0)
frappe.db.sql("delete from `tabPOS Profile`") 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): def test_sales_invoice_gl_entry_with_perpetual_inventory_no_item_code(self):
set_perpetual_inventory() set_perpetual_inventory()

View File

@ -24,6 +24,7 @@ def get_party_tax_withholding_details(ref_doc):
.format(tax_withholding_category, ref_doc.company)) .format(tax_withholding_category, ref_doc.company))
tds_amount = get_tds_amount(ref_doc, tax_details, fy) tds_amount = get_tds_amount(ref_doc, tax_details, fy)
tax_row = get_tax_row(tax_details, tds_amount) tax_row = get_tax_row(tax_details, tds_amount)
return tax_row return tax_row
def get_tax_withholding_details(tax_withholding_category, fiscal_year, company): def get_tax_withholding_details(tax_withholding_category, fiscal_year, company):
@ -62,46 +63,64 @@ def get_tax_row(tax_details, tds_amount):
def get_tds_amount(ref_doc, tax_details, fiscal_year_details): def get_tds_amount(ref_doc, tax_details, fiscal_year_details):
fiscal_year, year_start_date, year_end_date = fiscal_year_details fiscal_year, year_start_date, year_end_date = fiscal_year_details
tds_amount = 0 tds_amount = 0
tds_deducted = 0
def _get_tds(): def _get_tds(amount):
tds_amount = 0 if amount <= 0:
if not tax_details.threshold or ref_doc.net_total >= tax_details.threshold: return 0
tds_amount = ref_doc.net_total * tax_details.rate / 100
return tds_amount
if tax_details.cumulative_threshold: return amount * tax_details.rate / 100
entries = frappe.db.sql("""
entries = frappe.db.sql("""
select voucher_no, credit select voucher_no, credit
from `tabGL Entry` from `tabGL Entry`
where party=%s and fiscal_year=%s and credit > 0 where party=%s and fiscal_year=%s and credit > 0
""", (ref_doc.supplier, fiscal_year), as_dict=1) """, (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] tds_vouchers = vouchers + advance_vouchers
vouchers += get_advance_vouchers(ref_doc.supplier, fiscal_year)
tds_deducted = 0 if tds_vouchers:
if vouchers: tds_deducted = frappe.db.sql("""
tds_deducted = flt(frappe.db.sql(""" SELECT sum(credit) FROM `tabGL Entry`
select sum(credit) WHERE
from `tabGL Entry` account=%s and fiscal_year=%s and credit > 0
where account=%s and fiscal_year=%s and credit > 0 and voucher_no in ({0})""". format(','.join(['%s'] * len(tds_vouchers))),
and voucher_no in ({0}) ((tax_details.account_head, fiscal_year) + tuple(tds_vouchers)))
""".format(', '.join(["'%s'" % d for d in vouchers])),
(tax_details.account_head, fiscal_year))[0][0]) 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) 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 \ if ((tax_details.get('threshold', 0) and supplier_credit_amount >= tax_details.threshold)
+ flt(ref_doc.net_total) - debit_note_amount or (tax_details.get('cumulative_threshold', 0) and supplier_credit_amount >= tax_details.cumulative_threshold)):
if total_invoiced_amount >= tax_details.cumulative_threshold: tds_amount = _get_tds(supplier_credit_amount)
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()
return tds_amount return tds_amount
@ -114,7 +133,7 @@ def get_advance_vouchers(supplier, fiscal_year=None, company=None, from_date=Non
select distinct voucher_no select distinct voucher_no
from `tabGL Entry` from `tabGL Entry`
where party=%s and %s and debit > 0 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): def get_debit_note_amount(supplier, year_start_date, year_end_date, company=None):
condition = "" condition = ""
@ -126,4 +145,4 @@ def get_debit_note_amount(supplier, year_start_date, year_end_date, company=None
from `tabPurchase Invoice` from `tabPurchase Invoice`
where supplier=%s %s and is_return=1 and docstatus=1 where supplier=%s %s and is_return=1 and docstatus=1
and posting_date between %s and %s and posting_date between %s and %s
""", (supplier, condition, year_start_date, year_end_date))) """, (supplier, condition, year_start_date, year_end_date)))

View File

@ -6,6 +6,7 @@ from __future__ import unicode_literals
import frappe import frappe
import unittest import unittest
from frappe.utils import today from frappe.utils import today
from erpnext.accounts.utils import get_fiscal_year
test_dependencies = ["Supplier Group"] test_dependencies = ["Supplier Group"]
@ -14,65 +15,105 @@ class TestTaxWithholdingCategory(unittest.TestCase):
def setUpClass(self): def setUpClass(self):
# create relevant supplier, etc # create relevant supplier, etc
create_records() create_records()
create_tax_with_holding_category()
def test_single_threshold_tds(self): def test_cumulative_threshold_tds(self):
frappe.db.set_value("Supplier", "Test TDS Supplier", "tax_withholding_category", "TDS - 194D - Individual") frappe.db.set_value("Supplier", "Test TDS Supplier", "tax_withholding_category", "Cumulative Threshold TDS")
pi = create_purchase_invoice() 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() pi.submit()
self.assertEqual(pi.taxes_and_charges_deducted, 800) # assert equal tax deduction on total invoice amount uptil now
self.assertEqual(pi.grand_total, 15200) 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 # check gl entry for the purchase invoice
gl_entries = frappe.db.get_all('GL Entry', filters={'voucher_no': pi.name}, fields=["*"]) gl_entries = frappe.db.get_all('GL Entry', filters={'voucher_no': pi.name}, fields=["*"])
self.assertEqual(len(gl_entries), 3) self.assertEqual(len(gl_entries), 3)
for d in gl_entries: for d in gl_entries:
if d.account == pi.credit_to: 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"): 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"): elif d.account == pi.taxes[0].get("account_head"):
self.assertEqual(d.credit, 800) self.assertEqual(d.credit, 2000)
else: else:
raise ValueError("Account head does not match.") raise ValueError("Account head does not match.")
# delete purchase invoice to avoid it interefering in other tests pi = create_purchase_invoice(supplier = "Test TDS Supplier1")
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.submit() 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) 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 # delete invoices to avoid clashing
for d in invoices: for d in invoices:
d.cancel() d.cancel()
frappe.delete_doc("Purchase Invoice", d.name) 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 # return sales invoice doc object
item = frappe.get_doc('Item', {'item_name': 'TDS Item'}) item = frappe.get_doc('Item', {'item_name': 'TDS Item'})
args = frappe._dict(args)
pi = frappe.get_doc({ pi = frappe.get_doc({
"doctype": "Purchase Invoice", "doctype": "Purchase Invoice",
"posting_date": today(), "posting_date": today(),
"apply_tds": 1, "apply_tds": 1,
"supplier": frappe.get_doc('Supplier', {"supplier_name": "Test TDS Supplier"}).name, "supplier": args.supplier,
"company": '_Test Company', "company": '_Test Company',
"taxes_and_charges": "", "taxes_and_charges": "",
"currency": "INR", "currency": "INR",
@ -81,8 +122,8 @@ def create_purchase_invoice(qty=1):
"items": [{ "items": [{
'doctype': 'Purchase Invoice Item', 'doctype': 'Purchase Invoice Item',
'item_code': item.name, 'item_code': item.name,
'qty': qty, 'qty': args.qty or 1,
'rate': 16000, 'rate': args.rate or 10000,
'cost_center': 'Main - _TC', 'cost_center': 'Main - _TC',
'expense_account': 'Stock Received But Not Billed - _TC' 'expense_account': 'Stock Received But Not Billed - _TC'
}] }]
@ -92,20 +133,73 @@ def create_purchase_invoice(qty=1):
return pi return pi
def create_records(): def create_records():
# create a new supplier # create a new suppliers
frappe.get_doc({ for name in ['Test TDS Supplier', 'Test TDS Supplier1', 'Test TDS Supplier2']:
"supplier_group": "_Test Supplier Group", if frappe.db.exists('Supplier', name):
"supplier_name": "Test TDS Supplier", continue
"doctype": "Supplier",
"tax_withholding_category": "TDS - 194D - Individual" frappe.get_doc({
}).insert() "supplier_group": "_Test Supplier Group",
"supplier_name": name,
"doctype": "Supplier",
}).insert()
# create an item # create an item
frappe.get_doc({ if not frappe.db.exists('Item', "TDS Item"):
"doctype": "Item", frappe.get_doc({
"item_code": "TDS Item", "doctype": "Item",
"item_name": "TDS Item", "item_code": "TDS Item",
"item_group": "All Item Groups", "item_name": "TDS Item",
"company": "_Test Company", "item_group": "All Item Groups",
"is_stock_item": 0, "is_stock_item": 0,
}).insert() }).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()

View File

@ -1135,16 +1135,18 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
}, },
apply_category: function() { apply_category: function() {
var me = this; frappe.db.get_value("Item Group", {lft: 1, is_group: 1}, "name", (r) => {
category = this.selected_item_group || "All Item Groups"; category = this.selected_item_group || r.name;
if(category == 'All Item Groups') { if(category == r.name) {
return this.item_data return this.item_data
} else { } else {
return this.item_data.filter(function(element, index, array){ return this.item_data.filter(function(element, index, array){
return element.item_group == category; return element.item_group == category;
}); });
} }
})
}, },
bind_items_event: function() { bind_items_event: function() {

View File

@ -5,7 +5,7 @@ from __future__ import unicode_literals
import frappe, erpnext import frappe, erpnext
from frappe import _, msgprint, scrub 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.model.utils import get_fetch_values
from frappe.utils import (add_days, getdate, formatdate, date_diff, from frappe.utils import (add_days, getdate, formatdate, date_diff,
add_years, get_timestamp, nowdate, flt, add_months, get_last_day) add_years, get_timestamp, nowdate, flt, add_months, get_last_day)
@ -151,10 +151,7 @@ def get_default_price_list(party):
def set_price_list(out, party, party_type, given_price_list): def set_price_list(out, party, party_type, given_price_list):
# price list # price list
price_list = filter(None, get_user_permissions() price_list = get_permitted_documents('Price List')
.get("Price List", {})
.get("docs", []))
price_list = list(price_list)
if price_list: if price_list:
price_list = price_list[0] price_list = price_list[0]

View File

@ -91,6 +91,7 @@ class PurchaseOrder(BuyingController):
self.party_account_currency = get_party_account_currency("Supplier", self.supplier, self.company) self.party_account_currency = get_party_account_currency("Supplier", self.supplier, self.company)
def validate_minimum_order_qty(self): def validate_minimum_order_qty(self):
if not self.get("items"): return
items = list(set([d.item_code for d in self.get("items")])) 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 itemwise_min_order_qty = frappe._dict(frappe.db.sql("""select name, min_order_qty

View File

@ -561,10 +561,6 @@ def get_data():
"label": _("Subscription Management"), "label": _("Subscription Management"),
"icon": "fa fa-microchip ", "icon": "fa fa-microchip ",
"items": [ "items": [
{
"type": "doctype",
"name": "Subscriber",
},
{ {
"type": "doctype", "type": "doctype",
"name": "Subscription Plan", "name": "Subscription Plan",

View File

@ -572,5 +572,12 @@ def get_data():
"type": "module", "type": "module",
"label": _("Non Profit"), "label": _("Non Profit"),
"hidden": 1 "hidden": 1
},
{
"module_name": "Quality Management",
"color": "blue",
"icon": "octicon octicon-package",
"type": "module",
"label": _("Quality Management")
} }
] ]

View File

@ -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"),
}
]
},
]

View File

@ -678,7 +678,7 @@ class BuyingController(StockController):
frappe.db.sql("delete from `tabSerial No` where purchase_document_no=%s", self.name) frappe.db.sql("delete from `tabSerial No` where purchase_document_no=%s", self.name)
def validate_schedule_date(self): 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")]) self.schedule_date = min([d.schedule_date for d in self.get("items")])
if self.schedule_date: if self.schedule_date:

View File

@ -12,6 +12,9 @@ from erpnext.controllers.accounts_controller import AccountsController
from erpnext.stock.stock_ledger import get_valuation_rate from erpnext.stock.stock_ledger import get_valuation_rate
from erpnext.stock import get_warehouse_account_map from erpnext.stock import get_warehouse_account_map
class QualityInspectionRequiredError(frappe.ValidationError): pass
class QualityInspectionRejectedError(frappe.ValidationError): pass
class StockController(AccountsController): class StockController(AccountsController):
def validate(self): def validate(self):
super(StockController, self).validate() super(StockController, self).validate()
@ -317,7 +320,6 @@ class StockController(AccountsController):
def validate_inspection(self): def validate_inspection(self):
'''Checks if quality inspection is set for Items that require inspection. '''Checks if quality inspection is set for Items that require inspection.
On submit, throw an exception''' On submit, throw an exception'''
inspection_required_fieldname = None inspection_required_fieldname = None
if self.doctype in ["Purchase Receipt", "Purchase Invoice"]: if self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
inspection_required_fieldname = "inspection_required_before_purchase" inspection_required_fieldname = "inspection_required_before_purchase"
@ -330,17 +332,25 @@ class StockController(AccountsController):
return return
for d in self.get('items'): for d in self.get('items'):
raise_exception = False qa_required = False
if (inspection_required_fieldname and not d.quality_inspection and if (inspection_required_fieldname and not d.quality_inspection and
frappe.db.get_value("Item", d.item_code, inspection_required_fieldname)): 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: 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)) frappe.msgprint(_("Quality Inspection required for Item {0}").format(d.item_code))
if self.docstatus==1: 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): def update_blanket_order(self):
blanket_orders = list(set([d.blanket_order for d in self.items if d.blanket_order])) blanket_orders = list(set([d.blanket_order for d in self.items if d.blanket_order]))

View File

@ -12,7 +12,7 @@ app_license = "GNU General Public License (v3)"
source_link = "https://github.com/frappe/erpnext" source_link = "https://github.com/frappe/erpnext"
develop_version = '12.x.x-develop' 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" error_report_email = "support@erpnext.com"
@ -254,7 +254,8 @@ scheduler_events = {
"erpnext.assets.doctype.asset.asset.update_maintenance_status", "erpnext.assets.doctype.asset.asset.update_maintenance_status",
"erpnext.assets.doctype.asset.asset.make_post_gl_entry", "erpnext.assets.doctype.asset.asset.make_post_gl_entry",
"erpnext.crm.doctype.contract.contract.update_status_for_contracts", "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": [ "daily_long": [
"erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_latest_price_in_all_boms" "erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_latest_price_in_all_boms"

View File

@ -62,8 +62,8 @@ class Employee(NestedSet):
def validate_user_details(self): def validate_user_details(self):
data = frappe.db.get_value('User', data = frappe.db.get_value('User',
self.user_id, ['enabled', 'user_image'], as_dict=1) self.user_id, ['enabled', 'user_image'], as_dict=1)
if data.get("user_image"):
self.image = data.get("user_image") self.image = data.get("user_image")
self.validate_for_enabled_user_id(data.get("enabled", 0)) self.validate_for_enabled_user_id(data.get("enabled", 0))
self.validate_duplicate_user_id() self.validate_duplicate_user_id()

View File

@ -14,7 +14,7 @@ frappe.ui.form.on("Leave Application", {
doctype: frm.doc.doctype doctype: frm.doc.doctype
} }
}; };
}); });
frm.set_query("employee", erpnext.queries.employee); frm.set_query("employee", erpnext.queries.employee);
}, },
@ -83,7 +83,7 @@ frappe.ui.form.on("Leave Application", {
if (!frm.doc.employee && frappe.defaults.get_user_permissions()) { if (!frm.doc.employee && frappe.defaults.get_user_permissions()) {
const perm = frappe.defaults.get_user_permissions(); const perm = frappe.defaults.get_user_permissions();
if (perm && perm['Employee']) { 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]);
} }
} }
}, },

View File

@ -4,7 +4,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import frappe import frappe
from frappe.utils import flt, cint from frappe.utils import flt, cint, cstr
from frappe import _ from frappe import _
from frappe.model.mapper import get_mapped_doc from frappe.model.mapper import get_mapped_doc
from frappe.model.document import Document from frappe.model.document import Document
@ -22,7 +22,7 @@ class SalaryStructure(Document):
overwritten_fields_if_missing = ["amount_based_on_formula", "formula", "amount"] overwritten_fields_if_missing = ["amount_based_on_formula", "formula", "amount"]
for table in ["earnings", "deductions"]: for table in ["earnings", "deductions"]:
for d in self.get(table): 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) overwritten_fields + overwritten_fields_if_missing, as_dict=1)
if component_default_value: if component_default_value:
for fieldname in overwritten_fields: for fieldname in overwritten_fields:

View File

@ -402,6 +402,8 @@ frappe.ui.form.on("BOM Item", "items_remove", function(frm) {
var toggle_operations = function(frm) { var toggle_operations = function(frm) {
frm.toggle_display("operations_section", cint(frm.doc.with_operations) == 1); 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) { frappe.ui.form.on("BOM", "with_operations", function(frm) {

View File

@ -80,41 +80,6 @@
"translatable": 0, "translatable": 0,
"unique": 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": "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_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
@ -154,8 +119,10 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "inspection_required", "default": "1",
"fieldtype": "Check", "description": "Quantity of item obtained after manufacturing / repacking from given quantities of raw materials",
"fieldname": "quantity",
"fieldtype": "Float",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
@ -163,51 +130,18 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Inspection Required", "label": "Quantity",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"oldfieldname": "quantity",
"oldfieldtype": "Currency",
"permlevel": 0, "permlevel": 0,
"precision": "",
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"remember_last_selected_value": 0, "remember_last_selected_value": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 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": "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, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0, "translatable": 0,
@ -346,77 +280,11 @@
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
"allow_on_submit": 1, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "rm_cost_as_per", "fieldname": "inspection_required",
"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",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
@ -425,7 +293,7 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Set rate of sub-assembly item based on BOM", "label": "Inspection Required",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
@ -481,7 +349,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "allow_same_item_multiple_times", "fieldname": "allow_same_item_multiple_times",
"fieldtype": "Data", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
@ -508,12 +376,12 @@
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 1,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "with_operations", "default": "1",
"fieldname": "transfer_material_against_job_card", "fieldname": "set_rate_of_sub_assembly_item_based_on_bom",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
@ -522,7 +390,7 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Transfer Material Against Job Card", "label": "Set rate of sub-assembly item based on BOM",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
@ -538,6 +406,40 @@
"translatable": 0, "translatable": 0,
"unique": 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,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
@ -603,6 +505,72 @@
"translatable": 0, "translatable": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"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_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
@ -670,12 +638,12 @@
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 1,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "conversion_rate", "fieldname": "rm_cost_as_per",
"fieldtype": "Float", "fieldtype": "Select",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
@ -683,17 +651,50 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Conversion Rate", "label": "Rate Of Materials Based On",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"options": "Valuation Rate\nLast Purchase Rate\nPrice List",
"permlevel": 0, "permlevel": 0,
"precision": "9",
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
"read_only": 0, "read_only": 0,
"remember_last_selected_value": 0, "remember_last_selected_value": 0,
"report_hide": 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, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0, "translatable": 0,
@ -707,7 +708,7 @@
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"depends_on": "", "depends_on": "",
"description": "Specify the operations, operating cost and give a unique Operation no to your operations.", "description": "",
"fieldname": "operations_section", "fieldname": "operations_section",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"hidden": 0, "hidden": 0,
@ -1976,7 +1977,7 @@
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2018-10-24 02:07:21.618275", "modified": "2018-12-13 17:45:44.843197",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Manufacturing", "module": "Manufacturing",
"name": "BOM", "name": "BOM",

View File

@ -81,7 +81,7 @@ class BOM(WebsiteGenerator):
def get_item_det(self, item_code): def get_item_det(self, item_code):
item = frappe.db.sql("""select name, item_name, docstatus, description, image, item = frappe.db.sql("""select name, item_name, docstatus, description, image,
is_sub_contracted_item, stock_uom, default_bom, last_purchase_rate, 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) from `tabItem` where name=%s""", item_code, as_dict = 1)
if not item: if not item:
@ -109,7 +109,7 @@ class BOM(WebsiteGenerator):
"item_name": item.item_name, "item_name": item.item_name,
"bom_no": item.bom_no, "bom_no": item.bom_no,
"stock_qty": item.stock_qty, "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: for r in ret:
if not item.get(r): if not item.get(r):
@ -128,8 +128,8 @@ class BOM(WebsiteGenerator):
self.validate_rm_item(item) self.validate_rm_item(item)
args['bom_no'] = args['bom_no'] or item and cstr(item[0]['default_bom']) or '' 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 args['transfer_for_manufacture'] = (cstr(args.get('include_item_in_manufacturing', '')) or
item and item[0].allow_transfer_for_manufacture or 0) item and item[0].include_item_in_manufacturing or 0)
args.update(item[0]) args.update(item[0])
rate = self.get_rm_rate(args) rate = self.get_rm_rate(args)
@ -145,7 +145,7 @@ class BOM(WebsiteGenerator):
'qty' : args.get("qty") or args.get("stock_qty") or 1, 'qty' : args.get("qty") or args.get("stock_qty") or 1,
'stock_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, '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 return ret_item
@ -479,7 +479,7 @@ class BOM(WebsiteGenerator):
'stock_uom' : d.stock_uom, 'stock_uom' : d.stock_uom,
'stock_qty' : flt(d.stock_qty), 'stock_qty' : flt(d.stock_qty),
'rate' : d.base_rate, '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): def company_currency(self):
@ -496,7 +496,7 @@ class BOM(WebsiteGenerator):
# Did not use qty_consumed_per_unit in the query, as it leads to rounding loss # 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, 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.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 bom_item.stock_qty / ifnull(bom.quantity, 1) as qty_consumed_per_unit
from `tabBOM Explosion Item` bom_item, tabBOM bom 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) where bom_item.parent = bom.name and bom.name = %s and bom.docstatus = 1""", bom_no, as_dict = 1)
@ -511,7 +511,7 @@ class BOM(WebsiteGenerator):
'stock_uom' : d['stock_uom'], 'stock_uom' : d['stock_uom'],
'stock_qty' : d['qty_consumed_per_unit'] * stock_qty, 'stock_qty' : d['qty_consumed_per_unit'] * stock_qty,
'rate' : flt(d['rate']), '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): def add_exploded_items(self):
@ -587,7 +587,7 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite
query = query.format(table="BOM Explosion Item", query = query.format(table="BOM Explosion Item",
where_conditions="", where_conditions="",
is_stock_item=is_stock_item, 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""") (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) items = frappe.db.sql(query, { "parent": bom, "qty": qty, "bom": bom, "company": company }, as_dict=True)
@ -596,7 +596,7 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite
items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True) items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
else: else:
query = query.format(table="BOM Item", where_conditions="", is_stock_item=is_stock_item, 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) items = frappe.db.sql(query, { "qty": qty, "bom": bom, "company": company }, as_dict=True)
for item in items: for item in items:

View File

@ -11,7 +11,7 @@
"uom": "_Test UOM", "uom": "_Test UOM",
"stock_uom": "_Test UOM", "stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC", "source_warehouse": "_Test Warehouse - _TC",
"allow_transfer_for_manufacture": 1 "include_item_in_manufacturing": 1
}, },
{ {
"amount": 2000.0, "amount": 2000.0,
@ -23,7 +23,7 @@
"uom": "_Test UOM", "uom": "_Test UOM",
"stock_uom": "_Test UOM", "stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC", "source_warehouse": "_Test Warehouse - _TC",
"allow_transfer_for_manufacture": 1 "include_item_in_manufacturing": 1
} }
], ],
"docstatus": 1, "docstatus": 1,
@ -57,7 +57,7 @@
"uom": "_Test UOM", "uom": "_Test UOM",
"stock_uom": "_Test UOM", "stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC", "source_warehouse": "_Test Warehouse - _TC",
"allow_transfer_for_manufacture": 1 "include_item_in_manufacturing": 1
}, },
{ {
"amount": 2000.0, "amount": 2000.0,
@ -69,7 +69,7 @@
"uom": "_Test UOM", "uom": "_Test UOM",
"stock_uom": "_Test UOM", "stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC", "source_warehouse": "_Test Warehouse - _TC",
"allow_transfer_for_manufacture": 1 "include_item_in_manufacturing": 1
} }
], ],
"docstatus": 1, "docstatus": 1,
@ -102,7 +102,7 @@
"uom": "_Test UOM", "uom": "_Test UOM",
"stock_uom": "_Test UOM", "stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC", "source_warehouse": "_Test Warehouse - _TC",
"allow_transfer_for_manufacture": 1 "include_item_in_manufacturing": 1
}, },
{ {
"amount": 3000.0, "amount": 3000.0,
@ -115,7 +115,7 @@
"uom": "_Test UOM", "uom": "_Test UOM",
"stock_uom": "_Test UOM", "stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC", "source_warehouse": "_Test Warehouse - _TC",
"allow_transfer_for_manufacture": 1 "include_item_in_manufacturing": 1
} }
], ],
"docstatus": 1, "docstatus": 1,
@ -150,7 +150,7 @@
"uom": "_Test UOM", "uom": "_Test UOM",
"stock_uom": "_Test UOM", "stock_uom": "_Test UOM",
"source_warehouse": "_Test Warehouse - _TC", "source_warehouse": "_Test Warehouse - _TC",
"allow_transfer_for_manufacture": 1 "include_item_in_manufacturing": 1
} }
], ],
"docstatus": 1, "docstatus": 1,

View File

@ -1,5 +1,6 @@
{ {
"allow_copy": 0, "allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0, "allow_guest_to_view": 0,
"allow_import": 0, "allow_import": 0,
"allow_rename": 0, "allow_rename": 0,
@ -573,7 +574,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "allow_transfer_for_manufacture", "fieldname": "include_item_in_manufacturing",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
@ -582,7 +583,7 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Allow Transfer for Manufacture", "label": "Include Item In Manufacturing",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
@ -609,7 +610,7 @@
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2018-08-27 16:32:35.152139", "modified": "2018-11-20 19:04:59.813773",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Manufacturing", "module": "Manufacturing",
"name": "BOM Explosion Item", "name": "BOM Explosion Item",

View File

@ -79,34 +79,67 @@
"unique": 0 "unique": 0
}, },
{ {
"allow_bulk_edit": 0, "allow_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
"allow_on_submit": 0, "allow_on_submit": 0,
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "column_break_3", "fieldname": "operation",
"fieldtype": "Column Break", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
"in_filter": 0, "in_filter": 0,
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"length": 0, "label": "Item operation",
"no_copy": 0, "length": 0,
"permlevel": 0, "no_copy": 0,
"precision": "", "options": "Operation",
"print_hide": 0, "permlevel": 0,
"print_hide_if_no_value": 0, "precision": "",
"read_only": 0, "print_hide": 0,
"remember_last_selected_value": 0, "print_hide_if_no_value": 0,
"report_hide": 0, "read_only": 0,
"reqd": 0, "remember_last_selected_value": 0,
"search_index": 0, "report_hide": 0,
"set_only_once": 0, "reqd": 0,
"translatable": 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 "unique": 0
}, },
{ {
@ -932,8 +965,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_from": "item_code.allow_transfer_for_manufacture", "fetch_from": "item_code.include_item_in_manufacturing",
"fieldname": "allow_transfer_for_manufacture",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
@ -942,7 +974,6 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Allow Transfer for Manufacture",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
@ -956,6 +987,29 @@
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 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 "unique": 0
}, },
{ {
@ -1023,6 +1077,38 @@
"set_only_once": 0, "set_only_once": 0,
"translatable": 0, "translatable": 0,
"unique": 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, "has_web_view": 0,
@ -1035,7 +1121,7 @@
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2018-11-22 15:04:55.187136", "modified": "2018-12-26 15:04:56.187136",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Manufacturing", "module": "Manufacturing",
"name": "BOM Item", "name": "BOM Item",

View File

@ -3,7 +3,7 @@
frappe.ui.form.on('Job Card', { frappe.ui.form.on('Job Card', {
refresh: function(frm) { 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) { if (frm.doc.for_quantity != frm.doc.transferred_qty) {
frm.add_custom_button(__("Material Request"), () => { frm.add_custom_button(__("Material Request"), () => {
frm.trigger("make_material_request"); frm.trigger("make_material_request");
@ -31,6 +31,7 @@ frappe.ui.form.on('Job Card', {
frm.add_custom_button(__("Complete Job"), () => { frm.add_custom_button(__("Complete Job"), () => {
frm.set_value('actual_end_date', frappe.datetime.now_datetime()); frm.set_value('actual_end_date', frappe.datetime.now_datetime());
frm.save(); frm.save();
frm.savesubmit();
}); });
} }
} }

View File

@ -1,5 +1,6 @@
{ {
"allow_copy": 0, "allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0, "allow_guest_to_view": 0,
"allow_import": 0, "allow_import": 0,
"allow_rename": 0, "allow_rename": 0,
@ -46,6 +47,39 @@
"translatable": 0, "translatable": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"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_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
@ -112,39 +146,6 @@
"translatable": 0, "translatable": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"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_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
@ -281,9 +282,8 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"default": "0", "fieldname": "wip_warehouse",
"fieldname": "transferred_qty", "fieldtype": "Link",
"fieldtype": "Float",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
@ -291,17 +291,18 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Transferred Qty", "label": "WIP Warehouse",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"options": "Warehouse",
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
"read_only": 1, "read_only": 0,
"remember_last_selected_value": 0, "remember_last_selected_value": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 1,
"search_index": 0, "search_index": 0,
"set_only_once": 0, "set_only_once": 0,
"translatable": 0, "translatable": 0,
@ -635,8 +636,9 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "bom_no", "default": "0",
"fieldtype": "Link", "fieldname": "transferred_qty",
"fieldtype": "Float",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
@ -644,10 +646,42 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "BOM No", "label": "Transferred Qty",
"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": "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, "length": 0,
"no_copy": 0, "no_copy": 0,
"options": "BOM",
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
@ -701,8 +735,8 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "column_break_20", "fieldname": "remarks",
"fieldtype": "Column Break", "fieldtype": "Small Text",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
@ -710,6 +744,7 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Remarks",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
@ -732,8 +767,8 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "remarks", "fieldname": "column_break_20",
"fieldtype": "Small Text", "fieldtype": "Column Break",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
"ignore_xss_filter": 0, "ignore_xss_filter": 0,
@ -741,7 +776,6 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Remarks",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
@ -776,13 +810,13 @@
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Status", "label": "Status",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 1,
"options": "Open\nWork In Progress\nCancelled\nCompleted", "options": "Open\nWork In Progress\nMaterial Transferred\nSubmitted\nCancelled\nCompleted",
"permlevel": 0, "permlevel": 0,
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
"read_only": 0, "read_only": 1,
"remember_last_selected_value": 0, "remember_last_selected_value": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 0, "reqd": 0,
@ -834,7 +868,7 @@
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2018-08-28 16:50:43.576151", "modified": "2018-12-13 17:23:57.986381",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Manufacturing", "module": "Manufacturing",
"name": "Job Card", "name": "Job Card",

View File

@ -11,9 +11,9 @@ from frappe.model.document import Document
class JobCard(Document): class JobCard(Document):
def validate(self): def validate(self):
self.status = 'Open'
self.validate_actual_dates() self.validate_actual_dates()
self.set_time_in_mins() self.set_time_in_mins()
self.set_status()
def validate_actual_dates(self): def validate_actual_dates(self):
if get_datetime(self.actual_start_date) > get_datetime(self.actual_end_date): if get_datetime(self.actual_start_date) > get_datetime(self.actual_end_date):
@ -48,7 +48,7 @@ class JobCard(Document):
return return
doc = frappe.get_doc('Work Order', self.get('work_order')) 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 return
for d in doc.required_items: for d in doc.required_items:
@ -104,20 +104,23 @@ class JobCard(Document):
wo.set_actual_dates() wo.set_actual_dates()
wo.save() wo.save()
def set_transferred_qty(self): def set_transferred_qty(self, update_status=False):
if not self.items: if not self.items:
self.transferred_qty = self.for_quantity if self.docstatus == 1 else 0 self.transferred_qty = self.for_quantity if self.docstatus == 1 else 0
if self.items: if self.items:
self.transferred_qty = frappe.db.get_value('Stock Entry', {'job_card': self.name, self.transferred_qty = frappe.db.get_value('Stock Entry', {
'work_order': self.work_order, 'docstatus': 1}, 'sum(fg_completed_qty)') or 0 '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) self.db_set("transferred_qty", self.transferred_qty)
qty = 0 qty = 0
if self.work_order: if self.work_order:
doc = frappe.get_doc('Work Order', 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 completed = True
for d in doc.operations: for d in doc.operations:
if d.status != 'Completed': if d.status != 'Completed':
@ -131,15 +134,28 @@ class JobCard(Document):
doc.db_set('material_transferred_for_manufacturing', qty) doc.db_set('material_transferred_for_manufacturing', qty)
self.set_status() self.set_status(update_status)
def set_status(self): def set_status(self, update_status=False):
status = 'Cancelled' if self.docstatus == 2 else 'Work In Progress' self.status = {
0: "Open",
1: "Submitted",
2: "Cancelled"
}[self.docstatus or 0]
if self.for_quantity == self.transferred_qty: if self.actual_start_date:
status = 'Completed' 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() @frappe.whitelist()
def make_material_request(source_name, target_doc=None): def make_material_request(source_name, target_doc=None):

View File

@ -6,6 +6,8 @@ frappe.listview_settings['Job Card'] = {
return [__("Completed"), "green", "status,=,Completed"]; return [__("Completed"), "green", "status,=,Completed"];
} else if (doc.docstatus == 2) { } else if (doc.docstatus == 2) {
return [__("Cancelled"), "red", "status,=,Cancelled"]; return [__("Cancelled"), "red", "status,=,Cancelled"];
} else if (doc.status === "Material Transferred") {
return [__('Material Transferred'), "blue", "status,=,Material Transferred"];
} else { } else {
return [__("Open"), "red", "status,=,Open"]; return [__("Open"), "red", "status,=,Open"];
} }

View File

@ -306,7 +306,7 @@ class TestWorkOrder(unittest.TestCase):
items = {'Finished Good Transfer Item': 1, '_Test FG Item': 1, '_Test FG Item 1': 0} items = {'Finished Good Transfer Item': 1, '_Test FG Item': 1, '_Test FG Item 1': 0}
for item, allow_transfer in items.items(): for item, allow_transfer in items.items():
make_item(item, { make_item(item, {
'allow_transfer_for_manufacture': allow_transfer 'include_item_in_manufacturing': allow_transfer
}) })
fg_item = 'Finished Good Transfer Item' fg_item = 'Finished Good Transfer Item'

View File

@ -112,11 +112,21 @@ frappe.ui.form.on("Work Order", {
frm.trigger('show_progress'); 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.doc.qty != frm.doc.material_transferred_for_manufacturing) {
frm.add_custom_button(__('Create Job Card'), () => {
frm.trigger("make_job_card"); const not_completed = frm.doc.operations.filter(d => {
}).addClass('btn-primary'); 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) { if(frm.doc.required_items && frm.doc.allow_alternative_item) {
@ -294,7 +304,7 @@ frappe.ui.form.on("Work Order", {
frm.trigger('set_sales_order'); frm.trigger('set_sales_order');
erpnext.in_production_item_onchange = true; erpnext.in_production_item_onchange = true;
$.each(["description", "stock_uom", "project", "bom_no", $.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]); frm.set_value(field, r.message[field]);
}); });
@ -340,9 +350,8 @@ frappe.ui.form.on("Work Order", {
before_submit: function(frm) { before_submit: function(frm) {
frm.toggle_reqd(["fg_warehouse", "wip_warehouse"], true); frm.toggle_reqd(["fg_warehouse", "wip_warehouse"], true);
frm.fields_dict.required_items.grid.toggle_reqd("source_warehouse", true); frm.fields_dict.required_items.grid.toggle_reqd("source_warehouse", true);
if (frm.doc.operations) { frm.toggle_reqd("transfer_material_against", frm.doc.operations);
frm.fields_dict.operations.grid.toggle_reqd("workstation", true); frm.fields_dict.operations.grid.toggle_reqd("workstation", frm.doc.operations);
}
}, },
set_sales_order: function(frm) { set_sales_order: function(frm) {
@ -425,7 +434,7 @@ erpnext.work_order = {
} }
const show_start_btn = (frm.doc.skip_transfer 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 (show_start_btn){
if ((flt(doc.material_transferred_for_manufacturing) < flt(doc.qty)) if ((flt(doc.material_transferred_for_manufacturing) < flt(doc.qty))

View File

@ -1,5 +1,6 @@
{ {
"allow_copy": 0, "allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0, "allow_guest_to_view": 0,
"allow_import": 1, "allow_import": 1,
"allow_rename": 0, "allow_rename": 0,
@ -183,6 +184,38 @@
"translatable": 0, "translatable": 0,
"unique": 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": 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_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
@ -223,7 +256,8 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "allow_alternative_item", "description": "Check if material transfer entry is not required",
"fieldname": "skip_transfer",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
@ -232,7 +266,7 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Allow Alternative Item", "label": "Skip Material Transfer",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
@ -486,39 +520,6 @@
"translatable": 0, "translatable": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"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_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
@ -552,39 +553,6 @@
"translatable": 0, "translatable": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"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_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
@ -1070,6 +1038,41 @@
"translatable": 0, "translatable": 0,
"unique": 0 "unique": 0
}, },
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"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_bulk_edit": 0,
"allow_in_quick_entry": 0, "allow_in_quick_entry": 0,
@ -1672,7 +1675,7 @@
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2018-09-05 06:28:22.983369", "modified": "2018-12-13 15:33:12.490710",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Manufacturing", "module": "Manufacturing",
"name": "Work Order", "name": "Work Order",

View File

@ -191,7 +191,7 @@ class WorkOrder(Document):
for purpose, fieldname in (("Manufacture", "produced_qty"), for purpose, fieldname in (("Manufacture", "produced_qty"),
("Material Transfer for Manufacture", "material_transferred_for_manufacturing")): ("Material Transfer for Manufacture", "material_transferred_for_manufacturing")):
if (purpose == 'Material Transfer for Manufacture' and 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 continue
qty = flt(frappe.db.sql("""select sum(fg_completed_qty) qty = flt(frappe.db.sql("""select sum(fg_completed_qty)
@ -459,7 +459,7 @@ class WorkOrder(Document):
'allow_alternative_item': item.allow_alternative_item, 'allow_alternative_item': item.allow_alternative_item,
'required_qty': item.qty, 'required_qty': item.qty,
'source_warehouse': item.source_warehouse or item.default_warehouse, '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() self.set_available_qty()
@ -564,11 +564,11 @@ def get_item_details(item, project = None):
frappe.throw(_("Default BOM for {0} not found").format(item)) frappe.throw(_("Default BOM for {0} not found").format(item))
bom_data = frappe.db.get_value('BOM', res['bom_no'], 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['project'] = project or bom_data.project
res['allow_alternative_item'] = bom_data.allow_alternative_item 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"])) res.update(check_if_scrap_warehouse_mandatory(res["bom_no"]))
return res return res
@ -682,7 +682,7 @@ def create_job_card(work_order, row, qty=0, auto_create=False):
'wip_warehouse': work_order.wip_warehouse '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() doc.get_required_items()
if auto_create: if auto_create:

View File

@ -1,5 +1,6 @@
{ {
"allow_copy": 0, "allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0, "allow_guest_to_view": 0,
"allow_import": 0, "allow_import": 0,
"allow_rename": 0, "allow_rename": 0,
@ -342,7 +343,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fieldname": "allow_transfer_for_manufacture", "fieldname": "include_item_in_manufacturing",
"fieldtype": "Check", "fieldtype": "Check",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
@ -351,7 +352,7 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Allow Transfer for Manufacture", "label": "Include Item In Manufacturing",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
@ -506,7 +507,7 @@
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2018-10-04 16:16:54.237829", "modified": "2018-11-20 19:04:38.508839",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Manufacturing", "module": "Manufacturing",
"name": "Work Order Item", "name": "Work Order Item",

View File

@ -22,3 +22,4 @@ ERPNext Integrations
Non Profit Non Profit
Hotels Hotels
Hub Node Hub Node
Quality Management

View File

@ -495,7 +495,7 @@ erpnext.patches.v10_0.set_b2c_limit
erpnext.patches.v10_0.update_translatable_fields erpnext.patches.v10_0.update_translatable_fields
erpnext.patches.v10_0.rename_offer_letter_to_job_offer erpnext.patches.v10_0.rename_offer_letter_to_job_offer
execute:frappe.delete_doc('DocType', 'Production Planning Tool', ignore_missing=True) 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.v10_0.add_default_cash_flow_mappers
erpnext.patches.v11_0.make_quality_inspection_template erpnext.patches.v11_0.make_quality_inspection_template
erpnext.patches.v10_0.update_status_for_multiple_source_in_po erpnext.patches.v10_0.update_status_for_multiple_source_in_po
@ -579,6 +579,7 @@ erpnext.patches.v10_0.update_user_image_in_employee
erpnext.patches.v11_0.update_delivery_trip_status erpnext.patches.v11_0.update_delivery_trip_status
erpnext.patches.v10_0.repost_gle_for_purchase_receipts_with_rejected_items 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.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_learn_to_help
erpnext.patches.v12_0.rename_accounts_desktop_icon_to_accounting erpnext.patches.v12_0.rename_accounts_desktop_icon_to_accounting
erpnext.patches.v12_0.replace_project_list_desktop_icon_with_projects_module_desktop_icon erpnext.patches.v12_0.replace_project_list_desktop_icon_with_projects_module_desktop_icon

View File

@ -6,37 +6,36 @@ import frappe
def execute(): def execute():
frappe.reload_doc("hr", "doctype", "daily_work_summary_group") if not frappe.db.table_exists('Daily Work Summary Group'):
frappe.reload_doc("hr", "doctype", "daily_work_summary_group_user") 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 # check if Daily Work Summary Settings Company table exists
try: try:
frappe.db.sql('DESC `tabDaily Work Summary Settings Company`') frappe.db.sql('DESC `tabDaily Work Summary Settings Company`')
except Exception: except Exception:
return return
# get the previously saved settings # get the previously saved settings
previous_setting = get_previous_setting() previous_setting = get_previous_setting()
if previous_setting["companies"]: if previous_setting["companies"]:
for d in previous_setting["companies"]: for d in previous_setting["companies"]:
users = frappe.get_list("Employee", dict( users = frappe.get_list("Employee", dict(
company=d.company, user_id=("!=", " ")), "user_id as user") company=d.company, user_id=("!=", " ")), "user_id as user")
if(len(users)): if(len(users)):
# create new group entry for each company entry # create new group entry for each company entry
new_group = frappe.get_doc(dict(doctype="Daily Work Summary Group", new_group = frappe.get_doc(dict(doctype="Daily Work Summary Group",
name="Daily Work Summary for " + d.company, name="Daily Work Summary for " + d.company,
users=users, users=users,
send_emails_at=d.send_emails_at, send_emails_at=d.send_emails_at,
subject=previous_setting["subject"], subject=previous_setting["subject"],
message=previous_setting["message"])) message=previous_setting["message"]))
new_group.flags.ignore_permissions = True new_group.flags.ignore_permissions = True
new_group.flags.ignore_validate = True new_group.flags.ignore_validate = True
new_group.insert(ignore_if_duplicate = True) new_group.insert(ignore_if_duplicate = True)
frappe.delete_doc("Daily Work Summary Settings")
frappe.delete_doc("Daily Work Summary Settings Company")
def get_setting_companies(): frappe.delete_doc("DocType", "Daily Work Summary Settings")
return frappe.db.sql("select * from `tabDaily Work Summary Settings Company`", as_dict=True) frappe.delete_doc("DocType", "Daily Work Summary Settings Company")
def get_previous_setting(): def get_previous_setting():
@ -47,3 +46,6 @@ def get_previous_setting():
obj[field] = value obj[field] = value
obj["companies"] = get_setting_companies() obj["companies"] = get_setting_companies()
return obj return obj
def get_setting_companies():
return frappe.db.sql("select * from `tabDaily Work Summary Settings Company`", as_dict=True)

View File

@ -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))

View File

@ -1,28 +1,60 @@
import frappe 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 # Skips user permission check for doctypes where department link field was recently added
# https://github.com/frappe/erpnext/pull/14121 # https://github.com/frappe/erpnext/pull/14121
def execute(): def execute():
user_permissions = frappe.get_all("User Permission", doctypes_to_skip = []
filters=[['allow', '=', 'Department']], for doctype in ['Appraisal', 'Leave Allocation', 'Expense Claim', 'Instructor', 'Salary Slip',
fields=['name', 'skip_for_doctype']) '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', user_permissions = frappe.get_all("User Permission",
'Attendance', 'Training Feedback', 'Training Result Employee', filters=[['allow', '=', 'Department'], ['applicable_for', 'in', [None] + doctypes_to_skip]],
'Leave Application', 'Employee Advance', 'Activity Cost', 'Training Event Employee', fields=['name', 'applicable_for'])
'Timesheet', 'Sales Person', 'Payroll Employee Detail']:
if frappe.db.exists('Custom Field', { 'dt': doctype, 'fieldname': 'department'}): continue
doctypes_to_skip.append(doctype)
for perm in user_permissions: user_permissions_to_delete = []
skip_for_doctype = perm.get('skip_for_doctype') new_user_permissions_list = []
skip_for_doctype = skip_for_doctype.split('\n') + doctypes_to_skip for user_permission in user_permissions:
skip_for_doctype = set(skip_for_doctype) # to remove duplicates if user_permission.applicable_for:
skip_for_doctype = '\n'.join(skip_for_doctype) # convert back to string # 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))

View File

@ -6,7 +6,7 @@ import frappe
def execute(): def execute():
frappe.reload_doc('stock', 'doctype', 'item') 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""") where ifnull(is_stock_item, 0) = 1""")
for doctype in ['BOM Item', 'Work Order Item', 'BOM Explosion Item']: for doctype in ['BOM Item', 'Work Order Item', 'BOM Explosion Item']:
@ -14,7 +14,7 @@ def execute():
frappe.db.sql(""" update `tab{0}` child, tabItem item frappe.db.sql(""" update `tab{0}` child, tabItem item
set set
child.allow_transfer_for_manufacture = 1 child.include_item_in_manufacturing = 1
where where
child.item_code = item.name and ifnull(item.is_stock_item, 0) = 1 child.item_code = item.name and ifnull(item.is_stock_item, 0) = 1
""".format(doctype)) """.format(doctype))

View File

@ -16,7 +16,7 @@ from six import iteritems
class Project(Document): class Project(Document):
def get_feed(self): 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): def onload(self):
"""Load project tasks for quick view""" """Load project tasks for quick view"""
@ -76,7 +76,7 @@ class Project(Document):
def validate_project_name(self): def validate_project_name(self):
if self.get("__islocal") and frappe.db.exists("Project", self.project_name): 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): def validate_dates(self):
if self.expected_start_date and self.expected_end_date: if self.expected_start_date and self.expected_end_date:
@ -258,13 +258,13 @@ class Project(Document):
self.total_purchase_cost = total_purchase_cost and total_purchase_cost[0][0] or 0 self.total_purchase_cost = total_purchase_cost and total_purchase_cost[0][0] or 0
def update_sales_amount(self): 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) 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 self.total_sales_amount = total_sales_amount and total_sales_amount[0][0] or 0
def update_billed_amount(self): 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) 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 self.total_billed_amount = total_billed_amount and total_billed_amount[0][0] or 0

View File

@ -97,6 +97,9 @@ erpnext.setup.slides_settings = [
if (!this.values.company_abbr) { if (!this.values.company_abbr) {
return false; return false;
} }
if (this.values.company_abbr.length > 5) {
return false;
}
return true; return true;
} }
}, },

View File

@ -237,7 +237,7 @@ $.extend(erpnext.utils, {
let unscrub_option = frappe.model.unscrub(option); let unscrub_option = frappe.model.unscrub(option);
let user_permission = frappe.defaults.get_user_permissions(); let user_permission = frappe.defaults.get_user_permissions();
if(user_permission && user_permission[unscrub_option]) { if(user_permission && user_permission[unscrub_option]) {
return user_permission[unscrub_option]["docs"]; return user_permission[unscrub_option].map(perm => perm.doc);
} else { } else {
return $.map(locals[`:${unscrub_option}`], function(c) { return c.name; }).sort(); return $.map(locals[`:${unscrub_option}`], function(c) { return c.name; }).sort();
} }

View File

View File

@ -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();
}
});
}
}
});

View File

@ -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
}

View File

@ -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

View File

@ -0,0 +1,12 @@
from frappe import _
def get_data():
return {
'fieldname': 'feedback',
'transactions': [
{
'label': _('Action'),
'items': ['Quality Action']
}
],
}

View File

@ -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"];
}
}
};

View File

@ -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()
]);
});

View File

@ -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()

View File

@ -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
}

View File

@ -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

View File

@ -0,0 +1,5 @@
// Copyright (c) 2018, Frappe and contributors
// For license information, please see license.txt
frappe.ui.form.on('Customer Feedback Template', {
});

View File

@ -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
}

View File

@ -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

View File

@ -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()
]);
});

View File

@ -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]

View File

@ -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
}

View File

@ -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

View File

@ -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();
}
}
});

View File

@ -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
}

View File

@ -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'

View File

@ -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"];
}
}
};

View File

@ -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()
]);
});

View File

@ -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]

View File

@ -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
}

View File

@ -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

View File

@ -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();
}

View File

@ -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
}

View File

@ -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

View File

@ -0,0 +1,16 @@
from frappe import _
def get_data():
return {
'fieldname': 'goal',
'transactions': [
{
'label': _('Review'),
'items': ['Quality Review']
},
{
'label': _('Action'),
'items': ['Quality Action']
}
]
}

View File

@ -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()
]);
});

View File

@ -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()

View File

@ -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();
}
});

View File

@ -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
}

View File

@ -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'

View File

@ -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"];
}
}
};

View File

@ -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()
]);
});

View File

@ -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]

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -0,0 +1,5 @@
// Copyright (c) 2018, Frappe and contributors
// For license information, please see license.txt
frappe.ui.form.on('Quality Procedure', {
});

View File

@ -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
}

View File

@ -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()

View File

@ -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']
}
],
}

View File

@ -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();
}
};

Some files were not shown because too many files have changed in this diff Show More