From 5607762c0fdc7496f36136a461318b5a80a5cdba Mon Sep 17 00:00:00 2001 From: Andrew McLeod Date: Fri, 16 Nov 2018 11:08:39 +0000 Subject: [PATCH 01/31] fix/feat: Allow extension of barcode types (without validation) Currently, it is difficult to add new custom barcode types for two reasons, both of which relate to validate_barcode in item.py: - There is a bug where barcode types with a space in, such as Code 128, are split in two (so barcode_type is checked against 'Code' and '128' rather than 'Code 128'). This is fixed by splitting the Options field against a newline, instead of spaces. - All barcodes are validated against the stdnum.ean library. This only handles EAN-8, EAN-13 and UPC-12 barcodes and any other barcode will fail. Barcodes with no type will continue to not be checked. Barcodes with the default barcode_types of EAN, UPC will continue to be checked. The non-default barcode_types of EAN-13 and EAN-8 will also be checked. The barcode_type is cast to upper case before this check is made so ean, upc, ean-13 and ean-8 will also be validated. This allows people to add their own barcode types, such as Code 128 and QR codes. Users can add custom validation of these barcodes using the usual hooks, but they cannot remove the standard validation. --- erpnext/stock/doctype/item/item.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index 17cf044074..294e26d80f 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -502,7 +502,7 @@ class Item(WebsiteGenerator): from stdnum import ean if len(self.barcodes) > 0: for item_barcode in self.barcodes: - options = frappe.get_meta("Item Barcode").get_options("barcode_type").split() + options = frappe.get_meta("Item Barcode").get_options("barcode_type").split('\n') if item_barcode.barcode: duplicate = frappe.db.sql( """select parent from `tabItem Barcode` where barcode = %s and parent != %s""", (item_barcode.barcode, self.name)) @@ -511,7 +511,7 @@ class Item(WebsiteGenerator): item_barcode.barcode, duplicate[0][0])) item_barcode.barcode_type = "" if item_barcode.barcode_type not in options else item_barcode.barcode_type - if item_barcode.barcode_type: + if item_barcode.barcode_type and item_barcode.barcode_type.upper() in ('EAN', 'UPC-A', 'EAN-13', 'EAN-8'): if not ean.is_valid(item_barcode.barcode): frappe.throw(_("Barcode {0} is not a valid {1} code").format( item_barcode.barcode, item_barcode.barcode_type)) From f99a68a69507173f3cdfc814cb1010cc7cdb7773 Mon Sep 17 00:00:00 2001 From: Andrew McLeod Date: Fri, 16 Nov 2018 13:55:55 +0000 Subject: [PATCH 02/31] feat: Added unit testing for Item Barcodes in item.py Adds three different barcodes and barcodes types to a test item and checks that they are added correctly. Adds a barcode that already exists, and checks a DuplicateEntryError is raised. Adds an invalid EAN barcode and checks InvalidBarcode (a subclass of ValidationError) is raised. --- erpnext/stock/doctype/item/item.py | 8 +++- erpnext/stock/doctype/item/test_item.py | 61 ++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py index 294e26d80f..566b6386fe 100644 --- a/erpnext/stock/doctype/item/item.py +++ b/erpnext/stock/doctype/item/item.py @@ -32,6 +32,10 @@ class StockExistsForTemplate(frappe.ValidationError): pass +class InvalidBarcode(frappe.ValidationError): + pass + + class Item(WebsiteGenerator): website = frappe._dict( page_title_field="item_name", @@ -508,13 +512,13 @@ class Item(WebsiteGenerator): """select parent from `tabItem Barcode` where barcode = %s and parent != %s""", (item_barcode.barcode, self.name)) if duplicate: frappe.throw(_("Barcode {0} already used in Item {1}").format( - item_barcode.barcode, duplicate[0][0])) + item_barcode.barcode, duplicate[0][0]), frappe.DuplicateEntryError) item_barcode.barcode_type = "" if item_barcode.barcode_type not in options else item_barcode.barcode_type if item_barcode.barcode_type and item_barcode.barcode_type.upper() in ('EAN', 'UPC-A', 'EAN-13', 'EAN-8'): if not ean.is_valid(item_barcode.barcode): frappe.throw(_("Barcode {0} is not a valid {1} code").format( - item_barcode.barcode, item_barcode.barcode_type)) + item_barcode.barcode, item_barcode.barcode_type), InvalidBarcode) def validate_warehouse_for_reorder(self): '''Validate Reorder level table for duplicate and conditional mandatory''' diff --git a/erpnext/stock/doctype/item/test_item.py b/erpnext/stock/doctype/item/test_item.py index 7ef4f8cecc..24292f7b4f 100644 --- a/erpnext/stock/doctype/item/test_item.py +++ b/erpnext/stock/doctype/item/test_item.py @@ -8,7 +8,7 @@ import frappe from frappe.test_runner import make_test_objects from erpnext.controllers.item_variant import (create_variant, ItemVariantExistsError, InvalidItemAttributeValueError, get_variant) -from erpnext.stock.doctype.item.item import StockExistsForTemplate +from erpnext.stock.doctype.item.item import StockExistsForTemplate, InvalidBarcode from erpnext.stock.doctype.item.item import get_uom_conv_factor from frappe.model.rename_doc import rename_doc from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry @@ -305,6 +305,65 @@ class TestItem(unittest.TestCase): item_doc.has_variants = 1 self.assertRaises(StockExistsForTemplate, item_doc.save) + def test_add_item_barcode(self): + # Clean up + frappe.db.sql("""delete from `tabItem Barcode`""") + item_code = "Test Item Barcode" + if frappe.db.exists("Item", item_code): + frappe.delete_doc("Item", item_code) + + # Create new item and add barcodes + barcode_properties_list = [ + { + "barcode": "0012345678905", + "barcode_type": "EAN" + }, + { + "barcode": "012345678905", + "barcode_type": "UAN" + }, + { + "barcode": "ARBITRARY_TEXT", + } + ] + create_item(item_code) + for barcode_properties in barcode_properties_list: + item_doc = frappe.get_doc('Item', item_code) + new_barcode = item_doc.append('barcodes') + new_barcode.update(barcode_properties) + item_doc.save() + + # Check values saved correctly + barcodes = frappe.get_list( + 'Item Barcode', + fields=['barcode', 'barcode_type'], + filters={'parent': item_code}) + + for barcode_properties in barcode_properties_list: + barcode_to_find = barcode_properties['barcode'] + matching_barcodes = [ + x for x in barcodes + if x['barcode'] == barcode_to_find + ] + self.assertEqual(len(matching_barcodes), 1) + details = matching_barcodes[0] + + for key, value in iteritems(barcode_properties): + self.assertEqual(value, details.get(key)) + + # Add barcode again - should cause DuplicateEntryError + item_doc = frappe.get_doc('Item', item_code) + new_barcode = item_doc.append('barcodes') + new_barcode.update(barcode_properties_list[0]) + self.assertRaises(frappe.DuplicateEntryError, item_doc.save) + + # Add invalid barcode - should cause InvalidBarcode + item_doc = frappe.get_doc('Item', item_code) + new_barcode = item_doc.append('barcodes') + new_barcode.barcode = '9999999999999' + new_barcode.barcode_type = 'EAN' + self.assertRaises(InvalidBarcode, item_doc.save) + def set_item_variant_settings(fields): doc = frappe.get_doc('Item Variant Settings') doc.set('fields', fields) From dc3ae114cd2c95b0121bd9c5a767b78c23051d8f Mon Sep 17 00:00:00 2001 From: Jamsheer Date: Wed, 14 Nov 2018 12:37:13 +0530 Subject: [PATCH 03/31] feat: Reschedule - Patient Appointment --- .../patient_appointment.js | 291 ++- .../patient_appointment.json | 1977 +++++++++-------- 2 files changed, 1167 insertions(+), 1101 deletions(-) diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js index 71c8212412..414782a6b7 100644 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js @@ -39,7 +39,9 @@ frappe.ui.form.on('Patient Appointment', { frm.add_custom_button(__('Cancel'), function() { btn_update_status(frm, "Cancelled"); }); - + frm.add_custom_button(__('Reschedule'), function() { + check_and_set_availability(frm); + }); if(frm.doc.procedure_template){ frm.add_custom_button(__("Procedure"),function(){ btn_create_procedure(frm); @@ -59,7 +61,9 @@ frappe.ui.form.on('Patient Appointment', { frm.add_custom_button(__('Cancel'), function() { btn_update_status(frm, "Cancelled"); }); - + frm.add_custom_button(__('Reschedule'), function() { + check_and_set_availability(frm); + }); if(frm.doc.procedure_template){ frm.add_custom_button(__("Procedure"),function(){ btn_create_procedure(frm); @@ -100,117 +104,7 @@ frappe.ui.form.on('Patient Appointment', { }); }, check_availability: function(frm) { - var { practitioner, appointment_date } = frm.doc; - if(!(practitioner && appointment_date)) { - frappe.throw(__("Please select Healthcare Practitioner and Date")); - } - - // show booking modal - frm.call({ - method: 'get_availability_data', - args: { - practitioner: practitioner, - date: appointment_date - }, - callback: (r) => { - var data = r.message; - if(data.slot_details.length > 0){ - show_availability(data); - }else{ - show_empty_state(); - } - } - }); - - function show_empty_state() { - frappe.msgprint({ - title: __('Not Available'), - message: __("Healthcare Practitioner {0} not available on {1}", [practitioner.bold(), appointment_date.bold()]), - indicator: 'red' - }); - } - - function show_availability(data) { - var d = new frappe.ui.Dialog({ - title: __("Available slots"), - fields: [{ fieldtype: 'HTML', fieldname: 'available_slots'}], - primary_action_label: __("Book"), - primary_action: function() { - // book slot - var btn_selected = $wrapper.find('button.btn-selected-slot'); - frm.set_value('appointment_time', btn_selected.attr('data-name')); - frm.set_value('service_unit', btn_selected.attr('data-service-unit') || ''); - frm.set_value('duration', btn_selected.attr('data-duration')); - d.hide(); - frm.enable_save(); - frm.save(); - frm.enable_save(); - } - }); - var $wrapper = d.fields_dict.available_slots.$wrapper; - - // disable dialog action initially - d.get_primary_btn().attr('disabled', true); - - var slot_details = data.slot_details; - var slot_html = ""; - var duration = frm.doc.duration | 0; - $.each(slot_details, function(i, slot_detail){ - slot_html = slot_html + ``; - slot_html = slot_html + `
` + slot_detail['avail_slot'].map(slot => { - let disabled = ''; - let start_str = slot.from_time; - let slot_start_time = moment(slot.from_time, 'HH:mm:ss'); - let slot_to_time = moment(slot.to_time, 'HH:mm:ss'); - let interval = (slot_to_time - slot_start_time)/60000 | 0; - // iterate in all booked appointments, update the start time and duration - slot_detail['appointments'].forEach(function(booked) { - let booked_moment = moment(booked.appointment_time, 'HH:mm:ss'); - let end_time = booked_moment.clone().add(booked.duration, 'minutes'); - // Deal with 0 duration appointments - if(booked_moment.isSame(slot_start_time) || booked_moment.isBetween(slot_start_time, slot_to_time)){ - if(booked.duration == 0){ - disabled = 'disabled="disabled"'; - return false; - } - } - // Check for overlaps considering appointment duration - if(slot_start_time.isBefore(end_time) && slot_to_time.isAfter(booked_moment)){ - // There is an overlap - disabled = 'disabled="disabled"'; - return false; - } - }); - - return ``; - }).join(""); - slot_html = slot_html + `
`; - }); - - $wrapper - .css('margin-bottom', 0) - .addClass('text-center') - .html(slot_html); - - // blue button when clicked - $wrapper.on('click', 'button', function() { - var $btn = $(this); - $wrapper.find('button').removeClass('btn-primary'); - $wrapper.find('button').removeClass('btn-selected-slot'); - $btn.addClass('btn-primary'); - $btn.addClass('btn-selected-slot'); - // enable dialog action - d.get_primary_btn().attr('disabled', null); - }); - - d.show(); - } + check_and_set_availability(frm) }, onload:function(frm){ if(frm.is_new()) { @@ -223,6 +117,177 @@ frappe.ui.form.on('Patient Appointment', { } }); +var check_and_set_availability = function(frm) { + var selected_slot = null; + var service_unit = null; + var duration = null; + var { patient } = frm.doc; + + show_availability() + + function show_empty_state(practitioner, appointment_date) { + frappe.msgprint({ + title: __('Not Available'), + message: __("Healthcare Practitioner {0} not available on {1}", [practitioner.bold(), appointment_date.bold()]), + indicator: 'red' + }); + } + + function show_availability(data) { + let selected_practitioner = ''; + var d = new frappe.ui.Dialog({ + title: __("Available slots"), + fields: [ + { fieldtype: 'Link', options: 'Medical Department', reqd:1, fieldname: 'department', label: 'Medical Department'}, + { fieldtype: 'Column Break'}, + { fieldtype: 'Link', options: 'Healthcare Practitioner', reqd:1, fieldname: 'practitioner', label: 'Healthcare Practitioner'}, + { fieldtype: 'Column Break'}, + { fieldtype: 'Date', reqd:1, fieldname: 'appointment_date', label: 'Date'}, + { fieldtype: 'Section Break'}, + { fieldtype: 'HTML', fieldname: 'available_slots'} + ], + primary_action_label: __("Book"), + primary_action: function() { + frm.set_value('appointment_time', selected_slot); + frm.set_value('service_unit', service_unit || ''); + frm.set_value('duration', duration); + frm.set_value('practitioner', d.get_value('practitioner')); + frm.set_value('department', d.get_value('department')); + frm.set_value('appointment_date', d.get_value('appointment_date')); + d.hide(); + frm.enable_save(); + frm.save(); + frm.enable_save(); + d.get_primary_btn().attr('disabled', true); + } + }); + + d.set_values({ + 'department': frm.doc.department, + 'practitioner': frm.doc.practitioner, + 'appointment_date': frm.doc.appointment_date + }); + + d.fields_dict["department"].df.onchange = () => { + d.set_values({ + 'practitioner': '' + }); + var department = d.get_value('department'); + if(department){ + d.fields_dict.practitioner.get_query = function() { + return { + filters: { + "department": department + } + } + } + } + } + + // disable dialog action initially + d.get_primary_btn().attr('disabled', true); + + // Field Change Handler + + var fd = d.fields_dict; + + d.fields_dict["appointment_date"].df.onchange = () => { + show_slots(d, fd); + } + d.fields_dict["practitioner"].df.onchange = () => { + if(d.get_value('practitioner') && d.get_value('practitioner') != selected_practitioner){ + selected_practitioner = d.get_value('practitioner'); + show_slots(d, fd); + } + } + d.show(); + } + + function show_slots(d, fd) { + if (d.get_value('appointment_date') && d.get_value('practitioner')){ + fd.available_slots.html("") + frappe.call({ + method: 'erpnext.healthcare.doctype.patient_appointment.patient_appointment.get_availability_data', + args: { + practitioner: d.get_value('practitioner'), + date: d.get_value('appointment_date') + }, + callback: (r) => { + var data = r.message; + if(data.slot_details.length > 0) { + var $wrapper = d.fields_dict.available_slots.$wrapper; + + // make buttons for each slot + var slot_details = data.slot_details; + var slot_html = ""; + for (let i = 0; i < slot_details.length; i++) { + slot_html = slot_html + ``; + slot_html = slot_html + `
` + slot_details[i].avail_slot.map(slot => { + let disabled = ''; + let start_str = slot.from_time; + let slot_start_time = moment(slot.from_time, 'HH:mm:ss'); + let slot_to_time = moment(slot.to_time, 'HH:mm:ss'); + let interval = (slot_to_time - slot_start_time)/60000 | 0; + //iterate in all booked appointments, update the start time and duration + slot_details[i].appointments.forEach(function(booked) { + let booked_moment = moment(booked.appointment_time, 'HH:mm:ss'); + let end_time = booked_moment.clone().add(booked.duration, 'minutes'); + // Deal with 0 duration appointments + if(booked_moment.isSame(slot_start_time) || booked_moment.isBetween(slot_start_time, slot_to_time)){ + if(booked.duration == 0){ + disabled = 'disabled="disabled"'; + return false; + } + } + // Check for overlaps considering appointment duration + if(slot_start_time.isBefore(end_time) && slot_to_time.isAfter(booked_moment)){ + // There is an overlap + disabled = 'disabled="disabled"'; + return false; + } + }); + return ``; + }).join(""); + slot_html = slot_html + `
`; + } + + $wrapper + .css('margin-bottom', 0) + .addClass('text-center') + .html(slot_html); + + // blue button when clicked + $wrapper.on('click', 'button', function() { + var $btn = $(this); + $wrapper.find('button').removeClass('btn-primary'); + $btn.addClass('btn-primary'); + selected_slot = $btn.attr('data-name'); + service_unit = $btn.attr('data-service-unit') + duration = $btn.attr('data-duration') + // enable dialog action + d.get_primary_btn().attr('disabled', null); + }); + + }else { + // fd.available_slots.html("Please select a valid date.".bold()) + show_empty_state(d.get_value('practitioner'), d.get_value('appointment_date')); + } + }, + freeze: true, + freeze_message: __("Fetching records......") + }); + }else{ + fd.available_slots.html("Appointment date and Healthcare Practitioner are Mandatory".bold()) + } + } +} + var get_procedure_prescribed = function(frm){ if(frm.doc.patient){ frappe.call({ diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json index cef49d730b..7f79989f0d 100644 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json @@ -1,1058 +1,1059 @@ { - "allow_copy": 1, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 0, - "autoname": "HLC-APP-.YYYY.-.#####", - "beta": 1, - "creation": "2017-05-04 11:52:40.941507", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "Document", - "editable_grid": 0, - "engine": "InnoDB", + "allow_copy": 1, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 1, + "allow_rename": 0, + "autoname": "OP-.######", + "beta": 1, + "creation": "2017-05-04 11:52:40.941507", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "Document", + "editable_grid": 0, + "engine": "InnoDB", "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "patient.inpatient_record", - "fieldname": "inpatient_record", - "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": "Inpatient Record", - "length": 0, - "no_copy": 0, - "options": "Inpatient Record", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_from": "patient.inpatient_record", + "fieldname": "inpatient_record", + "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": "Inpatient Record", + "length": 0, + "no_copy": 0, + "options": "Inpatient Record", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "inpatient_record.patient", - "fieldname": "patient", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Patient", - "length": 0, - "no_copy": 0, - "options": "Patient", - "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": 1, - "set_only_once": 1, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_from": "inpatient_record.patient", + "fieldname": "patient", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 1, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Patient", + "length": 0, + "no_copy": 0, + "options": "Patient", + "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": 1, + "set_only_once": 1, + "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": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Department", - "length": 0, - "no_copy": 0, - "options": "Medical 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": 1, - "set_only_once": 1, - "translatable": 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": 1, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Department", + "length": 0, + "no_copy": 0, + "options": "Medical Department", + "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": 1, + "set_only_once": 1, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "practitioner", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Healthcare Practitioner", - "length": 0, - "no_copy": 0, - "options": "Healthcare Practitioner", - "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": 1, - "set_only_once": 1, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "practitioner", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 1, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Healthcare Practitioner", + "length": 0, + "no_copy": 0, + "options": "Healthcare Practitioner", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 1, + "set_only_once": 1, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "get_procedure_from_encounter", - "fieldtype": "Button", - "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": "Get prescribed procedures", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "get_procedure_from_encounter", + "fieldtype": "Button", + "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": "Get prescribed procedures", + "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_prescription", - "fieldtype": "Link", - "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": "Procedure Prescription", - "length": 0, - "no_copy": 1, - "options": "Procedure Prescription", - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "procedure_prescription", + "fieldtype": "Link", + "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": "Procedure Prescription", + "length": 0, + "no_copy": 1, + "options": "Procedure Prescription", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "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_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": "Procedure", - "length": 0, - "no_copy": 0, - "options": "Clinical Procedure 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": 1, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "procedure_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": "Procedure", + "length": 0, + "no_copy": 0, + "options": "Clinical Procedure 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": 1, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "appointment_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 1, - "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": 1, - "search_index": 1, - "set_only_once": 1, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "appointment_date", + "fieldtype": "Date", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 1, + "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": 1, + "search_index": 1, + "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": "appointment_time", - "fieldtype": "Time", - "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": "Time", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.__islocal", + "fieldname": "check_availability", + "fieldtype": "Button", + "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": "Check availability", + "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, - "description": "In Minutes", - "fieldname": "duration", - "fieldtype": "Int", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 1, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Duration", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "appointment_time", + "fieldtype": "Time", + "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": "Time", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:doc.__islocal", - "fieldname": "check_availability", - "fieldtype": "Button", - "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": "Check availability", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "description": "In Minutes", + "fieldname": "duration", + "fieldtype": "Int", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 1, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Duration", + "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_1", - "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, - "label": "", - "length": 0, - "no_copy": 0, - "options": "", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break_1", + "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, + "label": "", + "length": 0, + "no_copy": 0, + "options": "", + "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": "service_unit", - "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": "Service Unit", - "length": 0, - "no_copy": 0, - "options": "Healthcare Service Unit", - "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": 1, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "service_unit", + "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": "Service Unit", + "length": 0, + "no_copy": 0, + "options": "Healthcare Service Unit", + "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": 1, + "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": "", - "fetch_from": "patient.patient_name", - "fieldname": "patient_name", - "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": "Patient Name", - "length": 0, - "no_copy": 0, - "options": "", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "", + "fetch_from": "patient.patient_name", + "fieldname": "patient_name", + "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": "Patient Name", + "length": 0, + "no_copy": 0, + "options": "", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "patient.sex", - "fieldname": "patient_sex", - "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": "Gender", - "length": 0, - "no_copy": 1, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 1, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_from": "patient.sex", + "fieldname": "patient_sex", + "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": "Gender", + "length": 0, + "no_copy": 1, + "options": "", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 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": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "patient_age", - "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": "Patient Age", - "length": 0, - "no_copy": 0, - "options": "", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "patient_age", + "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": "Patient Age", + "length": 0, + "no_copy": 0, + "options": "", + "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": "Scheduled", - "fieldname": "status", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 1, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Status", - "length": 0, - "no_copy": 0, - "options": "\nScheduled\nOpen\nClosed\nPending\nCancelled", - "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": 1, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "Scheduled", + "fieldname": "status", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 1, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Status", + "length": 0, + "no_copy": 0, + "options": "\nScheduled\nOpen\nClosed\nPending\nCancelled", + "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": 1, + "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": "appointment_type", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Type", - "length": 0, - "no_copy": 0, - "options": "Appointment Type", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "appointment_type", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 1, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Type", + "length": 0, + "no_copy": 0, + "options": "Appointment Type", + "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": "section_break_1", - "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, - "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": 1, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "", + "fieldname": "section_break_1", + "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, + "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": 1, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "appointment_datetime", - "fieldtype": "Datetime", - "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": "Date TIme", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 1, - "reqd": 0, - "search_index": 1, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "appointment_datetime", + "fieldtype": "Datetime", + "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": "Date TIme", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 1, + "reqd": 0, + "search_index": 1, + "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": "mode_of_payment", - "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": "Mode of Payment", - "length": 0, - "no_copy": 0, - "options": "Mode of Payment", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "mode_of_payment", + "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": "Mode of Payment", + "length": 0, + "no_copy": 0, + "options": "Mode of Payment", + "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": "paid_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": "Paid Amount", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "paid_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": "Paid Amount", + "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, + "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": "0", - "fieldname": "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": "Invoiced", - "length": 0, - "no_copy": 0, - "options": "", - "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": 1, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "fieldname": "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": "Invoiced", + "length": 0, + "no_copy": 0, + "options": "", + "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": 1, + "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": "company", - "fieldtype": "Link", - "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": "Company", - "length": 0, - "no_copy": 1, - "options": "Company", - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 1, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "company", + "fieldtype": "Link", + "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": "Company", + "length": 0, + "no_copy": 1, + "options": "Company", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 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": 0, - "bold": 0, - "collapsible": 1, - "columns": 0, - "fieldname": "section_break_3", - "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": "More Info", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 1, + "columns": 0, + "fieldname": "section_break_3", + "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": "More Info", + "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": "notes", - "fieldtype": "Small Text", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 1, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Notes", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "notes", + "fieldtype": "Small Text", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 1, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Notes", + "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": "referring_practitioner", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Referring Practitioner", - "length": 0, - "no_copy": 0, - "options": "Healthcare Practitioner", - "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": 1, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "referring_practitioner", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 1, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Referring Practitioner", + "length": 0, + "no_copy": 0, + "options": "Healthcare Practitioner", + "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": 1, + "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": "reminded", - "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": "Reminded", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 1, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 1, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "fieldname": "reminded", + "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": "Reminded", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 1, + "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-09-13 10:15:45.704550", - "modified_by": "Administrator", - "module": "Healthcare", - "name": "Patient Appointment", - "name_case": "", - "owner": "Administrator", + ], + "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-16 12:38:06.107194", + "modified_by": "Administrator", + "module": "Healthcare", + "name": "Patient Appointment", + "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": "Healthcare Administrator", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "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": "Healthcare Administrator", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "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": "Physician", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "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": "Physician", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "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": "Nursing User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "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": "Nursing User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "restrict_to_domain": "Healthcare", - "search_fields": "patient, practitioner, department, appointment_date, appointment_time", - "show_name_in_global_search": 1, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "patient", - "track_changes": 1, - "track_seen": 1, + ], + "quick_entry": 0, + "read_only": 0, + "read_only_onload": 0, + "restrict_to_domain": "Healthcare", + "search_fields": "patient, practitioner, department, appointment_date, appointment_time", + "show_name_in_global_search": 1, + "sort_field": "modified", + "sort_order": "DESC", + "title_field": "patient", + "track_changes": 1, + "track_seen": 1, "track_views": 0 -} +} \ No newline at end of file From 45695c9bcb1fc8cf0d45e6c8c810172a4803cc35 Mon Sep 17 00:00:00 2001 From: Jamsheer Date: Wed, 14 Nov 2018 12:55:33 +0530 Subject: [PATCH 04/31] fix: Realign Patient Appointment fields --- .../patient_appointment.json | 723 ++++++++++-------- 1 file changed, 424 insertions(+), 299 deletions(-) diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json index 7f79989f0d..c789cf8d1e 100644 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json @@ -89,150 +89,19 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "department", + "fieldname": "appointment_type", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 1, "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Department", - "length": 0, - "no_copy": 0, - "options": "Medical Department", - "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": 1, - "set_only_once": 1, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "practitioner", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Healthcare Practitioner", - "length": 0, - "no_copy": 0, - "options": "Healthcare Practitioner", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 1, - "set_only_once": 1, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "get_procedure_from_encounter", - "fieldtype": "Button", - "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": "Get prescribed procedures", + "label": "Appointment Type", "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_prescription", - "fieldtype": "Link", - "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": "Procedure Prescription", - "length": 0, - "no_copy": 1, - "options": "Procedure Prescription", - "permlevel": 0, - "precision": "", - "print_hide": 1, - "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_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": "Procedure", - "length": 0, - "no_copy": 0, - "options": "Clinical Procedure Template", + "options": "Appointment Type", "permlevel": 0, "precision": "", "print_hide": 0, @@ -246,103 +115,6 @@ "translatable": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "appointment_date", - "fieldtype": "Date", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 1, - "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": 1, - "search_index": 1, - "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.__islocal", - "fieldname": "check_availability", - "fieldtype": "Button", - "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": "Check availability", - "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": "appointment_time", - "fieldtype": "Time", - "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": "Time", - "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, @@ -409,6 +181,139 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "Scheduled", + "depends_on": "eval:!doc.__islocal", + "fieldname": "status", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 1, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Status", + "length": 0, + "no_copy": 0, + "options": "\nScheduled\nOpen\nClosed\nPending\nCancelled", + "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": 1, + "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_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": "Procedure", + "length": 0, + "no_copy": 0, + "options": "Clinical Procedure 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": 1, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "get_procedure_from_encounter", + "fieldtype": "Button", + "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": "Get prescribed procedures", + "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_prescription", + "fieldtype": "Link", + "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": "Procedure Prescription", + "length": 0, + "no_copy": 1, + "options": "Procedure Prescription", + "permlevel": 0, + "precision": "", + "print_hide": 1, + "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, @@ -442,6 +347,262 @@ "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.__islocal", + "fieldname": "check_availability", + "fieldtype": "Button", + "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": "Check availability", + "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": "section_break_12", + "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, + "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": "practitioner", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 1, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Healthcare Practitioner", + "length": 0, + "no_copy": 0, + "options": "Healthcare Practitioner", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 1, + "set_only_once": 1, + "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": 1, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Department", + "length": 0, + "no_copy": 0, + "options": "Medical Department", + "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": 1, + "set_only_once": 1, + "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_17", + "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": "appointment_date", + "fieldtype": "Date", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 1, + "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": 1, + "search_index": 1, + "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": "appointment_time", + "fieldtype": "Time", + "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": "Time", + "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_16", + "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, + "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, @@ -511,6 +672,37 @@ "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_21", + "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, @@ -544,73 +736,6 @@ "translatable": 0, "unique": 0 }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "Scheduled", - "fieldname": "status", - "fieldtype": "Select", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 1, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Status", - "length": 0, - "no_copy": 0, - "options": "\nScheduled\nOpen\nClosed\nPending\nCancelled", - "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": 1, - "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": "appointment_type", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Type", - "length": 0, - "no_copy": 0, - "options": "Appointment Type", - "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, @@ -979,7 +1104,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-16 12:38:06.107194", + "modified": "2018-11-14 10:24:01.529536", "modified_by": "Administrator", "module": "Healthcare", "name": "Patient Appointment", From ee6b317ab56d52dc07418e93b51a37f06b74689f Mon Sep 17 00:00:00 2001 From: Jamsheer Date: Wed, 14 Nov 2018 13:27:04 +0530 Subject: [PATCH 05/31] fix: Patient Appointment - Code standards --- .../patient_appointment.js | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js index 414782a6b7..2f328de1bc 100644 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.js @@ -104,7 +104,7 @@ frappe.ui.form.on('Patient Appointment', { }); }, check_availability: function(frm) { - check_and_set_availability(frm) + check_and_set_availability(frm); }, onload:function(frm){ if(frm.is_new()) { @@ -121,9 +121,8 @@ var check_and_set_availability = function(frm) { var selected_slot = null; var service_unit = null; var duration = null; - var { patient } = frm.doc; - show_availability() + show_availability(); function show_empty_state(practitioner, appointment_date) { frappe.msgprint({ @@ -133,7 +132,7 @@ var check_and_set_availability = function(frm) { }); } - function show_availability(data) { + function show_availability() { let selected_practitioner = ''; var d = new frappe.ui.Dialog({ title: __("Available slots"), @@ -179,10 +178,10 @@ var check_and_set_availability = function(frm) { filters: { "department": department } - } - } + }; + }; } - } + }; // disable dialog action initially d.get_primary_btn().attr('disabled', true); @@ -193,19 +192,19 @@ var check_and_set_availability = function(frm) { d.fields_dict["appointment_date"].df.onchange = () => { show_slots(d, fd); - } + }; d.fields_dict["practitioner"].df.onchange = () => { if(d.get_value('practitioner') && d.get_value('practitioner') != selected_practitioner){ selected_practitioner = d.get_value('practitioner'); show_slots(d, fd); } - } + }; d.show(); } function show_slots(d, fd) { if (d.get_value('appointment_date') && d.get_value('practitioner')){ - fd.available_slots.html("") + fd.available_slots.html(""); frappe.call({ method: 'erpnext.healthcare.doctype.patient_appointment.patient_appointment.get_availability_data', args: { @@ -228,7 +227,7 @@ var check_and_set_availability = function(frm) { let slot_start_time = moment(slot.from_time, 'HH:mm:ss'); let slot_to_time = moment(slot.to_time, 'HH:mm:ss'); let interval = (slot_to_time - slot_start_time)/60000 | 0; - //iterate in all booked appointments, update the start time and duration + // iterate in all booked appointments, update the start time and duration slot_details[i].appointments.forEach(function(booked) { let booked_moment = moment(booked.appointment_time, 'HH:mm:ss'); let end_time = booked_moment.clone().add(booked.duration, 'minutes'); @@ -268,8 +267,8 @@ var check_and_set_availability = function(frm) { $wrapper.find('button').removeClass('btn-primary'); $btn.addClass('btn-primary'); selected_slot = $btn.attr('data-name'); - service_unit = $btn.attr('data-service-unit') - duration = $btn.attr('data-duration') + service_unit = $btn.attr('data-service-unit'); + duration = $btn.attr('data-duration'); // enable dialog action d.get_primary_btn().attr('disabled', null); }); @@ -283,10 +282,10 @@ var check_and_set_availability = function(frm) { freeze_message: __("Fetching records......") }); }else{ - fd.available_slots.html("Appointment date and Healthcare Practitioner are Mandatory".bold()) + fd.available_slots.html("Appointment date and Healthcare Practitioner are Mandatory".bold()); } } -} +}; var get_procedure_prescribed = function(frm){ if(frm.doc.patient){ From 64e42e1e88678fc4773024243875b77f067caf91 Mon Sep 17 00:00:00 2001 From: Jamsheer Date: Wed, 14 Nov 2018 13:38:13 +0530 Subject: [PATCH 06/31] fix: Patient Appointment - update list view --- .../patient_appointment/patient_appointment.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json index c789cf8d1e..ee9f013084 100644 --- a/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json +++ b/erpnext/healthcare/doctype/patient_appointment/patient_appointment.json @@ -130,7 +130,7 @@ "ignore_xss_filter": 0, "in_filter": 1, "in_global_search": 0, - "in_list_view": 1, + "in_list_view": 0, "in_standard_filter": 0, "label": "Duration", "length": 0, @@ -197,7 +197,7 @@ "ignore_xss_filter": 0, "in_filter": 1, "in_global_search": 0, - "in_list_view": 1, + "in_list_view": 0, "in_standard_filter": 0, "label": "Status", "length": 0, @@ -425,7 +425,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 1, + "in_list_view": 0, "in_standard_filter": 1, "label": "Healthcare Practitioner", "length": 0, @@ -522,7 +522,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 1, "label": "Date", "length": 0, @@ -554,7 +554,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 0, "label": "Time", "length": 0, @@ -1104,7 +1104,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-11-14 10:24:01.529536", + "modified": "2018-11-14 13:24:01.529536", "modified_by": "Administrator", "module": "Healthcare", "name": "Patient Appointment", @@ -1181,4 +1181,4 @@ "track_changes": 1, "track_seen": 1, "track_views": 0 -} \ No newline at end of file +} From 5d2e52c4effbeaa4769132ae8c48f31c33746942 Mon Sep 17 00:00:00 2001 From: Ranjith Date: Mon, 19 Nov 2018 20:03:25 +0530 Subject: [PATCH 07/31] fix: healthcare patch --- .../v11_0/add_healthcare_service_unit_tree_root.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/erpnext/patches/v11_0/add_healthcare_service_unit_tree_root.py b/erpnext/patches/v11_0/add_healthcare_service_unit_tree_root.py index 0c4209ac9a..029ea8738b 100644 --- a/erpnext/patches/v11_0/add_healthcare_service_unit_tree_root.py +++ b/erpnext/patches/v11_0/add_healthcare_service_unit_tree_root.py @@ -3,12 +3,18 @@ from frappe import _ def execute(): """ assign lft and rgt appropriately """ + if "Healthcare" not in frappe.get_active_domains(): + return + frappe.reload_doc("healthcare", "doctype", "healthcare_service_unit") frappe.reload_doc("healthcare", "doctype", "healthcare_service_unit_type") + company = frappe.get_value("Company", {"domain": "Healthcare"}, "name") - if not frappe.db.exists("Healthcare Service Unit", _('All Healthcare Service Units')): + if company: frappe.get_doc({ 'doctype': 'Healthcare Service Unit', 'healthcare_service_unit_name': _('All Healthcare Service Units'), - 'is_group': 1 + 'is_group': 1, + 'company': company }).insert(ignore_permissions=True) + From 920dc1400f9aa7322250fe08db2eda86a9daf1af Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Fri, 23 Nov 2018 10:17:28 +0530 Subject: [PATCH 08/31] Customer/Supplier dashboard fix for multi company setup --- erpnext/accounts/party.py | 75 +++++++++++++++++++++++++------------- erpnext/public/js/utils.js | 17 ++++++--- 2 files changed, 60 insertions(+), 32 deletions(-) diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py index f19aaf833b..7c12ece40b 100644 --- a/erpnext/accounts/party.py +++ b/erpnext/accounts/party.py @@ -72,7 +72,7 @@ def _get_party_details(party=None, account=None, party_type="Customer", company= return out -def set_address_details(out, party, party_type, doctype=None, company=None, party_address=None, shipping_address=None): +def set_address_details(out, party, party_type, doctype=None, company=None, party_address=None, shipping_address=None): billing_address_field = "customer_address" if party_type == "Lead" \ else party_type.lower() + "_address" out[billing_address_field] = party_address or get_default_address(party_type, party.name) @@ -459,38 +459,61 @@ def get_timeline_data(doctype, name): def get_dashboard_info(party_type, party): current_fiscal_year = get_fiscal_year(nowdate(), as_dict=True) - company = frappe.db.get_default("company") or frappe.get_all("Company")[0].name - party_account_currency = get_party_account_currency(party_type, party, company) - company_default_currency = get_default_currency() \ - or frappe.get_cached_value('Company', company, 'default_currency') - - if party_account_currency==company_default_currency: - total_field = "base_grand_total" - else: - total_field = "grand_total" doctype = "Sales Invoice" if party_type=="Customer" else "Purchase Invoice" - billing_this_year = frappe.db.sql(""" - select sum({0}) - from `tab{1}` - where {2}=%s and docstatus=1 and posting_date between %s and %s - """.format(total_field, doctype, party_type.lower()), - (party, current_fiscal_year.year_start_date, current_fiscal_year.year_end_date)) + companies = frappe.db.sql(""" + select distinct company from `tab{0}` + where docstatus =1 and {1} = %s + """.format(doctype, party_type.lower()), (party), as_dict=1) - total_unpaid = frappe.db.sql(""" - select sum(debit_in_account_currency) - sum(credit_in_account_currency) + company_wise_info = [] + + company_wise_grand_total = frappe._dict(frappe.db.sql(""" + select company, sum(grand_total) + from `tab{0}` + where {1}=%s and docstatus=1 and posting_date between %s and %s + group by company + """.format(doctype, party_type.lower()), + (party, current_fiscal_year.year_start_date, current_fiscal_year.year_end_date))) + + company_wise_base_grand_total = frappe._dict(frappe.db.sql(""" + select company, sum(base_grand_total) + from `tab{0}` + where {1}=%s and docstatus=1 and posting_date between %s and %s + group by company + """.format(doctype, party_type.lower()), + (party, current_fiscal_year.year_start_date, current_fiscal_year.year_end_date))) + + company_wise_total_unpaid = frappe._dict(frappe.db.sql(""" + select company, sum(debit_in_account_currency) - sum(credit_in_account_currency) from `tabGL Entry` - where party_type = %s and party=%s""", (party_type, party)) + where party_type = %s and party=%s + group by company""", (party_type, party))) - info = {} - info["billing_this_year"] = flt(billing_this_year[0][0]) if billing_this_year else 0 - info["currency"] = party_account_currency - info["total_unpaid"] = flt(total_unpaid[0][0]) if total_unpaid else 0 - if party_type == "Supplier": - info["total_unpaid"] = -1 * info["total_unpaid"] + for d in companies: + company_default_currency = frappe.db.get_value("Company", d.company, 'default_currency') + party_account_currency = get_party_account_currency(party_type, party, d.company) - return info + if party_account_currency==company_default_currency: + billing_this_year = flt(company_wise_base_grand_total.get(d.company)) + else: + billing_this_year = flt(company_wise_grand_total.get(d.company)) + + total_unpaid = flt(company_wise_total_unpaid.get(d.company)) + + info = {} + info["billing_this_year"] = flt(billing_this_year) if billing_this_year else 0 + info["currency"] = party_account_currency + info["total_unpaid"] = flt(total_unpaid) if total_unpaid else 0 + info["company"] = d.company + + if party_type == "Supplier": + info["total_unpaid"] = -1 * info["total_unpaid"] + + company_wise_info.append(info) + + return company_wise_info def get_party_shipping_address(doctype, name): """ diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index baee68e6be..4f5470d38d 100644 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -103,12 +103,17 @@ $.extend(erpnext, { $.extend(erpnext.utils, { set_party_dashboard_indicators: function(frm) { if(frm.doc.__onload && frm.doc.__onload.dashboard_info) { - var info = frm.doc.__onload.dashboard_info; - frm.dashboard.add_indicator(__('Annual Billing: {0}', - [format_currency(info.billing_this_year, info.currency)]), 'blue'); - frm.dashboard.add_indicator(__('Total Unpaid: {0}', - [format_currency(info.total_unpaid, info.currency)]), - info.total_unpaid ? 'orange' : 'green'); + var company_wise_info = frm.doc.__onload.dashboard_info; + frm.dashboard.add_indicator(__('Company')); + frm.dashboard.add_indicator(__('Annual Billing')); + frm.dashboard.add_indicator(__('Total Unpaid')); + company_wise_info.forEach(function(info){ + frm.dashboard.add_indicator(__('{0}',[info.company])); + frm.dashboard.add_indicator(__('{0}', + [format_currency(info.billing_this_year, info.currency)])); + frm.dashboard.add_indicator(__('{0}', + [format_currency(info.total_unpaid, info.currency)])); + }); } }, From 0e8c36473a57344d265fd700d874684c91245d74 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Fri, 23 Nov 2018 11:22:24 +0530 Subject: [PATCH 09/31] Added colspan to indicators --- erpnext/public/js/utils.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index 4f5470d38d..6d7b167f1e 100644 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -104,15 +104,15 @@ $.extend(erpnext.utils, { set_party_dashboard_indicators: function(frm) { if(frm.doc.__onload && frm.doc.__onload.dashboard_info) { var company_wise_info = frm.doc.__onload.dashboard_info; - frm.dashboard.add_indicator(__('Company')); - frm.dashboard.add_indicator(__('Annual Billing')); - frm.dashboard.add_indicator(__('Total Unpaid')); + frm.dashboard.add_indicator(__('Company'), '', 4); + frm.dashboard.add_indicator(__('Annual Billing'), '', 4); + frm.dashboard.add_indicator(__('Total Unpaid'), '', 4); company_wise_info.forEach(function(info){ - frm.dashboard.add_indicator(__('{0}',[info.company])); + frm.dashboard.add_indicator(__('{0}',[info.company]), '', 4); frm.dashboard.add_indicator(__('{0}', - [format_currency(info.billing_this_year, info.currency)])); + [format_currency(info.billing_this_year, info.currency)]), '', 4); frm.dashboard.add_indicator(__('{0}', - [format_currency(info.total_unpaid, info.currency)])); + [format_currency(info.total_unpaid, info.currency)]), '', 4); }); } }, From a1cffc349003d1a3954005b868a671754120ce1b Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Fri, 23 Nov 2018 16:51:35 +0530 Subject: [PATCH 10/31] minor changes in dashboard --- erpnext/accounts/party.py | 24 ++++++++++++------------ erpnext/public/js/utils.js | 25 +++++++++++++++---------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py index 7c12ece40b..4620733139 100644 --- a/erpnext/accounts/party.py +++ b/erpnext/accounts/party.py @@ -464,25 +464,25 @@ def get_dashboard_info(party_type, party): companies = frappe.db.sql(""" select distinct company from `tab{0}` - where docstatus =1 and {1} = %s - """.format(doctype, party_type.lower()), (party), as_dict=1) + where docstatus =1 and {1} = %s""" + .format(doctype, party_type.lower()), (party), as_dict=1) company_wise_info = [] company_wise_grand_total = frappe._dict(frappe.db.sql(""" - select company, sum(grand_total) - from `tab{0}` - where {1}=%s and docstatus=1 and posting_date between %s and %s - group by company - """.format(doctype, party_type.lower()), + select company, sum(grand_total) + from `tab{0}` + where {1}=%s and docstatus=1 and posting_date between %s and %s + group by company""" + .format(doctype, party_type.lower()), (party, current_fiscal_year.year_start_date, current_fiscal_year.year_end_date))) company_wise_base_grand_total = frappe._dict(frappe.db.sql(""" - select company, sum(base_grand_total) - from `tab{0}` - where {1}=%s and docstatus=1 and posting_date between %s and %s - group by company - """.format(doctype, party_type.lower()), + select company, sum(base_grand_total) + from `tab{0}` + where {1}=%s and docstatus=1 and posting_date between %s and %s + group by company""" + .format(doctype, party_type.lower()), (party, current_fiscal_year.year_start_date, current_fiscal_year.year_end_date))) company_wise_total_unpaid = frappe._dict(frappe.db.sql(""" diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index 6d7b167f1e..b80f8ac02d 100644 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -104,16 +104,21 @@ $.extend(erpnext.utils, { set_party_dashboard_indicators: function(frm) { if(frm.doc.__onload && frm.doc.__onload.dashboard_info) { var company_wise_info = frm.doc.__onload.dashboard_info; - frm.dashboard.add_indicator(__('Company'), '', 4); - frm.dashboard.add_indicator(__('Annual Billing'), '', 4); - frm.dashboard.add_indicator(__('Total Unpaid'), '', 4); - company_wise_info.forEach(function(info){ - frm.dashboard.add_indicator(__('{0}',[info.company]), '', 4); - frm.dashboard.add_indicator(__('{0}', - [format_currency(info.billing_this_year, info.currency)]), '', 4); - frm.dashboard.add_indicator(__('{0}', - [format_currency(info.total_unpaid, info.currency)]), '', 4); - }); + if(company_wise_info[0]) { + frm.dashboard.stats_area.removeClass('hidden'); + frm.dashboard.stats_area_row.append( + '
Company
'+ + '
Annual Billing
' + + '
Total Unpaid
' + ); + company_wise_info.forEach(function(info) { + frm.dashboard.stats_area_row.append( + '
'+info.company+'
' + + '
'+format_currency(info.billing_this_year, info.currency)+'
' + + '
'+format_currency(info.billing_this_year, info.currency)+'
' + ); + }); + } } }, From f31caffa745f5fb809f5dff12d22d291c6caa37b Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Tue, 27 Nov 2018 15:04:12 +0530 Subject: [PATCH 11/31] Changes in get_dashboard_info --- erpnext/accounts/party.py | 26 ++++++++++++++------------ erpnext/public/js/utils.js | 13 ++++++++++--- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py index 1330efcc6e..777b209962 100644 --- a/erpnext/accounts/party.py +++ b/erpnext/accounts/party.py @@ -469,21 +469,23 @@ def get_dashboard_info(party_type, party): company_wise_info = [] - company_wise_grand_total = frappe._dict(frappe.db.sql(""" - select company, sum(grand_total) + company_wise_grand_total = frappe.db.sql(""" + select company, sum(grand_total) as grand_total, sum(base_grand_total) as base_grand_total from `tab{0}` where {1}=%s and docstatus=1 and posting_date between %s and %s group by company""" .format(doctype, party_type.lower()), - (party, current_fiscal_year.year_start_date, current_fiscal_year.year_end_date))) + (party, current_fiscal_year.year_start_date, current_fiscal_year.year_end_date), as_dict=1) + + company_wise_billing_this_year = frappe._dict() + + for d in company_wise_grand_total: + company_wise_billing_this_year.setdefault( + d.company,{ + "grand_total": d.grand_total, + "base_grand_total": d.base_grand_total + }) - company_wise_base_grand_total = frappe._dict(frappe.db.sql(""" - select company, sum(base_grand_total) - from `tab{0}` - where {1}=%s and docstatus=1 and posting_date between %s and %s - group by company""" - .format(doctype, party_type.lower()), - (party, current_fiscal_year.year_start_date, current_fiscal_year.year_end_date))) company_wise_total_unpaid = frappe._dict(frappe.db.sql(""" select company, sum(debit_in_account_currency) - sum(credit_in_account_currency) @@ -496,9 +498,9 @@ def get_dashboard_info(party_type, party): party_account_currency = get_party_account_currency(party_type, party, d.company) if party_account_currency==company_default_currency: - billing_this_year = flt(company_wise_base_grand_total.get(d.company)) + billing_this_year = flt(company_wise_billing_this_year.get(d.company,{}).get("base_grand_total")) else: - billing_this_year = flt(company_wise_grand_total.get(d.company)) + billing_this_year = flt(company_wise_billing_this_year.get(d.company,{}).get("grand_total")) total_unpaid = flt(company_wise_total_unpaid.get(d.company)) diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index b80f8ac02d..18716a99c9 100644 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -104,7 +104,7 @@ $.extend(erpnext.utils, { set_party_dashboard_indicators: function(frm) { if(frm.doc.__onload && frm.doc.__onload.dashboard_info) { var company_wise_info = frm.doc.__onload.dashboard_info; - if(company_wise_info[0]) { + if(company_wise_info.length > 1) { frm.dashboard.stats_area.removeClass('hidden'); frm.dashboard.stats_area_row.append( '
Company
'+ @@ -114,11 +114,18 @@ $.extend(erpnext.utils, { company_wise_info.forEach(function(info) { frm.dashboard.stats_area_row.append( '
'+info.company+'
' + - '
'+format_currency(info.billing_this_year, info.currency)+'
' + - '
'+format_currency(info.billing_this_year, info.currency)+'
' + '
'+format_currency(info.billing_this_year, info.currency)+'
' + + '
'+format_currency(info.billing_this_year, info.currency)+'
' ); }); } + else { + frm.dashboard.stats_area.removeClass('hidden'); + frm.dashboard.stats_area_row.append( + '
Annual Billing: '+format_currency(company_wise_info[0].billing_this_year, company_wise_info[0].currency)+'
' + + '
Total Unpaid: '+format_currency(company_wise_info[0].billing_this_year, company_wise_info[0].currency)+'
' + ); + } } }, From c1a3c72b49943d65f33c04764416052aaa4c2471 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Tue, 27 Nov 2018 17:09:12 +0530 Subject: [PATCH 12/31] final dashboard design --- erpnext/public/js/utils.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/erpnext/public/js/utils.js b/erpnext/public/js/utils.js index 18716a99c9..e2933210bb 100644 --- a/erpnext/public/js/utils.js +++ b/erpnext/public/js/utils.js @@ -106,24 +106,27 @@ $.extend(erpnext.utils, { var company_wise_info = frm.doc.__onload.dashboard_info; if(company_wise_info.length > 1) { frm.dashboard.stats_area.removeClass('hidden'); - frm.dashboard.stats_area_row.append( - '
Company
'+ - '
Annual Billing
' + - '
Total Unpaid
' - ); + frm.dashboard.stats_area_row.addClass('flex'); + frm.dashboard.stats_area_row.css('flex-wrap', 'wrap'); company_wise_info.forEach(function(info) { frm.dashboard.stats_area_row.append( - '
'+info.company+'
' + - '
'+format_currency(info.billing_this_year, info.currency)+'
' + - '
'+format_currency(info.billing_this_year, info.currency)+'
' + '
'+ + '
'+info.company+'
'+ + ''+ + ''+ + '
' ); }); } else { frm.dashboard.stats_area.removeClass('hidden'); frm.dashboard.stats_area_row.append( - '
Annual Billing: '+format_currency(company_wise_info[0].billing_this_year, company_wise_info[0].currency)+'
' + - '
Total Unpaid: '+format_currency(company_wise_info[0].billing_this_year, company_wise_info[0].currency)+'
' + '
Annual Billing: ' + +format_currency(company_wise_info[0].billing_this_year, company_wise_info[0].currency)+'
' + + '
Total Unpaid: ' + +format_currency(company_wise_info[0].billing_this_year, company_wise_info[0].currency)+'
' ); } } From 96598936ad87690f1033961636da1c6e7b595ad9 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 27 Nov 2018 17:48:13 +0530 Subject: [PATCH 13/31] fix(test): Fixed tests for discount with margin and period closing voucher --- .../test_period_closing_voucher.py | 1 + .../doctype/pricing_rule/test_pricing_rule.py | 36 +++++++------------ erpnext/controllers/taxes_and_totals.py | 7 ++-- .../public/js/controllers/taxes_and_totals.js | 3 +- erpnext/public/js/controllers/transaction.js | 2 +- 5 files changed, 20 insertions(+), 29 deletions(-) diff --git a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py index 9ef66edc34..eb02d97b78 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py +++ b/erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py @@ -72,6 +72,7 @@ class TestPeriodClosingVoucher(unittest.TestCase): "company": "_Test Company", "fiscal_year": get_fiscal_year(today(), company="_Test Company")[0], "posting_date": today(), + "cost_center": "_Test Cost Center - _TC", "remarks": "test" }) pcv.insert() diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py index 3fa34e279a..30ae71db3a 100644 --- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py +++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py @@ -11,12 +11,16 @@ from erpnext.stock.get_item_details import get_item_details from frappe import MandatoryError class TestPricingRule(unittest.TestCase): + def setUp(self): + frappe.db.sql("delete from `tabPricing Rule`") + + def tearDown(self): + frappe.db.sql("delete from `tabPricing Rule`") + def test_pricing_rule_for_discount(self): from erpnext.stock.get_item_details import get_item_details from frappe import MandatoryError - frappe.db.sql("delete from `tabPricing Rule`") - test_record = { "doctype": "Pricing Rule", "title": "_Test Pricing Rule", @@ -88,14 +92,10 @@ class TestPricingRule(unittest.TestCase): details = get_item_details(args) self.assertEquals(details.get("discount_percentage"), 15) - frappe.db.sql("delete from `tabPricing Rule`") - def test_pricing_rule_for_margin(self): from erpnext.stock.get_item_details import get_item_details from frappe import MandatoryError - frappe.db.sql("delete from `tabPricing Rule`") - test_record = { "doctype": "Pricing Rule", "title": "_Test Pricing Rule", @@ -109,14 +109,14 @@ class TestPricingRule(unittest.TestCase): "company": "_Test Company" } frappe.get_doc(test_record.copy()).insert() - + item_price = frappe.get_doc({ "doctype": "Item Price", "price_list": "_Test Price List 2", "item_code": "_Test FG Item 2", "price_list_rate": 100 }) - + item_price.insert(ignore_permissions=True) args = frappe._dict({ @@ -136,14 +136,10 @@ class TestPricingRule(unittest.TestCase): self.assertEquals(details.get("margin_type"), "Percentage") self.assertEquals(details.get("margin_rate_or_amount"), 10) - frappe.db.sql("delete from `tabPricing Rule`") - def test_pricing_rule_for_variants(self): from erpnext.stock.get_item_details import get_item_details from frappe import MandatoryError - frappe.db.sql("delete from `tabPricing Rule`") - if not frappe.db.exists("Item", "Test Variant PRT"): frappe.get_doc({ "doctype": "Item", @@ -209,8 +205,6 @@ class TestPricingRule(unittest.TestCase): self.assertEquals(details.get("discount_percentage"), 17.5) def test_pricing_rule_for_stock_qty(self): - frappe.db.sql("delete from `tabPricing Rule`") - test_record = { "doctype": "Pricing Rule", "title": "_Test Pricing Rule", @@ -253,24 +247,18 @@ class TestPricingRule(unittest.TestCase): def test_pricing_rule_with_margin_and_discount(self): frappe.delete_doc_if_exists('Pricing Rule', '_Test Pricing Rule') - make_pricing_rule(selling=1, margin_type="Percentage", margin_rate_or_amount=10) + make_pricing_rule(selling=1, margin_type="Percentage", margin_rate_or_amount=10, discount_percentage=10) si = create_sales_invoice(do_not_save=True) si.items[0].price_list_rate = 1000 si.payment_schedule = [] si.insert(ignore_permissions=True) item = si.items[0] - self.assertEquals(item.rate, 1100) self.assertEquals(item.margin_rate_or_amount, 10) - - # With discount - item.discount_percentage = 10 - si.payment_schedule = [] - si.save() - item = si.items[0] + self.assertEquals(item.rate_with_margin, 1100) + self.assertEqual(item.discount_percentage, 10) + self.assertEquals(item.discount_amount, 110) self.assertEquals(item.rate, 990) - self.assertEquals(item.discount_percentage, 10) - frappe.db.sql("delete from `tabPricing Rule`") def make_pricing_rule(**args): args = frappe._dict(args) diff --git a/erpnext/controllers/taxes_and_totals.py b/erpnext/controllers/taxes_and_totals.py index 41ba61b231..2639a15adc 100644 --- a/erpnext/controllers/taxes_and_totals.py +++ b/erpnext/controllers/taxes_and_totals.py @@ -66,8 +66,11 @@ class calculate_taxes_and_totals(object): if item.doctype in ['Quotation Item', 'Sales Order Item', 'Delivery Note Item', 'Sales Invoice Item']: item.rate_with_margin, item.base_rate_with_margin = self.calculate_margin(item) - item.rate = flt(item.rate_with_margin * (1.0 - (item.discount_percentage / 100.0)), item.precision("rate"))\ - if item.rate_with_margin > 0 else item.rate + if flt(item.rate_with_margin) > 0: + item.rate = flt(item.rate_with_margin * (1.0 - (item.discount_percentage / 100.0)), item.precision("rate")) + item.discount_amount = item.rate_with_margin - item.rate + elif flt(item.price_list_rate) > 0: + item.discount_amount = item.price_list_rate - item.rate item.net_rate = item.rate item.amount = flt(item.rate * item.qty, item.precision("amount")) diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js index a31acfc5f5..0a0dcf7be2 100644 --- a/erpnext/public/js/controllers/taxes_and_totals.js +++ b/erpnext/public/js/controllers/taxes_and_totals.js @@ -10,9 +10,8 @@ erpnext.taxes_and_totals = erpnext.payments.extend({ + flt(item.price_list_rate) * ( flt(item.margin_rate_or_amount) / 100); } else { item.rate_with_margin = flt(item.price_list_rate) + flt(item.margin_rate_or_amount); - item.base_rate_with_margin = flt(item.rate_with_margin) * flt(this.frm.doc.conversion_rate); } - + item.base_rate_with_margin = flt(item.rate_with_margin) * flt(this.frm.doc.conversion_rate); item.rate = flt(item.rate_with_margin , precision("rate", item)); if(item.discount_percentage){ diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index d9bd50c226..e5ecc5ba1b 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -33,7 +33,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ item.margin_rate_or_amount = 0; item.rate_with_margin = 0; } - + item.base_rate_with_margin = item.rate_with_margin * flt(frm.doc.conversion_rate); cur_frm.cscript.set_gross_profit(item); cur_frm.cscript.calculate_taxes_and_totals(); From ebe1e12a82aec4ba87b8ca116b178d5168f0cf45 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Wed, 28 Nov 2018 08:21:54 +0530 Subject: [PATCH 14/31] Codacy issue fixes --- erpnext/accounts/party.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py index 777b209962..ab7fc7db23 100644 --- a/erpnext/accounts/party.py +++ b/erpnext/accounts/party.py @@ -464,7 +464,8 @@ def get_dashboard_info(party_type, party): companies = frappe.db.sql(""" select distinct company from `tab{0}` - where docstatus =1 and {1} = %s""" + where docstatus =1 and {1} = %s + """ .format(doctype, party_type.lower()), (party), as_dict=1) company_wise_info = [] @@ -473,7 +474,8 @@ def get_dashboard_info(party_type, party): select company, sum(grand_total) as grand_total, sum(base_grand_total) as base_grand_total from `tab{0}` where {1}=%s and docstatus=1 and posting_date between %s and %s - group by company""" + group by company + """ .format(doctype, party_type.lower()), (party, current_fiscal_year.year_start_date, current_fiscal_year.year_end_date), as_dict=1) From 1a1c013b2abd174b00f6c67e971adcebd0160b5c Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Thu, 29 Nov 2018 08:34:47 +0530 Subject: [PATCH 15/31] Analytics report bug fixes and code cleaning --- .../purchase_analytics/purchase_analytics.js | 20 +++++++------------ .../production_analytics.js | 5 +---- .../report/sales_analytics/sales_analytics.js | 4 ++-- .../report/sales_analytics/sales_analytics.py | 13 +++++++----- .../report/stock_analytics/stock_analytics.js | 19 ++++-------------- .../report/stock_analytics/stock_analytics.py | 6 +++--- 6 files changed, 25 insertions(+), 42 deletions(-) diff --git a/erpnext/buying/report/purchase_analytics/purchase_analytics.js b/erpnext/buying/report/purchase_analytics/purchase_analytics.js index 297ec51cb1..139c4b7af5 100644 --- a/erpnext/buying/report/purchase_analytics/purchase_analytics.js +++ b/erpnext/buying/report/purchase_analytics/purchase_analytics.js @@ -68,12 +68,6 @@ frappe.query_reports["Purchase Analytics"] = { } ], - "formatter": function(value, row, column, data) { - if(!value){ - value = 0 - } - return value; - }, get_datatable_options(options) { return Object.assign(options, { checkboxColumn: true, @@ -110,19 +104,19 @@ frappe.query_reports["Purchase Analytics"] = { labels: raw_data.labels, datasets: new_datasets } - + setTimeout(() => { frappe.query_report.chart.update(new_data) - },200) - - + },500) + + setTimeout(() => { frappe.query_report.chart.draw(true); - }, 800) + }, 1000) frappe.query_report.raw_chart_data = new_data; }, } - }) - }, + }); + } } diff --git a/erpnext/manufacturing/report/production_analytics/production_analytics.js b/erpnext/manufacturing/report/production_analytics/production_analytics.js index b7b8f05d89..99f9b1260a 100644 --- a/erpnext/manufacturing/report/production_analytics/production_analytics.js +++ b/erpnext/manufacturing/report/production_analytics/production_analytics.js @@ -39,8 +39,5 @@ frappe.query_reports["Production Analytics"] = { default: "Monthly", reqd: 1 } - ], - "formatter": function(value, row, column, data) { - return value; - } + ] } diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.js b/erpnext/selling/report/sales_analytics/sales_analytics.js index 7dc7c754bc..ac3ebfef12 100644 --- a/erpnext/selling/report/sales_analytics/sales_analytics.js +++ b/erpnext/selling/report/sales_analytics/sales_analytics.js @@ -106,12 +106,12 @@ frappe.query_reports["Sales Analytics"] = { setTimeout(() => { frappe.query_report.chart.update(new_data) - },200) + }, 500) setTimeout(() => { frappe.query_report.chart.draw(true); - }, 800) + }, 1000) frappe.query_report.raw_chart_data = new_data; }, diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.py b/erpnext/selling/report/sales_analytics/sales_analytics.py index 8d99a9b789..07ad8399cb 100644 --- a/erpnext/selling/report/sales_analytics/sales_analytics.py +++ b/erpnext/selling/report/sales_analytics/sales_analytics.py @@ -212,11 +212,11 @@ class Analytics(object): def get_period(self, posting_date): if self.filters.range == 'Weekly': - period = "Week " + str(posting_date.isocalendar()[1]) + period = "Week " + str(posting_date.isocalendar()[1]) + " " + str(posting_date.year) elif self.filters.range == 'Monthly': - period = self.months[posting_date.month - 1] + period = str(self.months[posting_date.month - 1]) + " " + str(posting_date.year) elif self.filters.range == 'Quarterly': - period = "Quarter " + str(((posting_date.month-1)//3)+1) + period = "Quarter " + str(((posting_date.month-1)//3)+1) +" " + str(posting_date.year) else: year = get_fiscal_year(posting_date, company=self.filters.company) period = str(year[2]) @@ -277,11 +277,14 @@ class Analytics(object): def get_chart_data(self): length = len(self.columns) labels = [d.get("label") for d in self.columns[2:length-1]] + entry = { + 'name':self.data[0].get('entity_name') + } + print("##########") self.chart = { "data": { 'labels': labels, - 'datasets':[ - ] + 'datasets':[] }, "type": "line" } \ No newline at end of file diff --git a/erpnext/stock/report/stock_analytics/stock_analytics.js b/erpnext/stock/report/stock_analytics/stock_analytics.js index bebc84e057..12e4350d9a 100644 --- a/erpnext/stock/report/stock_analytics/stock_analytics.js +++ b/erpnext/stock/report/stock_analytics/stock_analytics.js @@ -71,17 +71,6 @@ frappe.query_reports["Stock Analytics"] = { reqd: 1 } ], - "formatter": function(value, row, column, data) { - if(!value && (column.fieldname == 'brand' || column.fieldname == 'uom')){ - value = "" - } - - if(Number(value)){ - value = value.toFixed(2) - } - - return value; - }, get_datatable_options(options) { return Object.assign(options, { checkboxColumn: true, @@ -120,16 +109,16 @@ frappe.query_reports["Stock Analytics"] = { setTimeout(() => { frappe.query_report.chart.update(new_data) - },200) + },500) setTimeout(() => { frappe.query_report.chart.draw(true); - }, 800) + }, 1000) frappe.query_report.raw_chart_data = new_data; }, } - }) - }, + }); + } } diff --git a/erpnext/stock/report/stock_analytics/stock_analytics.py b/erpnext/stock/report/stock_analytics/stock_analytics.py index dad8be1b8c..54eefdfaaa 100644 --- a/erpnext/stock/report/stock_analytics/stock_analytics.py +++ b/erpnext/stock/report/stock_analytics/stock_analytics.py @@ -99,11 +99,11 @@ def get_period(posting_date, filters): months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] if filters.range == 'Weekly': - period = "Week " + str(posting_date.isocalendar()[1]) + period = "Week " + str(posting_date.isocalendar()[1]) + " " + str(posting_date.year) elif filters.range == 'Monthly': - period = months[posting_date.month - 1] + period = str(months[posting_date.month - 1]) + " " + str(posting_date.year) elif filters.range == 'Quarterly': - period = "Quarter " + str(((posting_date.month-1)//3)+1) + period = "Quarter " + str(((posting_date.month-1)//3)+1) +" " + str(posting_date.year) else: year = get_fiscal_year(posting_date, company=filters.company) period = str(year[2]) From 3eef6411dd36ecc5af6ce85328df991115f67c26 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Thu, 29 Nov 2018 13:10:02 +0530 Subject: [PATCH 16/31] Removed print statement --- erpnext/selling/report/sales_analytics/sales_analytics.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.py b/erpnext/selling/report/sales_analytics/sales_analytics.py index 07ad8399cb..9cc6c404a6 100644 --- a/erpnext/selling/report/sales_analytics/sales_analytics.py +++ b/erpnext/selling/report/sales_analytics/sales_analytics.py @@ -277,10 +277,6 @@ class Analytics(object): def get_chart_data(self): length = len(self.columns) labels = [d.get("label") for d in self.columns[2:length-1]] - entry = { - 'name':self.data[0].get('entity_name') - } - print("##########") self.chart = { "data": { 'labels': labels, From 3c7c4a61be65c2ad56b81a64d2e292e07df9718a Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Thu, 29 Nov 2018 14:28:01 +0530 Subject: [PATCH 17/31] Test case fix --- .../report/sales_analytics/test_analytics.py | 168 +++++++++--------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/erpnext/selling/report/sales_analytics/test_analytics.py b/erpnext/selling/report/sales_analytics/test_analytics.py index f59fff46f7..5d68b06b6d 100644 --- a/erpnext/selling/report/sales_analytics/test_analytics.py +++ b/erpnext/selling/report/sales_analytics/test_analytics.py @@ -35,52 +35,52 @@ class TestAnalytics(unittest.TestCase): { "entity": "_Test Customer 1", "entity_name": "_Test Customer 1", - "apr": 0.0, - "may": 0.0, - "jun": 0.0, - "jul": 0.0, - "aug": 0.0, - "sep": 0.0, - "oct": 0.0, - "nov": 0.0, - "dec": 0.0, - "jan": 0.0, - "feb": 2000.0, - "mar": 0.0, + "apr_2017": 0.0, + "may_2017": 0.0, + "jun_2017": 0.0, + "jul_2017": 0.0, + "aug_2017": 0.0, + "oct_2017": 0.0, + "sep_2017": 0.0, + "nov_2017": 0.0, + "dec_2017": 0.0, + "jan_2018": 0.0, + "feb_2018": 2000.0, + "mar_2018": 0.0, "total":2000.0 }, { "entity": "_Test Customer 2", "entity_name": "_Test Customer 2", - "apr": 0.0, - "may": 0.0, - "jun": 0.0, - "jul": 0.0, - "aug": 0.0, - "sep": 1500.0, - "oct": 1000.0, - "nov": 0.0, - "dec": 0.0, - "jan": 0.0, - "feb": 0.0, - "mar": 0.0, + "apr_2017": 0.0, + "may_2017": 0.0, + "jun_2017": 0.0, + "jul_2017": 0.0, + "aug_2017": 0.0, + "sep_2017": 1500.0, + "oct_2017": 1000.0, + "nov_2017": 0.0, + "dec_2017": 0.0, + "jan_2018": 0.0, + "feb_2018": 0.0, + "mar_2018": 0.0, "total":2500.0 }, { "entity": "_Test Customer 3", "entity_name": "_Test Customer 3", - "apr": 0.0, - "may": 0.0, - "jun": 2000.0, - "jul": 1000.0, - "aug": 0.0, - "sep": 0.0, - "oct": 0.0, - "nov": 0.0, - "dec": 0.0, - "jan": 0.0, - "feb": 0.0, - "mar": 0.0, + "apr_2017": 0.0, + "may_2017": 0.0, + "jun_2017": 2000.0, + "jul_2017": 1000.0, + "aug_2017": 0.0, + "sep_2017": 0.0, + "oct_2017": 0.0, + "nov_2017": 0.0, + "dec_2017": 0.0, + "jan_2018": 0.0, + "feb_2018": 0.0, + "mar_2018": 0.0, "total": 3000.0 } ] @@ -103,18 +103,18 @@ class TestAnalytics(unittest.TestCase): expected_first_row = { "entity": "All Customer Groups", "indent": 0, - "apr": 0.0, - "may": 0.0, - "jun": 2000.0, - "jul": 1000.0, - "aug": 0.0, - "sep": 1500.0, - "oct": 1000.0, - "nov": 0.0, - "dec": 0.0, - "jan": 0.0, - "feb": 2000.0, - "mar": 0.0, + "apr_2017": 0.0, + "may_2017": 0.0, + "jun_2017": 2000.0, + "jul_2017": 1000.0, + "aug_2017": 0.0, + "sep_2017": 1500.0, + "oct_2017": 1000.0, + "nov_2017": 0.0, + "dec_2017": 0.0, + "jan_2018": 0.0, + "feb_2018": 2000.0, + "mar_2018": 0.0, "total":7500.0 } self.assertEqual(expected_first_row, report[1][0]) @@ -136,52 +136,52 @@ class TestAnalytics(unittest.TestCase): { "entity": "_Test Customer 1", "entity_name": "_Test Customer 1", - "apr": 0.0, - "may": 0.0, - "jun": 0.0, - "jul": 0.0, - "aug": 0.0, - "sep": 0.0, - "oct": 0.0, - "nov": 0.0, - "dec": 0.0, - "jan": 0.0, - "feb": 20.0, - "mar": 0.0, + "apr_2017": 0.0, + "may_2017": 0.0, + "jun_2017": 0.0, + "jul_2017": 0.0, + "aug_2017": 0.0, + "sep_2017": 0.0, + "oct_2017": 0.0, + "nov_2017": 0.0, + "dec_2017": 0.0, + "jan_2018": 0.0, + "feb_2018": 20.0, + "mar_2018": 0.0, "total":20.0 }, { "entity": "_Test Customer 2", "entity_name": "_Test Customer 2", - "apr": 0.0, - "may": 0.0, - "jun": 0.0, - "jul": 0.0, - "aug": 0.0, - "sep": 15.0, - "oct": 10.0, - "nov": 0.0, - "dec": 0.0, - "jan": 0.0, - "feb": 0.0, - "mar": 0.0, + "apr_2017": 0.0, + "may_2017": 0.0, + "jun_2017": 0.0, + "jul_2017": 0.0, + "aug_2017": 0.0, + "sep_2017": 15.0, + "oct_2017": 10.0, + "nov_2017": 0.0, + "dec_2017": 0.0, + "jan_2018": 0.0, + "feb_2018": 0.0, + "mar_2018": 0.0, "total":25.0 }, { "entity": "_Test Customer 3", "entity_name": "_Test Customer 3", - "apr": 0.0, - "may": 0.0, - "jun": 20.0, - "jul": 10.0, - "aug": 0.0, - "sep": 0.0, - "oct": 0.0, - "nov": 0.0, - "dec": 0.0, - "jan": 0.0, - "feb": 0.0, - "mar": 0.0, + "apr_2017": 0.0, + "may_2017": 0.0, + "jun_2017": 20.0, + "jul_2017": 10.0, + "aug_2017": 0.0, + "sep_2017": 0.0, + "oct_2017": 0.0, + "nov_2017": 0.0, + "dec_2017": 0.0, + "jan_2018": 0.0, + "feb_2018": 0.0, + "mar_2018": 0.0, "total": 30.0 } ] From ee05e358d1a1f2c5aaef32d84d9f02a311bfd68b Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Thu, 29 Nov 2018 16:24:28 +0530 Subject: [PATCH 18/31] Rewrote query using orm --- erpnext/accounts/party.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py index ab7fc7db23..e5cdad1f94 100644 --- a/erpnext/accounts/party.py +++ b/erpnext/accounts/party.py @@ -462,22 +462,22 @@ def get_dashboard_info(party_type, party): doctype = "Sales Invoice" if party_type=="Customer" else "Purchase Invoice" - companies = frappe.db.sql(""" - select distinct company from `tab{0}` - where docstatus =1 and {1} = %s - """ - .format(doctype, party_type.lower()), (party), as_dict=1) + companies = frappe.get_all(doctype, filters={ + 'docstatus': 1, + party_type.lower(): party + }, distinct=1, fields=['company']) company_wise_info = [] - company_wise_grand_total = frappe.db.sql(""" - select company, sum(grand_total) as grand_total, sum(base_grand_total) as base_grand_total - from `tab{0}` - where {1}=%s and docstatus=1 and posting_date between %s and %s - group by company - """ - .format(doctype, party_type.lower()), - (party, current_fiscal_year.year_start_date, current_fiscal_year.year_end_date), as_dict=1) + company_wise_grand_total = frappe.get_all(doctype, + filters={ + 'docstatus': 1, + party_type.lower(): party, + 'posting_date': ('between', [current_fiscal_year.year_start_date, current_fiscal_year.year_end_date]) + }, + group_by="company", + fields=["company", "sum(grand_total) as grand_total", "sum(base_grand_total) as base_grand_total"] + ) company_wise_billing_this_year = frappe._dict() From ca332bdcdbd0ce08d3cbef6e038c229db6d86870 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Thu, 29 Nov 2018 18:15:29 +0530 Subject: [PATCH 19/31] Revert "[Fix] Accounts receivable summary print is not working" --- .../report/accounts_receivable/accounts_receivable.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html index b22f880f6e..b4276a10cd 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html @@ -228,10 +228,10 @@ {% } else { %} {%= __("Total") %} {% } %} - {%= format_currency(data[i][__("Total Invoiced Amt")], data[i]["currency"]) %} - {%= format_currency(data[i][__("Total Paid Amt")], data[i]["currency"]) %} - {%= report.report_name === "Accounts Receivable Summary" ? format_currency(data[i][__("Credit Note Amt")], data[i]["currency"]) : format_currency(data[i][__("Debit Note Amt")], data[i]["currency"]) %} - {%= format_currency(data[i][__("Total Outstanding Amt")], data[i]["currency"]) %} + {%= format_currency(data[i][("total_invoiced_amt")], data[i]["currency"]) %} + {%= format_currency(data[i][("total_paid_amt")], data[i]["currency"]) %} + {%= report.report_name === "Accounts Receivable Summary" ? format_currency(data[i][__("credit_note_amt")], data[i]["currency"]) : format_currency(data[i][__("debit_note_amt")], data[i]["currency"]) %} + {%= format_currency(data[i][("total_outstanding_amt")], data[i]["currency"]) %} {% } %} {% } %} From eda0a6eb331d1ce39d5a2521988431daee2359eb Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 30 Nov 2018 15:15:17 +0530 Subject: [PATCH 20/31] fix(test): Fixed tests for period closing voucher --- .../doctype/period_closing_voucher/period_closing_voucher.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py index 03d0918226..dee8b16358 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py +++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py @@ -75,7 +75,8 @@ class PeriodClosingVoucher(AccountsController): "debit_in_account_currency": abs(net_pl_balance) if net_pl_balance > 0 else 0, "debit": abs(net_pl_balance) if net_pl_balance > 0 else 0, "credit_in_account_currency": abs(net_pl_balance) if net_pl_balance < 0 else 0, - "credit": abs(net_pl_balance) if net_pl_balance < 0 else 0 + "credit": abs(net_pl_balance) if net_pl_balance < 0 else 0, + "cost_center": self.cost_center })) from erpnext.accounts.general_ledger import make_gl_entries From 37b6a2ca0b7e1fbd0a67f70ebb8265677ce2fe36 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Fri, 30 Nov 2018 16:15:43 +0530 Subject: [PATCH 21/31] row check bug fix --- erpnext/selling/report/sales_analytics/sales_analytics.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/selling/report/sales_analytics/sales_analytics.js b/erpnext/selling/report/sales_analytics/sales_analytics.js index ac3ebfef12..0df425d1cd 100644 --- a/erpnext/selling/report/sales_analytics/sales_analytics.js +++ b/erpnext/selling/report/sales_analytics/sales_analytics.js @@ -67,6 +67,9 @@ frappe.query_reports["Sales Analytics"] = { reqd: 1 } ], + after_datatable_render: function(datatable_obj) { + $(datatable_obj.wrapper).find(".dt-row-0").find('input[type=checkbox]').click(); + }, get_datatable_options(options) { return Object.assign(options, { checkboxColumn: true, From 94a35390154eadd612c809dd75bdb4b1b7eac0c9 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Fri, 30 Nov 2018 16:20:48 +0530 Subject: [PATCH 22/31] Row check fix in stock analytics --- erpnext/stock/report/stock_analytics/stock_analytics.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/stock/report/stock_analytics/stock_analytics.js b/erpnext/stock/report/stock_analytics/stock_analytics.js index 12e4350d9a..6b384e2861 100644 --- a/erpnext/stock/report/stock_analytics/stock_analytics.js +++ b/erpnext/stock/report/stock_analytics/stock_analytics.js @@ -71,6 +71,9 @@ frappe.query_reports["Stock Analytics"] = { reqd: 1 } ], + after_datatable_render: function(datatable_obj) { + $(datatable_obj.wrapper).find(".dt-row-0").find('input[type=checkbox]').click(); + }, get_datatable_options(options) { return Object.assign(options, { checkboxColumn: true, From 16b8ecbe058bfb406cc35ddfe9c7bef69626c9fb Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Fri, 30 Nov 2018 16:20:52 +0530 Subject: [PATCH 23/31] [Fix] Stock value difference calculation for stock reconciliation --- .../stock/doctype/stock_reconciliation/stock_reconciliation.py | 2 +- erpnext/stock/stock_ledger.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py index 5b6e706674..257434fb89 100644 --- a/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -180,7 +180,7 @@ class StockReconciliation(StockController): frappe.throw(_("Valuation Rate required for Item in row {0}").format(row.idx)) if ((previous_sle and row.qty == previous_sle.get("qty_after_transaction") - and row.valuation_rate == previous_sle.get("valuation_rate")) + and (row.valuation_rate == previous_sle.get("valuation_rate") or row.qty == 0)) or (not previous_sle and not row.qty)): continue diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index 43140faff6..c73cbf2942 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -176,7 +176,7 @@ class update_entries_after(object): # rounding as per precision self.stock_value = flt(self.stock_value, self.precision) - if self.prev_stock_value < 0 and self.stock_value >= 0: + if self.prev_stock_value < 0 and self.stock_value >= 0 and sle.voucher_type != 'Stock Reconciliation': stock_value_difference = sle.actual_qty * self.valuation_rate else: stock_value_difference = self.stock_value - self.prev_stock_value From ec5bbe351c19d99675bddbe62a912a7faa45e8c0 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Fri, 30 Nov 2018 16:25:16 +0530 Subject: [PATCH 24/31] Row check fix for purchase analytics --- erpnext/buying/report/purchase_analytics/purchase_analytics.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/erpnext/buying/report/purchase_analytics/purchase_analytics.js b/erpnext/buying/report/purchase_analytics/purchase_analytics.js index 139c4b7af5..b55046e065 100644 --- a/erpnext/buying/report/purchase_analytics/purchase_analytics.js +++ b/erpnext/buying/report/purchase_analytics/purchase_analytics.js @@ -68,6 +68,9 @@ frappe.query_reports["Purchase Analytics"] = { } ], + after_datatable_render: function(datatable_obj) { + $(datatable_obj.wrapper).find(".dt-row-0").find('input[type=checkbox]').click(); + }, get_datatable_options(options) { return Object.assign(options, { checkboxColumn: true, From 4c79274054d2b9a06cb8439a9ca90704281fb166 Mon Sep 17 00:00:00 2001 From: deepeshgarg007 Date: Fri, 30 Nov 2018 18:01:22 +0530 Subject: [PATCH 25/31] Fixed patch and deprecated grid reports --- .../buying/page/purchase_analytics/README.md | 1 - .../page/purchase_analytics/__init__.py | 1 - .../purchase_analytics/purchase_analytics.js | 231 ---------------- .../purchase_analytics.json | 23 -- .../page/production_analytics/__init__.py | 1 - .../production_analytics.js | 155 ----------- .../production_analytics.json | 26 -- erpnext/patches.txt | 8 +- .../selling/page/sales_analytics/README.md | 1 - .../selling/page/sales_analytics/__init__.py | 1 - .../page/sales_analytics/sales_analytics.js | 246 ------------------ .../page/sales_analytics/sales_analytics.json | 26 -- erpnext/stock/page/stock_analytics/README.md | 1 - .../stock/page/stock_analytics/__init__.py | 1 - .../page/stock_analytics/stock_analytics.js | 16 -- .../page/stock_analytics/stock_analytics.json | 23 -- 16 files changed, 4 insertions(+), 757 deletions(-) delete mode 100644 erpnext/buying/page/purchase_analytics/README.md delete mode 100644 erpnext/buying/page/purchase_analytics/__init__.py delete mode 100644 erpnext/buying/page/purchase_analytics/purchase_analytics.js delete mode 100644 erpnext/buying/page/purchase_analytics/purchase_analytics.json delete mode 100644 erpnext/manufacturing/page/production_analytics/__init__.py delete mode 100644 erpnext/manufacturing/page/production_analytics/production_analytics.js delete mode 100644 erpnext/manufacturing/page/production_analytics/production_analytics.json delete mode 100644 erpnext/selling/page/sales_analytics/README.md delete mode 100644 erpnext/selling/page/sales_analytics/__init__.py delete mode 100644 erpnext/selling/page/sales_analytics/sales_analytics.js delete mode 100644 erpnext/selling/page/sales_analytics/sales_analytics.json delete mode 100644 erpnext/stock/page/stock_analytics/README.md delete mode 100644 erpnext/stock/page/stock_analytics/__init__.py delete mode 100644 erpnext/stock/page/stock_analytics/stock_analytics.js delete mode 100644 erpnext/stock/page/stock_analytics/stock_analytics.json diff --git a/erpnext/buying/page/purchase_analytics/README.md b/erpnext/buying/page/purchase_analytics/README.md deleted file mode 100644 index 332e4c2c05..0000000000 --- a/erpnext/buying/page/purchase_analytics/README.md +++ /dev/null @@ -1 +0,0 @@ -Trends of purchases across Items, Item Groups, Suppliers. \ No newline at end of file diff --git a/erpnext/buying/page/purchase_analytics/__init__.py b/erpnext/buying/page/purchase_analytics/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/erpnext/buying/page/purchase_analytics/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/erpnext/buying/page/purchase_analytics/purchase_analytics.js b/erpnext/buying/page/purchase_analytics/purchase_analytics.js deleted file mode 100644 index 06764a3c60..0000000000 --- a/erpnext/buying/page/purchase_analytics/purchase_analytics.js +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -// License: GNU General Public License v3. See license.txt - -frappe.pages['purchase-analytics'].on_page_load = function(wrapper) { - frappe.ui.make_app_page({ - parent: wrapper, - title: __('Purchase Analytics'), - single_column: true - }); - - new erpnext.PurchaseAnalytics(wrapper); - - frappe.breadcrumbs.add("Buying"); -} - -erpnext.PurchaseAnalytics = frappe.views.TreeGridReport.extend({ - init: function(wrapper) { - this._super({ - title: __("Purchase Analytics"), - parent: $(wrapper).find('.layout-main'), - page: wrapper.page, - doctypes: ["Item", "Item Group", "Supplier", "Supplier Group", "Company", "Fiscal Year", - "Purchase Invoice", "Purchase Invoice Item", - "Purchase Order", "Purchase Order Item[Purchase Analytics]", - "Purchase Receipt", "Purchase Receipt Item[Purchase Analytics]"], - tree_grid: { show: true } - }); - - this.tree_grids = { - "Supplier Group": { - label: __("Supplier Group / Supplier"), - show: true, - item_key: "supplier", - parent_field: "parent_supplier_group", - formatter: function(item) { - return item.supplier_name ? item.supplier_name + " (" + item.name + ")" : item.name; - } - }, - "Supplier": { - label: __("Supplier"), - show: false, - item_key: "supplier", - formatter: function(item) { - return item.supplier_name ? item.supplier_name + " (" + item.name + ")" : item.name; - } - }, - "Item Group": { - label: "Item", - show: true, - parent_field: "parent_item_group", - item_key: "item_code", - formatter: function(item) { - return item.name; - } - }, - "Item": { - label: "Item", - show: false, - item_key: "item_code", - formatter: function(item) { - return item.name; - } - }, - } - }, - setup_columns: function() { - this.tree_grid = this.tree_grids[this.tree_type]; - - var std_columns = [ - {id: "name", name: this.tree_grid.label, field: "name", width: 300}, - {id: "total", name: "Total", field: "total", plot: false, - formatter: this.currency_formatter} - ]; - - this.make_date_range_columns(); - this.columns = std_columns.concat(this.columns); - }, - filters: [ - {fieldtype:"Select", label: __("Tree Type"), fieldname: "tree_type", - options:["Supplier Group", "Supplier", "Item Group", "Item"], - filter: function(val, item, opts, me) { - return me.apply_zero_filter(val, item, opts, me); - }}, - {fieldtype:"Select", label: __("Based On"), fieldname: "based_on", - options:["Purchase Invoice", "Purchase Order", "Purchase Receipt"]}, - {fieldtype:"Select", label: __("Value or Qty"), fieldname: "value_or_qty", - options:["Value", "Quantity"]}, - {fieldtype:"Select", label: __("Company"), link:"Company", fieldname: "company", - default_value: __("Select Company...")}, - {fieldtype:"Date", label: __("From Date"), fieldname: "from_date"}, - {fieldtype:"Date", label: __("To Date"), fieldname: "to_date"}, - {fieldtype:"Select", label: __("Range"), fieldname: "range", - options:[{label: __("Daily"), value: "Daily"}, {label: __("Weekly"), value: "Weekly"}, - {label: __("Monthly"), value: "Monthly"}, {label: __("Quarterly"), value: "Quarterly"}, - {label: __("Yearly"), value: "Yearly"}]} - ], - setup_filters: function() { - var me = this; - this._super(); - - this.trigger_refresh_on_change(["value_or_qty", "tree_type", "based_on", "company"]); - - this.show_zero_check(); - }, - init_filter_values: function() { - this._super(); - this.filter_inputs.range.val('Monthly'); - }, - prepare_data: function() { - var me = this; - if (!this.tl) { - // add 'Not Set' Supplier & Item - // (Supplier / Item are not mandatory!!) - frappe.report_dump.data["Supplier"].push({ - name: __("Not Set"), - parent_supplier_group: __("All Supplier Groups"), - id: "Not Set", - }); - - frappe.report_dump.data["Item"].push({ - name: __("Not Set"), - parent_item_group: "All Item Groups", - id: "Not Set", - }); - } - - if (!this.tl || !this.tl[this.based_on]) { - this.make_transaction_list(this.based_on, this.based_on + " Item"); - } - - - if(!this.data || me.item_type != me.tree_type) { - var items; - if(me.tree_type=='Supplier') { - items = frappe.report_dump.data["Supplier"]; - } else if(me.tree_type=='Supplier Group') { - items = this.prepare_tree("Supplier", "Supplier Group"); - } else if(me.tree_type=="Item Group") { - items = this.prepare_tree("Item", "Item Group"); - } else if(me.tree_type=="Item") { - items = frappe.report_dump.data["Item"]; - } - - me.item_type = me.tree_type - me.parent_map = {}; - me.item_by_name = {}; - me.data = []; - - $.each(items, function(i, v) { - var d = copy_dict(v); - - me.data.push(d); - me.item_by_name[d.name] = d; - if(d[me.tree_grid.parent_field]) { - me.parent_map[d.name] = d[me.tree_grid.parent_field]; - } - me.reset_item_values(d); - }); - - this.set_indent(); - - } else { - // otherwise, only reset values - $.each(this.data, function(i, d) { - me.reset_item_values(d); - }); - } - - this.prepare_balances(); - if(me.tree_grid.show) { - this.set_totals(false); - this.update_groups(); - } else { - this.set_totals(true); - } - }, - prepare_balances: function() { - var me = this; - var from_date = frappe.datetime.str_to_obj(this.from_date); - var to_date = frappe.datetime.str_to_obj(this.to_date); - var is_val = this.value_or_qty == 'Value'; - - $.each(this.tl[this.based_on], function(i, tl) { - if (me.is_default('company') ? true : tl.company === me.company) { - var posting_date = frappe.datetime.str_to_obj(tl.posting_date); - if (posting_date >= from_date && posting_date <= to_date) { - var item = me.item_by_name[tl[me.tree_grid.item_key]] || - me.item_by_name['Not Set']; - item[me.column_map[tl.posting_date].field] += (is_val ? tl.base_net_amount : tl.qty); - } - } - }); - }, - update_groups: function() { - var me = this; - - $.each(this.data, function(i, item) { - var parent = me.parent_map[item.name]; - while(parent) { - var parent_group = me.item_by_name[parent]; - - $.each(me.columns, function(c, col) { - if (col.formatter == me.currency_formatter) { - parent_group[col.field] = - flt(parent_group[col.field]) - + flt(item[col.field]); - } - }); - parent = me.parent_map[parent]; - } - }); - }, - set_totals: function(sort) { - var me = this; - var checked = false; - $.each(this.data, function(i, d) { - d.total = 0.0; - $.each(me.columns, function(i, col) { - if(col.formatter==me.currency_formatter && !col.hidden && col.field!="total") - d.total += d[col.field]; - if(d.checked) checked = true; - }) - }); - - if(sort)this.data = this.data.sort(function(a, b) { return b.total - a.total; }); - - if(!this.checked) { - this.data[0].checked = true; - } - } -}); diff --git a/erpnext/buying/page/purchase_analytics/purchase_analytics.json b/erpnext/buying/page/purchase_analytics/purchase_analytics.json deleted file mode 100644 index ad13c7d415..0000000000 --- a/erpnext/buying/page/purchase_analytics/purchase_analytics.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "creation": "2012-09-21 20:15:16.000000", - "docstatus": 0, - "doctype": "Page", - "icon": "fa fa-bar-chart", - "idx": 1, - "modified": "2013-07-11 14:43:52.000000", - "modified_by": "Administrator", - "module": "Buying", - "name": "purchase-analytics", - "owner": "Administrator", - "page_name": "purchase-analytics", - "roles": [ - { - "role": "Analytics" - }, - { - "role": "Purchase Manager" - } - ], - "standard": "Yes", - "title": "Purchase Analytics" -} \ No newline at end of file diff --git a/erpnext/manufacturing/page/production_analytics/__init__.py b/erpnext/manufacturing/page/production_analytics/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/erpnext/manufacturing/page/production_analytics/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/erpnext/manufacturing/page/production_analytics/production_analytics.js b/erpnext/manufacturing/page/production_analytics/production_analytics.js deleted file mode 100644 index 1647313036..0000000000 --- a/erpnext/manufacturing/page/production_analytics/production_analytics.js +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -// License: GNU General Public License v3. See license.txt - -frappe.pages['production-analytics'].on_page_load = function(wrapper) { - frappe.ui.make_app_page({ - parent: wrapper, - title: __('Production Analytics'), - single_column: true - }); - - new erpnext.ProductionAnalytics(wrapper); - - frappe.breadcrumbs.add("Manufacturing"); -} - -erpnext.ProductionAnalytics = frappe.views.GridReportWithPlot.extend({ - init: function(wrapper) { - this._super({ - title: __("Production Analytics"), - parent: $(wrapper).find('.layout-main'), - page: wrapper.page, - doctypes: ["Item", "Company", "Fiscal Year", "Work Order"] - }); - - }, - setup_columns: function() { - - var std_columns = [ - {id: "name", name: __("Status"), field: "name", width: 100} - ]; - - this.make_date_range_columns(); - this.columns = std_columns.concat(this.columns); - }, - filters: [ - {fieldtype:"Select", label: __("Company"), link:"Company", fieldname: "company", - default_value: __("Select Company...")}, - {fieldtype:"Date", label: __("From Date"), fieldname: "from_date"}, - {fieldtype:"Date", label: __("To Date"), fieldname: "to_date"}, - {fieldtype:"Select", label: __("Range"), fieldname: "range", - options:[{label: __("Daily"), value: "Daily"}, {label: __("Weekly"), value: "Weekly"}, - {label: __("Monthly"), value: "Monthly"}, {label: __("Quarterly"), value: "Quarterly"}, - {label: __("Yearly"), value: "Yearly"}]} - ], - setup_filters: function() { - var me = this; - this._super(); - - this.trigger_refresh_on_change(["company"]); - this.trigger_refresh_on_change(["range"]); - - this.show_zero_check(); - - }, - init_filter_values: function() { - this._super(); - this.filter_inputs.range.val('Monthly'); - }, - setup_chart: function() { - var me = this; - - var chart_data = this.get_chart_data ? this.get_chart_data() : null; - - const parent = this.wrapper.find('.chart')[0]; - this.chart = new Chart(parent, { - height: 200, - data: chart_data, - type: 'line' - }); - }, - set_default_values: function() { - var values = { - from_date: frappe.datetime.str_to_user(frappe.datetime.add_months(frappe.datetime.now_datetime(),-12) ), - to_date: frappe.datetime.str_to_user(frappe.datetime.add_months(frappe.datetime.now_datetime(),1)) - } - - var me = this; - $.each(values, function(i, v) { - if(me.filter_inputs[i] && !me.filter_inputs[i].val()) - me.filter_inputs[i].val(v); - }) - }, - - prepare_data: function() { - // add Opening, Closing, Totals rows - // if filtered by account and / or voucher - var me = this; - var all_open_orders = {name:"All Work Orders", "id": "all-open-pos", - checked:true}; - var not_started = {name:"Not Started", "id":"not-started-pos", - checked:true}; - var overdue = {name:"Overdue (Not Started)", "id":"overdue-pos", - checked:true}; - var pending = {name:"Pending", "id":"pending-pos", - checked:true}; - var completed = {name:"Completed", "id":"completed-pos", - checked:true}; - - $.each(frappe.report_dump.data["Work Order"], function(i, d) { - var dateobj = frappe.datetime.str_to_obj(d.creation); - var date = frappe.datetime.str_to_user(d.creation.split(" ")[0]); - - $.each(me.columns, function(i,col) { - if (i > 1){ - var start_period = frappe.datetime.user_to_obj(frappe.datetime.str_to_user(col.id)); - var end_period = frappe.datetime.user_to_obj(frappe.datetime.str_to_user(col.name)); - var astart_date = frappe.datetime.user_to_obj(frappe.datetime.str_to_user(d.actual_start_date)); - var planned_start_date = frappe.datetime.user_to_obj(frappe.datetime.str_to_user(d.planned_start_date)); - var aend_date = frappe.datetime.user_to_obj(frappe.datetime.str_to_user(d.actual_end_date)); - var modified = frappe.datetime.user_to_obj(frappe.datetime.str_to_user(d.modified)); - - if (dateobj <= start_period || dateobj <= end_period) { - all_open_orders[col.field] = flt(all_open_orders[col.field]) + 1; - - if(d.status=="Completed") { - if(aend_date < start_period || modified < start_period) { - completed[col.field] = flt(completed[col.field]) + 1; - } - else if (astart_date < start_period) { - pending[col.field] = flt(pending[col.field]) + 1; - } - else if (planned_start_date < start_period) { - overdue[col.field] = flt(overdue[col.field]) + 1; - } else { - not_started[col.field] = flt(not_started[col.field]) + 1; - } - }else if(d.status == "In Process") - { - if (astart_date < start_period || modified < start_period){ - pending[col.field] = flt(pending[col.field]) + 1; - }else if (planned_start_date < start_period) { - overdue[col.field] = flt(overdue[col.field]) + 1; - }else{ - not_started[col.field] = flt(not_started[col.field]) + 1; - } - }else if(d.status == "Not Started") { - if (planned_start_date < start_period){ - overdue[col.field] = flt(overdue[col.field]) + 1; - }else{ - not_started[col.field] = flt(not_started[col.field]) + 1; - } - } - } - } - }); - }); - if(me.columns.length < 30){ - this.chart_area.toggle(true); - }else { - this.chart_area.toggle(false); - } - this.data = [all_open_orders, not_started, overdue, pending, completed]; - - } -}); diff --git a/erpnext/manufacturing/page/production_analytics/production_analytics.json b/erpnext/manufacturing/page/production_analytics/production_analytics.json deleted file mode 100644 index cd73bc826f..0000000000 --- a/erpnext/manufacturing/page/production_analytics/production_analytics.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "content": null, - "creation": "2012-09-21 20:15:16", - "docstatus": 0, - "doctype": "Page", - "icon": "fa fa-bar-chart", - "idx": 1, - "modified": "2017-02-20 17:33:05.913097", - "modified_by": "Administrator", - "module": "Manufacturing", - "name": "production-analytics", - "owner": "Administrator", - "page_name": "production-analytics", - "roles": [ - { - "role": "Analytics" - }, - { - "role": "Manufacturing Manager" - } - ], - "script": null, - "standard": "Yes", - "style": null, - "title": "Production Analytics" -} \ No newline at end of file diff --git a/erpnext/patches.txt b/erpnext/patches.txt index dc4c94c8d1..4a67eb4e47 100755 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -568,10 +568,10 @@ erpnext.patches.v11_0.remove_land_unit_icon erpnext.patches.v11_0.add_default_dispatch_notification_template erpnext.patches.v11_0.add_market_segments erpnext.patches.v11_0.add_sales_stages -execute:frappe.delete_doc("Page", "sales-analytics") -execute:frappe.delete_doc("Page", "purchase-analytics") -execute:frappe.delete_doc("Page", "stock-analytics") -execute:frappe.delete_doc("Page", "production-analytics") +execute:frappe.delete_doc_if_exists("Page", "sales-analytics") +execute:frappe.delete_doc_if_exists("Page", "purchase-analytics") +execute:frappe.delete_doc_if_exists("Page", "stock-analytics") +execute:frappe.delete_doc_if_exists("Page", "production-analytics") erpnext.patches.v11_0.ewaybill_fields_gst_india #2018-11-13 erpnext.patches.v11_0.drop_column_max_days_allowed erpnext.patches.v11_0.change_healthcare_desktop_icons diff --git a/erpnext/selling/page/sales_analytics/README.md b/erpnext/selling/page/sales_analytics/README.md deleted file mode 100644 index 11994c26b9..0000000000 --- a/erpnext/selling/page/sales_analytics/README.md +++ /dev/null @@ -1 +0,0 @@ -Trends of sales by Item, Item Group, Customer etc. \ No newline at end of file diff --git a/erpnext/selling/page/sales_analytics/__init__.py b/erpnext/selling/page/sales_analytics/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/erpnext/selling/page/sales_analytics/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/erpnext/selling/page/sales_analytics/sales_analytics.js b/erpnext/selling/page/sales_analytics/sales_analytics.js deleted file mode 100644 index f5caf1d591..0000000000 --- a/erpnext/selling/page/sales_analytics/sales_analytics.js +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -// License: GNU General Public License v3. See license.txt - -frappe.pages['sales-analytics'].on_page_load = function(wrapper) { - frappe.ui.make_app_page({ - parent: wrapper, - title: __('Sales Analytics'), - single_column: true - }); - new erpnext.SalesAnalytics(wrapper); - - - frappe.breadcrumbs.add("Selling") - -}; - -erpnext.SalesAnalytics = frappe.views.TreeGridReport.extend({ - init: function(wrapper) { - this._super({ - title: __("Sales Analytics"), - parent: $(wrapper).find('.layout-main'), - page: wrapper.page, - doctypes: ["Item", "Item Group", "Customer", "Customer Group", "Company", "Territory", - "Fiscal Year", "Sales Invoice", "Sales Invoice Item", - "Sales Order", "Sales Order Item[Sales Analytics]", - "Delivery Note", "Delivery Note Item[Sales Analytics]"], - tree_grid: { show: true } - }); - - this.tree_grids = { - "Customer Group": { - label: __("Customer Group / Customer"), - show: true, - item_key: "customer", - parent_field: "parent_customer_group", - formatter: function(item) { - return item.customer_name? item.customer_name + " (" + item.name + ")" : item.name; - } - }, - "Customer": { - label: __("Customer"), - show: false, - item_key: "customer", - formatter: function(item) { - return item.customer_name? item.customer_name + " (" + item.name + ")" : item.name; - } - }, - "Item Group": { - label: __("Item"), - show: true, - parent_field: "parent_item_group", - item_key: "item_code", - formatter: function(item) { - return item.name; - } - }, - "Item": { - label: __("Item"), - show: false, - item_key: "item_code", - formatter: function(item) { - return item.name; - } - }, - "Territory": { - label: __("Territory / Customer"), - show: true, - item_key: "customer", - parent_field: "parent_territory", - formatter: function(item) { - return item.customer_name? item.customer_name + " (" + item.name + ")" : item.name; - } - } - } - }, - setup_columns: function() { - this.tree_grid = this.tree_grids[this.tree_type]; - - var std_columns = [ - {id: "name", name: this.tree_grid.label, field: "name", width: 300}, - {id: "total", name: "Total", field: "total", plot: false, - formatter: this.currency_formatter} - ]; - - this.make_date_range_columns(); - this.columns = std_columns.concat(this.columns); - }, - filters: [ - {fieldtype:"Select", fieldname: "tree_type", label: __("Tree Type"), options:["Customer Group", "Customer", - "Item Group", "Item", "Territory"], - filter: function(val, item, opts, me) { - return me.apply_zero_filter(val, item, opts, me); - }}, - {fieldtype:"Select", fieldname: "based_on", label: __("Based On"), options:["Sales Invoice", - "Sales Order", "Delivery Note"]}, - {fieldtype:"Select", fieldname: "value_or_qty", label: __("Value or Qty"), - options:[{label: __("Value"), value: "Value"}, {label: __("Quantity"), value: "Quantity"}]}, - {fieldtype:"Date", fieldname: "from_date", label: __("From Date")}, - {fieldtype:"Label", fieldname: "to", label: __("To")}, - {fieldtype:"Date", fieldname: "to_date", label: __("To Date")}, - {fieldtype:"Select", fieldname: "company", label: __("Company"), link:"Company", - default_value: __("Select Company...")}, - {fieldtype:"Select", label: __("Range"), fieldname: "range", - options:[{label: __("Daily"), value: "Daily"}, {label: __("Weekly"), value: "Weekly"}, - {label: __("Monthly"), value: "Monthly"}, {label: __("Quarterly"), value: "Quarterly"}, - {label: __("Yearly"), value: "Yearly"}]} - ], - setup_filters: function() { - var me = this; - this._super(); - - this.trigger_refresh_on_change(["value_or_qty", "tree_type", "based_on", "company"]); - - this.show_zero_check(); - }, - init_filter_values: function() { - this._super(); - this.filter_inputs.range.val('Monthly'); - }, - prepare_data: function() { - var me = this; - if (!this.tl) { - // add 'Not Set' Customer & Item - // (Customer / Item are not mandatory!!) - frappe.report_dump.data["Customer"].push({ - name: "Not Set", - parent_customer_group: "All Customer Groups", - parent_territory: "All Territories", - id: "Not Set", - }); - - frappe.report_dump.data["Item"].push({ - name: "Not Set", - parent_item_group: "All Item Groups", - id: "Not Set", - }); - } - - if (!this.tl || !this.tl[this.based_on]) { - this.make_transaction_list(this.based_on, this.based_on + " Item"); - } - - if(!this.data || me.item_type != me.tree_type) { - if(me.tree_type=='Customer') { - var items = frappe.report_dump.data["Customer"]; - } if(me.tree_type=='Customer Group') { - var items = this.prepare_tree("Customer", "Customer Group"); - } else if(me.tree_type=="Item Group") { - var items = this.prepare_tree("Item", "Item Group"); - } else if(me.tree_type=="Item") { - var items = frappe.report_dump.data["Item"]; - } else if(me.tree_type=="Territory") { - var items = this.prepare_tree("Customer", "Territory"); - } - - me.item_type = me.tree_type - me.parent_map = {}; - me.item_by_name = {}; - me.data = []; - - $.each(items, function(i, v) { - var d = copy_dict(v); - - me.data.push(d); - me.item_by_name[d.name] = d; - if(d[me.tree_grid.parent_field]) { - me.parent_map[d.name] = d[me.tree_grid.parent_field]; - } - me.reset_item_values(d); - }); - - this.set_indent(); - - } else { - // otherwise, only reset values - $.each(this.data, function(i, d) { - me.reset_item_values(d); - }); - } - - this.prepare_balances(); - if(me.tree_grid.show) { - this.set_totals(false); - this.update_groups(); - } else { - this.set_totals(true); - } - - }, - prepare_balances: function() { - var me = this; - var from_date = frappe.datetime.str_to_obj(this.from_date); - var to_date = frappe.datetime.str_to_obj(this.to_date); - var is_val = this.value_or_qty == 'Value'; - - $.each(this.tl[this.based_on], function(i, tl) { - if (me.is_default('company') ? true : tl.company === me.company) { - var posting_date = frappe.datetime.str_to_obj(tl.posting_date); - if (posting_date >= from_date && posting_date <= to_date) { - var item = me.item_by_name[tl[me.tree_grid.item_key]] || - me.item_by_name['Not Set']; - if(item){ - item[me.column_map[tl.posting_date].field] += (is_val ? tl.base_net_amount : tl.qty); - } - } - } - }); - }, - update_groups: function() { - var me = this; - - $.each(this.data, function(i, item) { - var parent = me.parent_map[item.name]; - while(parent) { - var parent_group = me.item_by_name[parent]; - - $.each(me.columns, function(c, col) { - if (col.formatter == me.currency_formatter) { - parent_group[col.field] = - flt(parent_group[col.field]) - + flt(item[col.field]); - } - }); - parent = me.parent_map[parent]; - } - }); - }, - set_totals: function(sort) { - var me = this; - var checked = false; - $.each(this.data, function(i, d) { - d.total = 0.0; - $.each(me.columns, function(i, col) { - if(col.formatter==me.currency_formatter && !col.hidden && col.field!="total") - d.total += d[col.field]; - if(d.checked) checked = true; - }) - }); - - if(sort)this.data = this.data.sort(function(a, b) { return a.total < b.total; }); - - if(!this.checked) { - this.data[0].checked = true; - } - } -}); diff --git a/erpnext/selling/page/sales_analytics/sales_analytics.json b/erpnext/selling/page/sales_analytics/sales_analytics.json deleted file mode 100644 index 4a7761ebaf..0000000000 --- a/erpnext/selling/page/sales_analytics/sales_analytics.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "creation": "2012-09-21 20:15:12.000000", - "docstatus": 0, - "doctype": "Page", - "icon": "fa fa-bar-chart", - "idx": 1, - "modified": "2013-07-11 14:43:59.000000", - "modified_by": "Administrator", - "module": "Selling", - "name": "sales-analytics", - "owner": "Administrator", - "page_name": "sales-analytics", - "roles": [ - { - "role": "Analytics" - }, - { - "role": "Sales Manager" - }, - { - "role": "Maintenance Manager" - } - ], - "standard": "Yes", - "title": "Sales Analytics" -} \ No newline at end of file diff --git a/erpnext/stock/page/stock_analytics/README.md b/erpnext/stock/page/stock_analytics/README.md deleted file mode 100644 index 86c3644322..0000000000 --- a/erpnext/stock/page/stock_analytics/README.md +++ /dev/null @@ -1 +0,0 @@ -Trends of Items quantities and values. \ No newline at end of file diff --git a/erpnext/stock/page/stock_analytics/__init__.py b/erpnext/stock/page/stock_analytics/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/erpnext/stock/page/stock_analytics/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/erpnext/stock/page/stock_analytics/stock_analytics.js b/erpnext/stock/page/stock_analytics/stock_analytics.js deleted file mode 100644 index 6deeb7a1f4..0000000000 --- a/erpnext/stock/page/stock_analytics/stock_analytics.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -// License: GNU General Public License v3. See license.txt - -frappe.pages['stock-analytics'].on_page_load = function(wrapper) { - frappe.ui.make_app_page({ - parent: wrapper, - title: __('Stock Analytics'), - single_column: true - }); - - frappe.require(["assets/erpnext/js/stock_grid_report.js", - "assets/erpnext/js/stock_analytics.js"], function() { - new erpnext.StockAnalytics(wrapper); - frappe.breadcrumbs.add("Stock") - }); -}; diff --git a/erpnext/stock/page/stock_analytics/stock_analytics.json b/erpnext/stock/page/stock_analytics/stock_analytics.json deleted file mode 100644 index 90e9f2e56b..0000000000 --- a/erpnext/stock/page/stock_analytics/stock_analytics.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "creation": "2012-09-21 20:15:14.000000", - "docstatus": 0, - "doctype": "Page", - "icon": "fa fa-bar-chart", - "idx": 1, - "modified": "2013-07-11 14:44:10.000000", - "modified_by": "Administrator", - "module": "Stock", - "name": "stock-analytics", - "owner": "Administrator", - "page_name": "stock-analytics", - "roles": [ - { - "role": "Analytics" - }, - { - "role": "Material Manager" - } - ], - "standard": "Yes", - "title": "Stock Analytics" -} \ No newline at end of file From a8003c1af7e06eee1e0b2ea3f7e38f64b460df7e Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Mon, 3 Dec 2018 11:49:52 +0530 Subject: [PATCH 26/31] [Fix] Permissions issue while making item variants --- erpnext/stock/doctype/item/item.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/stock/doctype/item/item.js b/erpnext/stock/doctype/item/item.js index 86594a2a26..3bebd296ce 100644 --- a/erpnext/stock/doctype/item/item.js +++ b/erpnext/stock/doctype/item/item.js @@ -458,7 +458,7 @@ $.extend(erpnext.item, { fields: ["attribute_value"], limit_start: 0, limit_page_length: 500, - parent: "Item" + parent: "Item Attribute" } }).then((r) => { if(r.message) { @@ -579,7 +579,7 @@ $.extend(erpnext.item, { ["attribute_value", "like", term + "%"] ], fields: ["attribute_value"], - parent: "Item" + parent: "Item Attribute" }, callback: function(r) { if (r.message) { From db43c3af68bb95039cee168c2dc5b27a413a469b Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Mon, 3 Dec 2018 12:15:10 +0530 Subject: [PATCH 27/31] display message if details to fetch grade isnt filled up --- .../doctype/assessment_result/assessment_result.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/erpnext/education/doctype/assessment_result/assessment_result.js b/erpnext/education/doctype/assessment_result/assessment_result.js index cf176aa520..27f549016d 100644 --- a/erpnext/education/doctype/assessment_result/assessment_result.js +++ b/erpnext/education/doctype/assessment_result/assessment_result.js @@ -50,6 +50,12 @@ frappe.ui.form.on("Assessment Result", { frappe.ui.form.on("Assessment Result Detail", { score: function(frm, cdt, cdn) { var d = locals[cdt][cdn]; + + if(!d.maximum_score || !frm.doc.grading_scale) { + d.score = ""; + frappe.throw(__("Please fill in all the details to generate Assessment Result.")); + } + if (d.score > d.maximum_score) { frappe.throw(__("Score cannot be greater than Maximum Score")); } From dd7b020b0177d3200c7512dc6a398a5d88d23510 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 3 Dec 2018 14:24:41 +0530 Subject: [PATCH 28/31] fix(test): Fixed tests for period closing voucher --- .../doctype/period_closing_voucher/period_closing_voucher.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py index dee8b16358..7a2e25474a 100644 --- a/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py +++ b/erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py @@ -70,13 +70,14 @@ class PeriodClosingVoucher(AccountsController): net_pl_balance += flt(acc.balance_in_company_currency) if net_pl_balance: + cost_center = frappe.db.get_value("Company", self.company, "cost_center") gl_entries.append(self.get_gl_dict({ "account": self.closing_account_head, "debit_in_account_currency": abs(net_pl_balance) if net_pl_balance > 0 else 0, "debit": abs(net_pl_balance) if net_pl_balance > 0 else 0, "credit_in_account_currency": abs(net_pl_balance) if net_pl_balance < 0 else 0, "credit": abs(net_pl_balance) if net_pl_balance < 0 else 0, - "cost_center": self.cost_center + "cost_center": cost_center })) from erpnext.accounts.general_ledger import make_gl_entries From 675567419b564d4ab2992df763751edcec40b5ad Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 4 Dec 2018 18:43:52 +0530 Subject: [PATCH 29/31] [Fix] Permissions issue --- erpnext/public/js/utils/item_quick_entry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/public/js/utils/item_quick_entry.js b/erpnext/public/js/utils/item_quick_entry.js index b2e0b85556..0248f9a187 100644 --- a/erpnext/public/js/utils/item_quick_entry.js +++ b/erpnext/public/js/utils/item_quick_entry.js @@ -320,7 +320,7 @@ frappe.ui.form.ItemQuickEntryForm = frappe.ui.form.QuickEntryForm.extend({ ["attribute_value", "like", e.target.value + "%"] ], fields: ["attribute_value"], - parent: "Item" + parent: "Item Attribute" }, callback: function(r) { if (r.message) { From be0a349a5273bb5cc34e3f39a6efdfe13ae051e0 Mon Sep 17 00:00:00 2001 From: Frappe Bot Date: Thu, 6 Dec 2018 09:14:35 +0000 Subject: [PATCH 30/31] bumped to version 10.1.74 --- erpnext/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 97359ede97..2f63374928 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '10.1.73' +__version__ = '10.1.74' def get_default_company(user=None): '''Get default company for user''' From 4f1c65905008f8022657cd88f47704bca04fd781 Mon Sep 17 00:00:00 2001 From: Frappe Bot Date: Thu, 6 Dec 2018 09:50:24 +0000 Subject: [PATCH 31/31] bumped to version 11.0.3-beta.26 --- erpnext/hooks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index cbd3939b7b..c1bb41be74 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -12,7 +12,7 @@ app_license = "GNU General Public License (v3)" source_link = "https://github.com/frappe/erpnext" develop_version = '12.x.x-develop' -staging_version = '11.0.3-beta.25' +staging_version = '11.0.3-beta.26' error_report_email = "support@erpnext.com"