feat(quality): Check quality status before receipt/delivery (#16169)
This commit is contained in:
parent
78bc405eeb
commit
5a9579bae4
@ -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]))
|
||||||
|
@ -392,4 +392,3 @@ def create_item(item_code, is_stock_item=None, valuation_rate=0, warehouse=None)
|
|||||||
"company": "_Test Company"
|
"company": "_Test Company"
|
||||||
})
|
})
|
||||||
item.save()
|
item.save()
|
||||||
|
|
||||||
|
@ -3,8 +3,45 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
import unittest
|
import unittest
|
||||||
|
from frappe.utils import nowdate
|
||||||
|
from erpnext.stock.doctype.item.test_item import create_item
|
||||||
|
from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
|
||||||
|
from erpnext.controllers.stock_controller import QualityInspectionRejectedError, QualityInspectionRequiredError
|
||||||
|
|
||||||
# test_records = frappe.get_test_records('Quality Inspection')
|
# test_records = frappe.get_test_records('Quality Inspection')
|
||||||
|
|
||||||
class TestQualityInspection(unittest.TestCase):
|
class TestQualityInspection(unittest.TestCase):
|
||||||
pass
|
def setUp(self):
|
||||||
|
create_item("_Test Item with QA")
|
||||||
|
frappe.db.set_value("Item", "_Test Item with QA", "inspection_required_before_delivery", 1)
|
||||||
|
|
||||||
|
def test_qa_for_delivery(self):
|
||||||
|
dn = create_delivery_note(item_code="_Test Item with QA", do_not_submit=True)
|
||||||
|
self.assertRaises(QualityInspectionRequiredError, dn.submit)
|
||||||
|
|
||||||
|
qa = create_quality_inspection(reference_type="Delivery Note", reference_name=dn.name, status="Rejected")
|
||||||
|
dn.reload()
|
||||||
|
self.assertRaises(QualityInspectionRejectedError, dn.submit)
|
||||||
|
|
||||||
|
frappe.db.set_value("Quality Inspection Reading", {"parent": qa.name}, "status", "Accepted")
|
||||||
|
dn.reload()
|
||||||
|
dn.submit()
|
||||||
|
|
||||||
|
def create_quality_inspection(**args):
|
||||||
|
args = frappe._dict(args)
|
||||||
|
qa = frappe.new_doc("Quality Inspection")
|
||||||
|
qa.report_date = nowdate()
|
||||||
|
qa.inspection_type = args.inspection_type or "Outgoing"
|
||||||
|
qa.reference_type = args.reference_type
|
||||||
|
qa.reference_name = args.reference_name
|
||||||
|
qa.item_code = args.item_code or "_Test Item with QA"
|
||||||
|
qa.sample_size = 1
|
||||||
|
qa.inspected_by = frappe.session.user
|
||||||
|
qa.append("readings", {
|
||||||
|
"specification": "Size",
|
||||||
|
"status": args.status
|
||||||
|
})
|
||||||
|
qa.save()
|
||||||
|
qa.submit()
|
||||||
|
|
||||||
|
return qa
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>{{ item }}</td>
|
<td>{{ item }}</td>
|
||||||
<td class='text-right'>
|
<td class='text-right'>
|
||||||
{{ frappe.utils.fmt_money(itemised_taxable_amount.get(item), None, currency) }}
|
{{ frappe.utils.fmt_money(itemised_taxable_amount.get(item, 0), None, currency) }}
|
||||||
</td>
|
</td>
|
||||||
{% for tax_account in tax_accounts %}
|
{% for tax_account in tax_accounts %}
|
||||||
{% set tax_details = taxes.get(tax_account) %}
|
{% set tax_details = taxes.get(tax_account) %}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user