mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-06 21:59:13 +00:00
Clinical Procedure - Consumables Invoice Separately
This commit is contained in:
@@ -264,21 +264,20 @@ frappe.ui.form.on('Clinical Procedure Item', {
|
|||||||
let args = null;
|
let args = null;
|
||||||
if(d.item_code) {
|
if(d.item_code) {
|
||||||
args = {
|
args = {
|
||||||
'item_code' : d.item_code,
|
'doctype' : "Clinical Procedure",
|
||||||
'transfer_qty' : d.transfer_qty,
|
'item_code' : d.item_code,
|
||||||
'company' : frm.doc.company,
|
'company' : frm.doc.company,
|
||||||
'quantity' : d.qty
|
'warehouse': frm.doc.warehouse
|
||||||
};
|
};
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
doc: frm.doc,
|
method: "erpnext.stock.get_item_details.get_item_details",
|
||||||
method: "get_item_details",
|
args: {args: args},
|
||||||
args: args,
|
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
if(r.message) {
|
if(r.message) {
|
||||||
var d = locals[cdt][cdn];
|
frappe.model.set_value(cdt, cdn, "item_name", r.message.item_name);
|
||||||
$.each(r.message, function(k, v){
|
frappe.model.set_value(cdt, cdn, "stock_uom", r.message.stock_uom);
|
||||||
d[k] = v;
|
frappe.model.set_value(cdt, cdn, "conversion_factor", r.message.conversion_factor);
|
||||||
});
|
frappe.model.set_value(cdt, cdn, "actual_qty", r.message.actual_qty);
|
||||||
refresh_field("items");
|
refresh_field("items");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -704,6 +704,139 @@
|
|||||||
"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": "0",
|
||||||
|
"fieldname": "invoice_separately_as_consumables",
|
||||||
|
"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": "Consumables Invoice Separately",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"depends_on": "invoice_separately_as_consumables",
|
||||||
|
"fieldname": "consumable_total_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"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": "Consumable Total Amount",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 1,
|
||||||
|
"remember_last_selected_value": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"translatable": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_bulk_edit": 0,
|
||||||
|
"allow_in_quick_entry": 0,
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"columns": 0,
|
||||||
|
"depends_on": "invoice_separately_as_consumables",
|
||||||
|
"fieldname": "consumption_details",
|
||||||
|
"fieldtype": "Small Text",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_global_search": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"in_standard_filter": 0,
|
||||||
|
"label": "Consumption Details",
|
||||||
|
"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": "0",
|
||||||
|
"depends_on": "invoice_separately_as_consumables",
|
||||||
|
"fieldname": "consumption_invoiced",
|
||||||
|
"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": "Consumption Invoiced",
|
||||||
|
"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_bulk_edit": 0,
|
||||||
"allow_in_quick_entry": 0,
|
"allow_in_quick_entry": 0,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from frappe.utils import cint, flt, nowdate, nowtime
|
|||||||
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_account
|
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_account
|
||||||
from erpnext.healthcare.doctype.lab_test.lab_test import create_sample_doc
|
from erpnext.healthcare.doctype.lab_test.lab_test import create_sample_doc
|
||||||
from erpnext.stock.stock_ledger import get_previous_sle
|
from erpnext.stock.stock_ledger import get_previous_sle
|
||||||
|
from erpnext.stock.get_item_details import get_item_details
|
||||||
|
|
||||||
class ClinicalProcedure(Document):
|
class ClinicalProcedure(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
@@ -18,6 +19,12 @@ class ClinicalProcedure(Document):
|
|||||||
frappe.throw(("Set warehouse for Procedure {0} ").format(self.name))
|
frappe.throw(("Set warehouse for Procedure {0} ").format(self.name))
|
||||||
self.set_actual_qty()
|
self.set_actual_qty()
|
||||||
|
|
||||||
|
if self.items:
|
||||||
|
self.invoice_separately_as_consumables = False
|
||||||
|
for item in self.items:
|
||||||
|
if item.invoice_separately_as_consumables == 1:
|
||||||
|
self.invoice_separately_as_consumables = True
|
||||||
|
|
||||||
def before_insert(self):
|
def before_insert(self):
|
||||||
if self.consume_stock:
|
if self.consume_stock:
|
||||||
set_stock_items(self, self.procedure_template, "Clinical Procedure Template")
|
set_stock_items(self, self.procedure_template, "Clinical Procedure Template")
|
||||||
@@ -40,6 +47,36 @@ class ClinicalProcedure(Document):
|
|||||||
create_stock_entry(self)
|
create_stock_entry(self)
|
||||||
frappe.db.set_value("Clinical Procedure", self.name, "status", 'Completed')
|
frappe.db.set_value("Clinical Procedure", self.name, "status", 'Completed')
|
||||||
|
|
||||||
|
if self.items:
|
||||||
|
consumable_total_amount = 0
|
||||||
|
consumption_details = False
|
||||||
|
for item in self.items:
|
||||||
|
if item.invoice_separately_as_consumables:
|
||||||
|
price_list, price_list_currency = frappe.db.get_values("Price List", {"selling": 1}, ['name', 'currency'])[0]
|
||||||
|
args = {
|
||||||
|
'doctype': "Sales Invoice",
|
||||||
|
'item_code': item.item_code,
|
||||||
|
'company': self.company,
|
||||||
|
'warehouse': self.warehouse,
|
||||||
|
'customer': frappe.db.get_value("Patient", self.patient, "customer"),
|
||||||
|
'selling_price_list': price_list,
|
||||||
|
'price_list_currency': price_list_currency,
|
||||||
|
'plc_conversion_rate': 1.0,
|
||||||
|
'conversion_rate': 1.0
|
||||||
|
}
|
||||||
|
item_details = get_item_details(args)
|
||||||
|
item_price = item_details.price_list_rate * item.transfer_qty
|
||||||
|
item_consumption_details = item_details.item_name+"\t"+str(item.qty)+" "+item.uom+"\t"+str(item_price)
|
||||||
|
consumable_total_amount += item_price
|
||||||
|
if not consumption_details:
|
||||||
|
consumption_details = "Clinical Procedure ("+self.name+"):\n\t"+item_consumption_details
|
||||||
|
else:
|
||||||
|
consumption_details += "\n\t"+item_consumption_details
|
||||||
|
if consumable_total_amount > 0:
|
||||||
|
frappe.db.set_value("Clinical Procedure", self.name, "consumable_total_amount", consumable_total_amount)
|
||||||
|
frappe.db.set_value("Clinical Procedure", self.name, "consumption_details", consumption_details)
|
||||||
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
allow_start = self.set_actual_qty()
|
allow_start = self.set_actual_qty()
|
||||||
if allow_start:
|
if allow_start:
|
||||||
@@ -54,16 +91,7 @@ class ClinicalProcedure(Document):
|
|||||||
|
|
||||||
allow_start = True
|
allow_start = True
|
||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
previous_sle = get_previous_sle({
|
d.actual_qty = get_stock_qty(d.item_code, self.warehouse)
|
||||||
"item_code": d.item_code,
|
|
||||||
"warehouse": self.warehouse,
|
|
||||||
"posting_date": nowdate(),
|
|
||||||
"posting_time": nowtime()
|
|
||||||
})
|
|
||||||
|
|
||||||
# get actual stock at source warehouse
|
|
||||||
d.actual_qty = previous_sle.get("qty_after_transaction") or 0
|
|
||||||
|
|
||||||
# validate qty
|
# validate qty
|
||||||
if not allow_negative_stock and d.actual_qty < d.qty:
|
if not allow_negative_stock and d.actual_qty < d.qty:
|
||||||
allow_start = False
|
allow_start = False
|
||||||
@@ -93,28 +121,14 @@ class ClinicalProcedure(Document):
|
|||||||
se_child.expense_account = expense_account
|
se_child.expense_account = expense_account
|
||||||
return stock_entry.as_dict()
|
return stock_entry.as_dict()
|
||||||
|
|
||||||
def get_item_details(self, args=None):
|
@frappe.whitelist()
|
||||||
item = frappe.db.sql("""select stock_uom, description, image, item_name,
|
def get_stock_qty(item_code, warehouse):
|
||||||
expense_account, buying_cost_center, item_group from `tabItem`
|
return get_previous_sle({
|
||||||
where name = %s
|
"item_code": item_code,
|
||||||
and disabled=0
|
"warehouse": warehouse,
|
||||||
and (end_of_life is null or end_of_life='0000-00-00' or end_of_life > %s)""",
|
"posting_date": nowdate(),
|
||||||
(args.get('item_code'), nowdate()), as_dict = 1)
|
"posting_time": nowtime()
|
||||||
if not item:
|
}).get("qty_after_transaction") or 0
|
||||||
frappe.throw(_("Item {0} is not active or end of life has been reached").format(args.get('item_code')))
|
|
||||||
|
|
||||||
item = item[0]
|
|
||||||
|
|
||||||
ret = {
|
|
||||||
'uom' : item.stock_uom,
|
|
||||||
'stock_uom' : item.stock_uom,
|
|
||||||
'item_name' : item.item_name,
|
|
||||||
'quantity' : 0,
|
|
||||||
'transfer_qty' : 0,
|
|
||||||
'conversion_factor' : 1
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def set_stock_items(doc, stock_detail_parent, parenttype):
|
def set_stock_items(doc, stock_detail_parent, parenttype):
|
||||||
|
|||||||
Reference in New Issue
Block a user