diff --git a/.gitignore b/.gitignore index f905ec22a..cdfce720a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ *.egg-info *.swp tags -bloomstack_core/docs/current \ No newline at end of file +node_modules +bloomstack_core/docs/current diff --git a/bloomstack_core/bloomstack_core/custom/accounts_settings.json b/bloomstack_core/bloomstack_core/custom/accounts_settings.json new file mode 100644 index 000000000..82ff1228b --- /dev/null +++ b/bloomstack_core/bloomstack_core/custom/accounts_settings.json @@ -0,0 +1,83 @@ +{ + "custom_fields": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-01-29 00:54:39.492349", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Accounts Settings", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "auto_create_invoice_on_delivery_note_submit", + "fieldtype": "Check", + "hidden": 0, + "idx": 11, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "allow_cost_center_in_entry_of_bs_account", + "label": "Auto-Create Invoice on Delivery Note submit", + "modified": "2019-01-29 00:54:39.492349", + "modified_by": "Administrator", + "name": "Accounts Settings-auto_create_invoice_on_delivery_note_submit", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + } + ], + "custom_perms": [], + "doctype": "Accounts Settings", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-01-29 00:54:46.302013", + "default_value": null, + "doc_type": "Accounts Settings", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2019-01-29 00:54:46.302013", + "modified_by": "Administrator", + "name": "Accounts Settings-read_only_onload", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "read_only_onload", + "property_type": "Check", + "value": null + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/custom/bom.json b/bloomstack_core/bloomstack_core/custom/bom.json new file mode 100644 index 000000000..660df163c --- /dev/null +++ b/bloomstack_core/bloomstack_core/custom/bom.json @@ -0,0 +1,54 @@ +{ + "custom_fields": [], + "custom_perms": [], + "doctype": "BOM", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-08-05 00:09:19.489037", + "default_value": null, + "doc_type": "BOM", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2019-08-05 00:09:19.489037", + "modified_by": "Administrator", + "name": "BOM-read_only_onload", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "read_only_onload", + "property_type": "Check", + "value": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-08-05 00:09:19.464857", + "default_value": null, + "doc_type": "BOM", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2019-08-05 00:09:19.464857", + "modified_by": "Administrator", + "name": "BOM-title_field", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "title_field", + "property_type": "Data", + "value": "item_name" + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/custom/company.json b/bloomstack_core/bloomstack_core/custom/company.json new file mode 100644 index 000000000..e2583ced1 --- /dev/null +++ b/bloomstack_core/bloomstack_core/custom/company.json @@ -0,0 +1,83 @@ +{ + "custom_fields": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-08-02 02:37:29.931335", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Company", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "contact_name", + "fieldtype": "Data", + "hidden": 0, + "idx": 82, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "date_of_commencement", + "label": "Contact Name", + "modified": "2019-08-02 02:37:29.931335", + "modified_by": "Administrator", + "name": "Company-contact_name", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + } + ], + "custom_perms": [], + "doctype": "Company", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-08-02 02:37:29.854513", + "default_value": null, + "doc_type": "Company", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2019-08-02 02:37:29.854513", + "modified_by": "Administrator", + "name": "Company-read_only_onload", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "read_only_onload", + "property_type": "Check", + "value": null + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/custom/contract.json b/bloomstack_core/bloomstack_core/custom/contract.json new file mode 100644 index 000000000..bd66672dd --- /dev/null +++ b/bloomstack_core/bloomstack_core/custom/contract.json @@ -0,0 +1,440 @@ +{ + "custom_fields": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-23 08:42:57.553038", + "default": null, + "depends_on": "eval:doc.project", + "description": null, + "docstatus": 0, + "dt": "Contract", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "project", + "fieldtype": "Link", + "hidden": 0, + "idx": 14, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "end_date", + "label": "Project", + "modified": "2019-07-23 08:42:57.553038", + "modified_by": "Administrator", + "name": "Contract-project", + "no_copy": 0, + "options": "Project", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-23 07:34:08.410159", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Contract", + "fetch_from": "", + "fetch_if_empty": 0, + "fieldname": "payment_terms", + "fieldtype": "Table", + "hidden": 0, + "idx": 27, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "payment_terms_template", + "label": "Payment Terms", + "modified": "2019-07-23 07:34:08.410159", + "modified_by": "Administrator", + "name": "Contract-payment_terms", + "no_copy": 0, + "options": "Payment Terms Template Detail", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-23 07:33:29.739160", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Contract", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "payment_item", + "fieldtype": "Link", + "hidden": 0, + "idx": 25, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "sb_payment_details", + "label": "Payment Item", + "modified": "2019-07-23 07:33:29.739160", + "modified_by": "Administrator", + "name": "Contract-payment_item", + "no_copy": 0, + "options": "Item", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-23 07:21:53.260947", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Contract", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "payment_terms_template", + "fieldtype": "Link", + "hidden": 0, + "idx": 26, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "payment_item", + "label": "Payment Terms Template", + "modified": "2019-07-23 07:21:53.260947", + "modified_by": "Administrator", + "name": "Contract-payment_terms_template", + "no_copy": 0, + "options": "Payment Terms Template", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-23 07:21:53.047889", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Contract", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "sb_payment_details", + "fieldtype": "Section Break", + "hidden": 0, + "idx": 24, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "contract_terms", + "label": "Payment Terms", + "modified": "2019-07-23 07:21:53.047889", + "modified_by": "Administrator", + "name": "Contract-sb_payment_details", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-23 03:24:38.704056", + "default": null, + "depends_on": null, + "description": "Creates a new Project for the selected Party once the document is signed", + "docstatus": 0, + "dt": "Contract", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "project_template", + "fieldtype": "Link", + "hidden": 0, + "idx": 12, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "start_date", + "label": "Project Template", + "modified": "2019-07-23 03:24:38.704056", + "modified_by": "Administrator", + "name": "Contract-project_template", + "no_copy": 0, + "options": "Project Template", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-09 02:57:45.266126", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Contract", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "customer_signature", + "fieldtype": "Signature", + "hidden": 0, + "idx": 9, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "sb_signature", + "label": "Customer Signature", + "modified": "2019-07-09 02:57:45.266126", + "modified_by": "Administrator", + "name": "Contract-customer_signature", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 1, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-09 02:57:45.079868", + "default": null, + "depends_on": "eval:doc.customer_signature", + "description": null, + "docstatus": 0, + "dt": "Contract", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "sb_signature", + "fieldtype": "Section Break", + "hidden": 0, + "idx": 8, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "fulfilment_status", + "label": "Signature", + "modified": "2019-07-09 02:57:45.079868", + "modified_by": "Administrator", + "name": "Contract-sb_signature", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + } + ], + "custom_perms": [], + "doctype": "Contract", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-07-23 08:42:57.474224", + "default_value": null, + "doc_type": "Contract", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2019-07-23 08:42:57.474224", + "modified_by": "Administrator", + "name": "Contract-read_only_onload", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "read_only_onload", + "property_type": "Check", + "value": null + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/custom/delivery_note.json b/bloomstack_core/bloomstack_core/custom/delivery_note.json new file mode 100644 index 000000000..33c4ba8ab --- /dev/null +++ b/bloomstack_core/bloomstack_core/custom/delivery_note.json @@ -0,0 +1,359 @@ +{ + "custom_fields": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-03-01 02:17:20.998171", + "default": "Sales", + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Delivery Note", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "new_order_type", + "fieldtype": "Select", + "hidden": 0, + "idx": 7, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 1, + "insert_after": "customer_name", + "label": "Order Type", + "modified": "2019-03-01 02:17:20.998171", + "modified_by": "Administrator", + "name": "Delivery Note-new_order_type", + "no_copy": 0, + "options": "\nSales\nPromotional\nSample\nPAD\nWarranty\nConsignment\nReplenishment", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + } + ], + "custom_perms": [], + "doctype": "Delivery Note", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-03-01 02:17:28.793960", + "default_value": null, + "doc_type": "Delivery Note", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2019-03-01 02:17:28.793960", + "modified_by": "Administrator", + "name": "Delivery Note-read_only_onload", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "read_only_onload", + "property_type": "Check", + "value": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-11-23 00:29:16.981928", + "default_value": null, + "doc_type": "Delivery Note", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "lr_date", + "idx": 0, + "modified": "2018-11-23 00:29:16.981928", + "modified_by": "Administrator", + "name": "Delivery Note-lr_date-in_list_view", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "in_list_view", + "property_type": "Check", + "value": "1" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-10-11 02:28:47.401448", + "default_value": null, + "doc_type": "Delivery Note", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "per_installed", + "idx": 0, + "modified": "2018-10-11 02:28:47.401448", + "modified_by": "Administrator", + "name": "Delivery Note-per_installed-in_list_view", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "in_list_view", + "property_type": "Check", + "value": "0" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-08-29 01:29:41.962534", + "default_value": null, + "doc_type": "Delivery Note", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2018-08-29 01:29:41.962534", + "modified_by": "Administrator", + "name": "Delivery Note-default_print_format", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "default_print_format", + "property_type": "Data", + "value": "Shipping Manifest" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-05-29 00:42:12.334114", + "default_value": null, + "doc_type": "Delivery Note", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "naming_series", + "idx": 0, + "modified": "2018-05-29 00:42:12.334114", + "modified_by": "Administrator", + "name": "Delivery Note-naming_series-options", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "options", + "property_type": "Text", + "value": "DN-\nDN-RET-" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-05-03 14:12:24.245226", + "default_value": null, + "doc_type": "Delivery Note", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "tax_id", + "idx": 0, + "modified": "2018-05-03 14:12:24.245226", + "modified_by": "eric@digigrowit.com", + "name": "Delivery Note-tax_id-print_hide", + "owner": "eric@digigrowit.com", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "print_hide", + "property_type": "Check", + "value": "0" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-05-03 14:12:24.136125", + "default_value": null, + "doc_type": "Delivery Note", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "tax_id", + "idx": 0, + "modified": "2018-05-03 14:12:24.136125", + "modified_by": "eric@digigrowit.com", + "name": "Delivery Note-tax_id-hidden", + "owner": "eric@digigrowit.com", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "hidden", + "property_type": "Check", + "value": "0" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-05-03 14:12:10.885977", + "default_value": null, + "doc_type": "Delivery Note", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "in_words", + "idx": 0, + "modified": "2018-05-03 14:12:10.885977", + "modified_by": "eric@digigrowit.com", + "name": "Delivery Note-in_words-print_hide", + "owner": "eric@digigrowit.com", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "print_hide", + "property_type": "Check", + "value": "0" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-05-03 14:12:10.533978", + "default_value": null, + "doc_type": "Delivery Note", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "in_words", + "idx": 0, + "modified": "2018-05-03 14:12:10.533978", + "modified_by": "eric@digigrowit.com", + "name": "Delivery Note-in_words-hidden", + "owner": "eric@digigrowit.com", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "hidden", + "property_type": "Check", + "value": "0" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-05-03 14:12:08.951264", + "default_value": null, + "doc_type": "Delivery Note", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "rounded_total", + "idx": 0, + "modified": "2018-05-03 14:12:08.951264", + "modified_by": "eric@digigrowit.com", + "name": "Delivery Note-rounded_total-print_hide", + "owner": "eric@digigrowit.com", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "print_hide", + "property_type": "Check", + "value": "0" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-05-03 14:12:08.840749", + "default_value": null, + "doc_type": "Delivery Note", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "rounded_total", + "idx": 0, + "modified": "2018-05-03 14:12:08.840749", + "modified_by": "eric@digigrowit.com", + "name": "Delivery Note-rounded_total-hidden", + "owner": "eric@digigrowit.com", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "hidden", + "property_type": "Check", + "value": "0" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-05-03 14:12:08.726649", + "default_value": null, + "doc_type": "Delivery Note", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "base_rounded_total", + "idx": 0, + "modified": "2018-05-03 14:12:08.726649", + "modified_by": "eric@digigrowit.com", + "name": "Delivery Note-base_rounded_total-print_hide", + "owner": "eric@digigrowit.com", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "print_hide", + "property_type": "Check", + "value": "1" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-05-03 14:12:08.616538", + "default_value": null, + "doc_type": "Delivery Note", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "base_rounded_total", + "idx": 0, + "modified": "2018-05-03 14:12:08.616538", + "modified_by": "eric@digigrowit.com", + "name": "Delivery Note-base_rounded_total-hidden", + "owner": "eric@digigrowit.com", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "hidden", + "property_type": "Check", + "value": "0" + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/custom/delivery_settings.json b/bloomstack_core/bloomstack_core/custom/delivery_settings.json new file mode 100644 index 000000000..f2222892d --- /dev/null +++ b/bloomstack_core/bloomstack_core/custom/delivery_settings.json @@ -0,0 +1,134 @@ +{ + "custom_fields": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-16 11:47:50.288185", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Delivery Settings", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "packing_warehouse", + "fieldtype": "Link", + "hidden": 0, + "idx": 2, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "delivery_defaults", + "label": "Packing Warehouse", + "modified": "2019-07-16 11:47:50.288185", + "modified_by": "Administrator", + "name": "Delivery Settings-packing_warehouse", + "no_copy": 0, + "options": "Warehouse", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-16 11:47:50.187614", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Delivery Settings", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "delivery_defaults", + "fieldtype": "Section Break", + "hidden": 0, + "idx": 1, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": null, + "label": "Delivery Defaults", + "modified": "2019-07-16 11:47:50.187614", + "modified_by": "Administrator", + "name": "Delivery Settings-delivery_defaults", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + } + ], + "custom_perms": [], + "doctype": "Delivery Settings", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-07-16 11:49:58.069456", + "default_value": null, + "doc_type": "Delivery Settings", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2019-07-16 11:49:58.069456", + "modified_by": "Administrator", + "name": "Delivery Settings-read_only_onload", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "read_only_onload", + "property_type": "Check", + "value": null + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/custom/delivery_stop.json b/bloomstack_core/bloomstack_core/custom/delivery_stop.json new file mode 100644 index 000000000..ad1ddc812 --- /dev/null +++ b/bloomstack_core/bloomstack_core/custom/delivery_stop.json @@ -0,0 +1,185 @@ +{ + "custom_fields": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 1, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2018-11-06 01:17:14.903321", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Delivery Stop", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "paid_amount", + "fieldtype": "Currency", + "hidden": 0, + "idx": 12, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "grand_total", + "label": "Paid Amount", + "modified": "2018-11-06 01:17:14.903321", + "modified_by": "Administrator", + "name": "Delivery Stop-paid_amount", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 1, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2018-09-28 22:54:48.552714", + "default": null, + "depends_on": "eval:doc.sales_invoice && doc.docstatus==1 && !doc.visited", + "description": null, + "docstatus": 0, + "dt": "Delivery Stop", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "make_payment_entry", + "fieldtype": "Button", + "hidden": 0, + "idx": 13, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "paid_amount", + "label": "Make Payment Entry", + "modified": "2018-09-28 22:54:48.552714", + "modified_by": "Administrator", + "name": "Delivery Stop-make_payment_entry", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2018-09-28 07:00:48.235318", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Delivery Stop", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "sales_invoice", + "fieldtype": "Link", + "hidden": 0, + "idx": 9, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "delivery_note", + "label": "Sales Invoice", + "modified": "2018-09-28 07:00:48.235318", + "modified_by": "Administrator", + "name": "Delivery Stop-sales_invoice", + "no_copy": 0, + "options": "Sales Invoice", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + } + ], + "custom_perms": [], + "doctype": "Delivery Stop", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-11-06 01:17:29.901687", + "default_value": null, + "doc_type": "Delivery Stop", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2018-11-06 01:17:29.901687", + "modified_by": "Administrator", + "name": "Delivery Stop-read_only_onload", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "read_only_onload", + "property_type": "Check", + "value": null + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/custom/delivery_trip.json b/bloomstack_core/bloomstack_core/custom/delivery_trip.json new file mode 100644 index 000000000..6c5e8bc7e --- /dev/null +++ b/bloomstack_core/bloomstack_core/custom/delivery_trip.json @@ -0,0 +1,565 @@ +{ + "custom_fields": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 1, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-06-25 03:13:16.371830", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Delivery Trip", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "odometer_stop_time", + "fieldtype": "Datetime", + "hidden": 0, + "idx": 20, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "odometer_stop_value", + "label": "Odometer Stop Time", + "modified": "2019-06-25 03:13:16.371830", + "modified_by": "Administrator", + "name": "Delivery Trip-odometer_stop_time", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 1, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-06-25 03:13:15.798111", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Delivery Trip", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "odometer_stop_value", + "fieldtype": "Int", + "hidden": 0, + "idx": 19, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "column_break_17", + "label": "Odometer Stop Value", + "modified": "2019-06-25 03:13:15.798111", + "modified_by": "Administrator", + "name": "Delivery Trip-odometer_stop_value", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-06-25 03:13:15.536284", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Delivery Trip", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "column_break_17", + "fieldtype": "Column Break", + "hidden": 0, + "idx": 18, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "actual_distance_travelled", + "label": null, + "modified": "2019-06-25 03:13:15.536284", + "modified_by": "Administrator", + "name": "Delivery Trip-column_break_17", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 1, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-06-25 03:13:15.106705", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Delivery Trip", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "actual_distance_travelled", + "fieldtype": "Int", + "hidden": 0, + "idx": 17, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "odometer_start_time", + "label": "Actual Distance Travelled", + "modified": "2019-06-25 03:13:15.106705", + "modified_by": "Administrator", + "name": "Delivery Trip-actual_distance_travelled", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 1, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-06-25 03:13:14.786408", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Delivery Trip", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "odometer_start_time", + "fieldtype": "Datetime", + "hidden": 0, + "idx": 16, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "odometer_start_value", + "label": "Odometer Start Time", + "modified": "2019-06-25 03:13:14.786408", + "modified_by": "Administrator", + "name": "Delivery Trip-odometer_start_time", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 1, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-06-25 03:13:14.448372", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Delivery Trip", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "odometer_start_value", + "fieldtype": "Int", + "hidden": 0, + "idx": 15, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "odometer", + "label": "Odometer Start Value", + "modified": "2019-06-25 03:13:14.448372", + "modified_by": "Administrator", + "name": "Delivery Trip-odometer_start_value", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-06-25 03:13:14.150139", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Delivery Trip", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "odometer", + "fieldtype": "Section Break", + "hidden": 0, + "idx": 14, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "departure_time", + "label": "Odometer", + "modified": "2019-06-25 03:13:14.150139", + "modified_by": "Administrator", + "name": "Delivery Trip-odometer", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2018-09-07 02:42:46.433320", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Delivery Trip", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "map_embed", + "fieldtype": "Long Text", + "hidden": 1, + "idx": 27, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "map_html", + "label": "Map Embed", + "modified": "2018-09-07 02:42:46.433320", + "modified_by": "Administrator", + "name": "Delivery Trip-map_embed", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2018-09-07 02:42:04.358976", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Delivery Trip", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "map_html", + "fieldtype": "HTML", + "hidden": 0, + "idx": 26, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "sb_map", + "label": "Map", + "modified": "2018-09-07 02:42:04.358976", + "modified_by": "Administrator", + "name": "Delivery Trip-map_html", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2018-09-07 02:41:37.771282", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Delivery Trip", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "sb_map", + "fieldtype": "Section Break", + "hidden": 0, + "idx": 25, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "optimize_route", + "label": "Map", + "modified": "2018-09-07 02:41:37.771282", + "modified_by": "Administrator", + "name": "Delivery Trip-sb_map", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + } + ], + "custom_perms": [], + "doctype": "Delivery Trip", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-06-25 05:33:50.964282", + "default_value": null, + "doc_type": "Delivery Trip", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2019-06-25 05:33:50.964282", + "modified_by": "Administrator", + "name": "Delivery Trip-read_only_onload", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "read_only_onload", + "property_type": "Check", + "value": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-08-22 02:09:11.677024", + "default_value": null, + "doc_type": "Delivery Trip", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "naming_series", + "idx": 0, + "modified": "2018-09-06 03:22:24.860286", + "modified_by": "Administrator", + "name": "Delivery Trip-naming_series-options", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "options", + "property_type": "Text", + "value": "TOUR-.#####" + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/custom/driver.json b/bloomstack_core/bloomstack_core/custom/driver.json new file mode 100644 index 000000000..16233e531 --- /dev/null +++ b/bloomstack_core/bloomstack_core/custom/driver.json @@ -0,0 +1,54 @@ +{ + "custom_fields": [], + "custom_perms": [], + "doctype": "Driver", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-06-20 04:10:13.994226", + "default_value": null, + "doc_type": "Driver", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2019-06-20 04:10:13.994226", + "modified_by": "Administrator", + "name": "Driver-read_only_onload", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "read_only_onload", + "property_type": "Check", + "value": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-06-20 04:10:09.989446", + "default_value": null, + "doc_type": "Driver", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "employee", + "idx": 0, + "modified": "2019-06-20 04:10:09.989446", + "modified_by": "Administrator", + "name": "Driver-employee-reqd", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "reqd", + "property_type": "Check", + "value": "1" + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/custom/employee.json b/bloomstack_core/bloomstack_core/custom/employee.json new file mode 100644 index 000000000..44192f4f2 --- /dev/null +++ b/bloomstack_core/bloomstack_core/custom/employee.json @@ -0,0 +1,175 @@ +{ + "custom_fields": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-06-20 04:03:50.573192", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Employee", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "social_security_number", + "fieldtype": "Data", + "hidden": 0, + "idx": 69, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "place_of_issue", + "label": "Social Security Number", + "modified": "2019-06-20 04:03:50.573192", + "modified_by": "Administrator", + "name": "Employee-social_security_number", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + } + ], + "custom_perms": [], + "doctype": "Employee", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-06-20 04:03:50.511664", + "default_value": null, + "doc_type": "Employee", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2019-06-20 04:03:50.511664", + "modified_by": "Administrator", + "name": "Employee-read_only_onload", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "read_only_onload", + "property_type": "Check", + "value": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-04-09 05:39:16.764433", + "default_value": null, + "doc_type": "Employee", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "erpnext_user", + "idx": 0, + "modified": "2019-04-09 05:39:16.764433", + "modified_by": "Administrator", + "name": "Employee-erpnext_user-label", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "label", + "property_type": "Data", + "value": "Bloomstack User" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-08-07 05:58:01.116699", + "default_value": null, + "doc_type": "Employee", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "employee_number", + "idx": 0, + "modified": "2018-08-07 05:58:01.116699", + "modified_by": "Administrator", + "name": "Employee-employee_number-hidden", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "hidden", + "property_type": "Check", + "value": "1" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-08-07 05:58:00.867693", + "default_value": null, + "doc_type": "Employee", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "naming_series", + "idx": 0, + "modified": "2018-08-07 05:58:00.867693", + "modified_by": "Administrator", + "name": "Employee-naming_series-reqd", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "reqd", + "property_type": "Check", + "value": "1" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-08-07 05:58:00.766127", + "default_value": null, + "doc_type": "Employee", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "naming_series", + "idx": 0, + "modified": "2018-08-07 05:58:00.766127", + "modified_by": "Administrator", + "name": "Employee-naming_series-hidden", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "hidden", + "property_type": "Check", + "value": "0" + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/custom/packing_slip.json b/bloomstack_core/bloomstack_core/custom/packing_slip.json new file mode 100644 index 000000000..a887e0f77 --- /dev/null +++ b/bloomstack_core/bloomstack_core/custom/packing_slip.json @@ -0,0 +1,287 @@ +{ + "custom_fields": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-17 02:28:18.992261", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Packing Slip", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "company", + "fieldtype": "Data", + "hidden": 0, + "idx": 12, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "source_warehouse", + "label": "Company", + "modified": "2019-07-17 02:28:18.992261", + "modified_by": "Administrator", + "name": "Packing Slip-company", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 1, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-16 23:41:20.339385", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Packing Slip", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "target_warehouse", + "fieldtype": "Link", + "hidden": 0, + "idx": 15, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "column_break_12", + "label": "Target Warehouse", + "modified": "2019-07-16 23:41:20.339385", + "modified_by": "Administrator", + "name": "Packing Slip-target_warehouse", + "no_copy": 0, + "options": "Warehouse", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-16 23:41:19.900540", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Packing Slip", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "column_break_12", + "fieldtype": "Column Break", + "hidden": 0, + "idx": 13, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "company", + "label": null, + "modified": "2019-07-16 23:41:19.900540", + "modified_by": "Administrator", + "name": "Packing Slip-column_break_12", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-16 23:41:19.464196", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Packing Slip", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "source_warehouse", + "fieldtype": "Link", + "hidden": 0, + "idx": 12, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "section_break_10", + "label": "Source Warehouse", + "modified": "2019-07-16 23:41:19.464196", + "modified_by": "Administrator", + "name": "Packing Slip-source_warehouse", + "no_copy": 0, + "options": "Warehouse", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-16 23:38:56.134270", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Packing Slip", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "section_break_10", + "fieldtype": "Section Break", + "hidden": 0, + "idx": 11, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "to_case_no", + "label": null, + "modified": "2019-07-16 23:38:56.134270", + "modified_by": "Administrator", + "name": "Packing Slip-section_break_10", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + } + ], + "custom_perms": [], + "doctype": "Packing Slip", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-07-17 02:28:18.844066", + "default_value": null, + "doc_type": "Packing Slip", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2019-07-17 02:28:18.844066", + "modified_by": "Administrator", + "name": "Packing Slip-read_only_onload", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "read_only_onload", + "property_type": "Check", + "value": null + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/custom/packing_slip_item.json b/bloomstack_core/bloomstack_core/custom/packing_slip_item.json new file mode 100644 index 000000000..3715a6c0f --- /dev/null +++ b/bloomstack_core/bloomstack_core/custom/packing_slip_item.json @@ -0,0 +1,236 @@ +{ + "custom_fields": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-17 00:00:41.762787", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Packing Slip Item", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "target_warehouse", + "fieldtype": "Link", + "hidden": 0, + "idx": 9, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "column_break_8", + "label": "Target Warehouse", + "modified": "2019-07-17 00:00:41.762787", + "modified_by": "Administrator", + "name": "Packing Slip Item-target_warehouse", + "no_copy": 0, + "options": "Warehouse", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-17 00:00:41.458190", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Packing Slip Item", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "column_break_8", + "fieldtype": "Column Break", + "hidden": 0, + "idx": 8, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "source_warehouse", + "label": null, + "modified": "2019-07-17 00:00:41.458190", + "modified_by": "Administrator", + "name": "Packing Slip Item-column_break_8", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-17 00:00:41.113467", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Packing Slip Item", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "source_warehouse", + "fieldtype": "Link", + "hidden": 0, + "idx": 7, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "warehouse_details", + "label": "Source Warehouse", + "modified": "2019-07-17 00:00:41.113467", + "modified_by": "Administrator", + "name": "Packing Slip Item-source_warehouse", + "no_copy": 0, + "options": "Warehouse", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-07-17 00:00:40.784708", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Packing Slip Item", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "warehouse_details", + "fieldtype": "Section Break", + "hidden": 0, + "idx": 6, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "description", + "label": "Warehouse Details", + "modified": "2019-07-17 00:00:40.784708", + "modified_by": "Administrator", + "name": "Packing Slip Item-warehouse_details", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + } + ], + "custom_perms": [], + "doctype": "Packing Slip Item", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-07-17 00:00:40.748848", + "default_value": null, + "doc_type": "Packing Slip Item", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2019-07-17 00:00:40.748848", + "modified_by": "Administrator", + "name": "Packing Slip Item-read_only_onload", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "read_only_onload", + "property_type": "Check", + "value": null + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/custom/payment_schedule.json b/bloomstack_core/bloomstack_core/custom/payment_schedule.json new file mode 100644 index 000000000..8c5603d9c --- /dev/null +++ b/bloomstack_core/bloomstack_core/custom/payment_schedule.json @@ -0,0 +1,54 @@ +{ + "custom_fields": [], + "custom_perms": [], + "doctype": "Payment Schedule", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-04-29 23:11:40.519502", + "default_value": null, + "doc_type": "Payment Schedule", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "due_date", + "idx": 0, + "modified": "2019-04-29 23:11:40.519502", + "modified_by": "Administrator", + "name": "Payment Schedule-due_date-allow_on_submit", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "allow_on_submit", + "property_type": "Check", + "value": "1" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-04-29 23:11:40.483830", + "default_value": null, + "doc_type": "Payment Schedule", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2019-04-29 23:11:40.483830", + "modified_by": "Administrator", + "name": "Payment Schedule-read_only_onload", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "read_only_onload", + "property_type": "Check", + "value": null + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/custom/quotation.json b/bloomstack_core/bloomstack_core/custom/quotation.json new file mode 100644 index 000000000..86b2009e6 --- /dev/null +++ b/bloomstack_core/bloomstack_core/custom/quotation.json @@ -0,0 +1,282 @@ +{ + "custom_fields": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-03-07 01:16:30.488991", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Quotation", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "no_charge_order", + "fieldtype": "Check", + "hidden": 0, + "idx": 7, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "customer_name", + "label": "No Charge", + "modified": "2019-03-07 01:16:30.488991", + "modified_by": "Administrator", + "name": "Quotation-no_charge_order", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-02-21 04:09:11.252597", + "default": "Sales", + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Quotation", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "new_order_type", + "fieldtype": "Select", + "hidden": 0, + "idx": 14, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 1, + "insert_after": "order_type", + "label": "Order Type", + "modified": "2019-02-21 04:09:11.252597", + "modified_by": "Administrator", + "name": "Quotation-new_order_type", + "no_copy": 0, + "options": "\nSales\nPromotional\nSample\nPAD\nWarranty\nConsignment\nReplenishment", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 1, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-02-12 02:35:04.934641", + "default": null, + "depends_on": "eval:doc.customer_signature", + "description": null, + "docstatus": 0, + "dt": "Quotation", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "signature", + "fieldtype": "Section Break", + "hidden": 0, + "idx": 15, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "new_order_type", + "label": "Signature", + "modified": "2019-02-12 02:35:04.934641", + "modified_by": "Administrator", + "name": "Quotation-signature", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-02-12 02:28:18.711846", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Quotation", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "customer_signature", + "fieldtype": "Signature", + "hidden": 0, + "idx": 16, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "signature", + "label": "Customer Signature", + "modified": "2019-02-12 02:28:18.711846", + "modified_by": "Administrator", + "name": "Quotation-customer_signature", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + } + ], + "custom_perms": [], + "doctype": "Quotation", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-07-09 03:37:52.421975", + "default_value": null, + "doc_type": "Quotation", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2019-07-09 03:37:52.421975", + "modified_by": "Administrator", + "name": "Quotation-read_only_onload", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "read_only_onload", + "property_type": "Check", + "value": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-02-21 04:09:11.188707", + "default_value": null, + "doc_type": "Quotation", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "order_type", + "idx": 0, + "modified": "2019-02-21 04:09:11.188707", + "modified_by": "Administrator", + "name": "Quotation-order_type-hidden", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "hidden", + "property_type": "Check", + "value": "1" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-01-14 23:33:24.748564", + "default_value": null, + "doc_type": "Quotation", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "naming_series", + "idx": 0, + "modified": "2019-01-14 23:33:24.748564", + "modified_by": "Administrator", + "name": "Quotation-naming_series-options", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "options", + "property_type": "Text", + "value": "SAL-QTN-.YYYY.-" + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/custom/sales_invoice.json b/bloomstack_core/bloomstack_core/custom/sales_invoice.json new file mode 100644 index 000000000..c22571d1e --- /dev/null +++ b/bloomstack_core/bloomstack_core/custom/sales_invoice.json @@ -0,0 +1,267 @@ +{ + "custom_fields": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-02-21 04:10:56.481354", + "default": "Sales", + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Sales Invoice", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "new_order_type", + "fieldtype": "Select", + "hidden": 0, + "idx": 6, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "customer_name", + "label": "Order Type", + "modified": "2019-02-21 04:10:56.481354", + "modified_by": "Administrator", + "name": "Sales Invoice-new_order_type", + "no_copy": 0, + "options": "\nSales\nPromotional\nSample\nPAD\nWarranty\nConsignment\nReplenishment", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + } + ], + "custom_perms": [], + "doctype": "Sales Invoice", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-07-17 23:58:11.836385", + "default_value": null, + "doc_type": "Sales Invoice", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2019-07-17 23:58:11.836385", + "modified_by": "Administrator", + "name": "Sales Invoice-read_only_onload", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "read_only_onload", + "property_type": "Check", + "value": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-07-17 23:51:51.933198", + "default_value": null, + "doc_type": "Sales Invoice", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "scan_barcode", + "idx": 0, + "modified": "2019-07-17 23:51:51.933198", + "modified_by": "Administrator", + "name": "Sales Invoice-scan_barcode-hidden", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "hidden", + "property_type": "Check", + "value": "0" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-02-18 23:51:34.298918", + "default_value": null, + "doc_type": "Sales Invoice", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "status", + "idx": 0, + "modified": "2019-02-18 23:51:34.298918", + "modified_by": "Administrator", + "name": "Sales Invoice-status-allow_on_submit", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "allow_on_submit", + "property_type": "Check", + "value": "1" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-01-28 04:26:12.900822", + "default_value": null, + "doc_type": "Sales Invoice", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "due_date", + "idx": 0, + "modified": "2019-01-28 04:26:12.900822", + "modified_by": "Administrator", + "name": "Sales Invoice-due_date-allow_on_submit", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "allow_on_submit", + "property_type": "Check", + "value": "1" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-12-04 05:35:32.896878", + "default_value": null, + "doc_type": "Sales Invoice", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "tax_id", + "idx": 0, + "modified": "2018-12-04 05:35:32.896878", + "modified_by": "Administrator", + "name": "Sales Invoice-tax_id-print_hide", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "print_hide", + "property_type": "Check", + "value": "0" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-12-04 05:35:32.887097", + "default_value": null, + "doc_type": "Sales Invoice", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "tax_id", + "idx": 0, + "modified": "2018-12-04 05:35:32.887097", + "modified_by": "Administrator", + "name": "Sales Invoice-tax_id-hidden", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "hidden", + "property_type": "Check", + "value": "0" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-11-28 05:10:48.191961", + "default_value": null, + "doc_type": "Sales Invoice", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "naming_series", + "idx": 0, + "modified": "2018-11-28 05:10:48.191961", + "modified_by": "Administrator", + "name": "Sales Invoice-naming_series-options", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "options", + "property_type": "Text", + "value": "ACC-SINV-.YYYY.-" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-08-07 20:14:56.664866", + "default_value": null, + "doc_type": "Sales Invoice", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "payment_schedule", + "idx": 0, + "modified": "2018-08-07 20:14:56.664866", + "modified_by": "Administrator", + "name": "Sales Invoice-payment_schedule-print_hide", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "print_hide", + "property_type": "Check", + "value": "1" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-08-07 20:14:56.513216", + "default_value": null, + "doc_type": "Sales Invoice", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "due_date", + "idx": 0, + "modified": "2018-08-07 20:14:56.513216", + "modified_by": "Administrator", + "name": "Sales Invoice-due_date-print_hide", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "print_hide", + "property_type": "Check", + "value": "0" + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/custom/sales_order.json b/bloomstack_core/bloomstack_core/custom/sales_order.json new file mode 100644 index 000000000..0a382db5b --- /dev/null +++ b/bloomstack_core/bloomstack_core/custom/sales_order.json @@ -0,0 +1,318 @@ +{ + "custom_fields": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-03-07 01:17:41.814554", + "default": null, + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Sales Order", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "no_charge_order", + "fieldtype": "Check", + "hidden": 0, + "idx": 9, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "new_order_type", + "label": "No Charge", + "modified": "2019-03-07 01:17:41.814554", + "modified_by": "Administrator", + "name": "Sales Order-no_charge_order", + "no_copy": 0, + "options": null, + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": null, + "columns": 0, + "creation": "2019-02-21 04:06:32.923581", + "default": "Sales", + "depends_on": null, + "description": null, + "docstatus": 0, + "dt": "Sales Order", + "fetch_from": null, + "fetch_if_empty": 0, + "fieldname": "new_order_type", + "fieldtype": "Select", + "hidden": 0, + "idx": 8, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "insert_after": "order_type", + "label": "Order Type", + "modified": "2019-02-21 04:06:32.923581", + "modified_by": "Administrator", + "name": "Sales Order-new_order_type", + "no_copy": 0, + "options": "\nSales\nPromotional\nSample\nPAD\nWarranty\nConsignment\nReplenishment", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "permlevel": 0, + "precision": "", + "print_hide": 1, + "print_hide_if_no_value": 0, + "print_width": null, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "translatable": 0, + "unique": 0, + "width": null + } + ], + "custom_perms": [], + "doctype": "Sales Order", + "property_setters": [ + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-07-17 23:57:50.563097", + "default_value": null, + "doc_type": "Sales Order", + "docstatus": 0, + "doctype_or_field": "DocType", + "field_name": null, + "idx": 0, + "modified": "2019-07-17 23:57:50.563097", + "modified_by": "Administrator", + "name": "Sales Order-read_only_onload", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "read_only_onload", + "property_type": "Check", + "value": null + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-07-17 23:51:51.766814", + "default_value": null, + "doc_type": "Sales Order", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "scan_barcode", + "idx": 0, + "modified": "2019-07-17 23:51:51.766814", + "modified_by": "Administrator", + "name": "Sales Order-scan_barcode-hidden", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "hidden", + "property_type": "Check", + "value": "0" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-07-09 03:39:19.105714", + "default_value": null, + "doc_type": "Sales Order", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "delivery_date", + "idx": 0, + "modified": "2019-07-09 03:39:19.105714", + "modified_by": "Administrator", + "name": "Sales Order-delivery_date-label", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "label", + "property_type": "Data", + "value": "Expected Delivery Date" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-02-21 03:58:58.055003", + "default_value": null, + "doc_type": "Sales Order", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "order_type", + "idx": 0, + "modified": "2019-02-21 03:58:58.055003", + "modified_by": "Administrator", + "name": "Sales Order-order_type-hidden", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "hidden", + "property_type": "Check", + "value": "1" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-01-29 02:59:27.455625", + "default_value": null, + "doc_type": "Sales Order", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "payment_schedule", + "idx": 0, + "modified": "2019-01-29 02:59:27.455625", + "modified_by": "Administrator", + "name": "Sales Order-payment_schedule-print_hide", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "print_hide", + "property_type": "Check", + "value": "1" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2019-01-29 02:59:27.261534", + "default_value": null, + "doc_type": "Sales Order", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "due_date", + "idx": 0, + "modified": "2019-01-29 02:59:27.261534", + "modified_by": "Administrator", + "name": "Sales Order-due_date-print_hide", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "print_hide", + "property_type": "Check", + "value": "0" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-12-04 05:35:32.878619", + "default_value": null, + "doc_type": "Sales Order", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "tax_id", + "idx": 0, + "modified": "2018-12-04 05:35:32.878619", + "modified_by": "Administrator", + "name": "Sales Order-tax_id-print_hide", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "print_hide", + "property_type": "Check", + "value": "0" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-12-04 05:35:32.868323", + "default_value": null, + "doc_type": "Sales Order", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "tax_id", + "idx": 0, + "modified": "2018-12-04 05:35:32.868323", + "modified_by": "Administrator", + "name": "Sales Order-tax_id-hidden", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "hidden", + "property_type": "Check", + "value": "0" + }, + { + "_assign": null, + "_comments": null, + "_liked_by": null, + "_user_tags": null, + "creation": "2018-11-28 05:10:51.169484", + "default_value": null, + "doc_type": "Sales Order", + "docstatus": 0, + "doctype_or_field": "DocField", + "field_name": "naming_series", + "idx": 0, + "modified": "2018-11-28 05:10:51.169484", + "modified_by": "Administrator", + "name": "Sales Order-naming_series-options", + "owner": "Administrator", + "parent": null, + "parentfield": null, + "parenttype": null, + "property": "options", + "property_type": "Text", + "value": "SAL-ORD-.YYYY.-" + } + ], + "sync_on_migrate": 1 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/doctype/authorization_request/__init__.py b/bloomstack_core/bloomstack_core/doctype/authorization_request/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/bloomstack_core/doctype/authorization_request/authorization_request.js b/bloomstack_core/bloomstack_core/doctype/authorization_request/authorization_request.js new file mode 100644 index 000000000..657146f2b --- /dev/null +++ b/bloomstack_core/bloomstack_core/doctype/authorization_request/authorization_request.js @@ -0,0 +1,6 @@ +// Copyright (c) 2019, Bloom Stack, Inc and contributors +// For license information, please see license.txt + +frappe.ui.form.on("Authorization Request", { + +}); diff --git a/bloomstack_core/bloomstack_core/doctype/authorization_request/authorization_request.json b/bloomstack_core/bloomstack_core/doctype/authorization_request/authorization_request.json new file mode 100644 index 000000000..c1df7f9b7 --- /dev/null +++ b/bloomstack_core/bloomstack_core/doctype/authorization_request/authorization_request.json @@ -0,0 +1,495 @@ +{ + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "autoname": "AR.######", + "beta": 0, + "creation": "2019-05-10 04:18:42.975410", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 0, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "linked_doctype", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Linked DocType", + "length": 0, + "no_copy": 0, + "options": "DocType", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "linked_docname", + "fieldtype": "Dynamic Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Linked DocName", + "length": 0, + "no_copy": 0, + "options": "linked_doctype", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "", + "fetch_if_empty": 0, + "fieldname": "authorizer_email", + "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": "Authorizer Email", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "cb", + "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": 1, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "signature", + "fieldtype": "Signature", + "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": "Signature", + "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": 1, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "signee_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": "Signee Name", + "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, + "fetch_if_empty": 0, + "fieldname": "section_break_4", + "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": "", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "token", + "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": "Token", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "token_generated_on", + "fieldtype": "Datetime", + "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": "Token Generated On", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "request_link", + "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": "Request Link", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "section_break_13", + "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": 1, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "status", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Status", + "length": 0, + "no_copy": 0, + "options": "Request Sent\nApproved\nRejected", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "amended_from", + "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": "Amended From", + "length": 0, + "no_copy": 1, + "options": "Authorization Request", + "permlevel": 0, + "print_hide": 1, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 1, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2019-06-06 03:26:19.653725", + "modified_by": "Administrator", + "module": "Bloomstack Core", + "name": "Authorization Request", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "modified", + "sort_order": "ASC", + "track_changes": 1, + "track_seen": 0, + "track_views": 0 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/doctype/authorization_request/authorization_request.py b/bloomstack_core/bloomstack_core/doctype/authorization_request/authorization_request.py new file mode 100644 index 000000000..eef97cb8d --- /dev/null +++ b/bloomstack_core/bloomstack_core/doctype/authorization_request/authorization_request.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2019, Bloom Stack, Inc and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document +from frappe.utils import now_datetime +from frappe.utils.data import get_url +from erpnext import get_default_company + +class AuthorizationRequest(Document): + def after_insert(self): + self.generate_token() + self.send_authorization_request() + self.status = "Request Sent" + + def generate_token(self): + self.token = frappe.generate_hash(self.name, 32) + self.token_generated_on = now_datetime() + self.request_link = "{0}/authorize_document?token={1}&name={2}".format(get_url(), self.token, self.name) + self.save() + + def send_authorization_request(self): + """ + Email the link to user for them to authorize the document + """ + + doc = frappe.get_doc(self.linked_doctype, self.linked_docname) + company = doc.company if hasattr(doc, 'company') else get_default_company() + + subject = "{0} requests your authorization on {1}".format(company, self.linked_doctype) + message = frappe.render_template("templates/emails/authorization_request.html", { + "authorization_request": self, + }) + + frappe.sendmail(recipients=[self.authorizer_email], subject=subject, message=message) \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/doctype/authorization_request/test_authorization_request.js b/bloomstack_core/bloomstack_core/doctype/authorization_request/test_authorization_request.js new file mode 100644 index 000000000..ec8cade49 --- /dev/null +++ b/bloomstack_core/bloomstack_core/doctype/authorization_request/test_authorization_request.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Authorization Request", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Authorization Request + () => frappe.tests.make('Authorization Request', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/bloomstack_core/bloomstack_core/doctype/authorization_request/test_authorization_request.py b/bloomstack_core/bloomstack_core/doctype/authorization_request/test_authorization_request.py new file mode 100644 index 000000000..04f34047c --- /dev/null +++ b/bloomstack_core/bloomstack_core/doctype/authorization_request/test_authorization_request.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2019, Bloom Stack, Inc and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestAuthorizationRequest(unittest.TestCase): + pass diff --git a/bloomstack_core/bloomstack_core/doctype/compliance_info/compliance_info.json b/bloomstack_core/bloomstack_core/doctype/compliance_info/compliance_info.json index 7e9bd638d..9e2b8c57d 100644 --- a/bloomstack_core/bloomstack_core/doctype/compliance_info/compliance_info.json +++ b/bloomstack_core/bloomstack_core/doctype/compliance_info/compliance_info.json @@ -214,6 +214,39 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "use_type", + "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": "Use 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, @@ -323,7 +356,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2019-05-31 00:33:10.835703", + "modified": "2019-07-24 00:11:17.404754", "modified_by": "Administrator", "module": "Bloomstack Core", "name": "Compliance Info", diff --git a/bloomstack_core/bloomstack_core/doctype/project_template/__init__.py b/bloomstack_core/bloomstack_core/doctype/project_template/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/bloomstack_core/doctype/project_template/project_template.js b/bloomstack_core/bloomstack_core/doctype/project_template/project_template.js new file mode 100644 index 000000000..205ddfbe2 --- /dev/null +++ b/bloomstack_core/bloomstack_core/doctype/project_template/project_template.js @@ -0,0 +1,8 @@ +// Copyright (c) 2019, Bloom Stack, Inc and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Project Template', { + refresh: function(frm) { + + } +}); diff --git a/bloomstack_core/bloomstack_core/doctype/project_template/project_template.json b/bloomstack_core/bloomstack_core/doctype/project_template/project_template.json new file mode 100644 index 000000000..af0ac4a55 --- /dev/null +++ b/bloomstack_core/bloomstack_core/doctype/project_template/project_template.json @@ -0,0 +1,165 @@ +{ + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 1, + "allow_rename": 1, + "autoname": "field:template_name", + "beta": 0, + "creation": "2019-07-23 03:10:59.196756", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "template_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Template Name", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 1 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "sb_tasks", + "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": "Tasks", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "tasks", + "fieldtype": "Table", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Tasks", + "length": 0, + "no_copy": 0, + "options": "Project Template Task", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2019-07-23 03:10:59.196756", + "modified_by": "Administrator", + "module": "Bloomstack Core", + "name": "Project Template", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "quick_entry": 0, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "modified", + "sort_order": "DESC", + "title_field": "template_name", + "track_changes": 1, + "track_seen": 0, + "track_views": 0 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/doctype/project_template/project_template.py b/bloomstack_core/bloomstack_core/doctype/project_template/project_template.py new file mode 100644 index 000000000..ec74b3eff --- /dev/null +++ b/bloomstack_core/bloomstack_core/doctype/project_template/project_template.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2019, Bloom Stack, Inc and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals + +import frappe +from frappe import _ +from frappe.model.document import Document + + +class ProjectTemplate(Document): + def validate(self): + self.validate_task_days() + + def validate_task_days(self): + for task in self.tasks: + if task.days_to_task_start and task.days_to_task_start < 0: + frappe.throw(_("Days to task start must be positive")) + + if task.days_to_task_end and task.days_to_task_end < 0: + frappe.throw(_("Days to task end must be positive")) + + if task.days_to_task_start and task.days_to_task_end and task.days_to_task_start > task.days_to_task_end: + frappe.throw(_("Days to task start cannot be after days to task end")) diff --git a/bloomstack_core/bloomstack_core/doctype/project_template/test_project_template.js b/bloomstack_core/bloomstack_core/doctype/project_template/test_project_template.js new file mode 100644 index 000000000..df8296e60 --- /dev/null +++ b/bloomstack_core/bloomstack_core/doctype/project_template/test_project_template.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Project Template", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Project Template + () => frappe.tests.make('Project Template', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/bloomstack_core/bloomstack_core/doctype/project_template/test_project_template.py b/bloomstack_core/bloomstack_core/doctype/project_template/test_project_template.py new file mode 100644 index 000000000..d4c3223fa --- /dev/null +++ b/bloomstack_core/bloomstack_core/doctype/project_template/test_project_template.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2019, Bloom Stack, Inc and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestProjectTemplate(unittest.TestCase): + pass diff --git a/bloomstack_core/bloomstack_core/doctype/project_template_task/__init__.py b/bloomstack_core/bloomstack_core/doctype/project_template_task/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/bloomstack_core/doctype/project_template_task/project_template_task.json b/bloomstack_core/bloomstack_core/doctype/project_template_task/project_template_task.json new file mode 100644 index 000000000..e406d7d74 --- /dev/null +++ b/bloomstack_core/bloomstack_core/doctype/project_template_task/project_template_task.json @@ -0,0 +1,208 @@ +{ + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2019-07-23 02:55:43.458950", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "task_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Task Name", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "description", + "fieldtype": "Small Text", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Description", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "days_to_task_start", + "fieldtype": "Int", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Days to Task Start", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "days_to_task_end", + "fieldtype": "Int", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Days to Task End", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_if_empty": 0, + "fieldname": "weight", + "fieldtype": "Int", + "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": "Weight", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 1, + "max_attachments": 0, + "modified": "2019-07-23 03:13:40.519196", + "modified_by": "Administrator", + "module": "Bloomstack Core", + "name": "Project Template Task", + "name_case": "", + "owner": "Administrator", + "permissions": [], + "quick_entry": 0, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1, + "track_seen": 0, + "track_views": 0 +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/doctype/project_template_task/project_template_task.py b/bloomstack_core/bloomstack_core/doctype/project_template_task/project_template_task.py new file mode 100644 index 000000000..0e74d3beb --- /dev/null +++ b/bloomstack_core/bloomstack_core/doctype/project_template_task/project_template_task.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2019, Bloom Stack, Inc and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class ProjectTemplateTask(Document): + pass diff --git a/bloomstack_core/bloomstack_core/page/__init__.py b/bloomstack_core/bloomstack_core/page/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/bloomstack_core/page/insight_engine/__init__.py b/bloomstack_core/bloomstack_core/page/insight_engine/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/bloomstack_core/page/insight_engine/insight_engine.html b/bloomstack_core/bloomstack_core/page/insight_engine/insight_engine.html new file mode 100644 index 000000000..3b322b6cb --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/insight_engine/insight_engine.html @@ -0,0 +1,146 @@ +
+
+
+
+
+ {{ format_currency(total_monthly_revenue) }} + MONTHLY REVENUE + Payments received in the last 30 days +
+
+
+
+ {{ format_currency(total_weekly_revenue) }} + WEEKLY REVENUE + Payments received in the last 7 days +
+
+
+
+ {{ format_currency(yesterday_revenue) }} + YESTERDAY\'S REVENUE + Payments received on {{ moment().subtract(1, "d").format("MMM D") }} +
+
+
+
+
+
+ {{ format_currency(average_monthly_revenue) }} + AVERAGE MONTHLY REVENUE + Average of payments received in the last 30 days +
+
+
+
+ {{ format_currency(average_weekly_revenue) }} + AVERAGE WEEKLY REVENUE + Average of payments received in the last 7 days +
+
+
+
+ {{ format_currency(cash_on_hand) }} + CASH ON HAND + As on {{ moment().format("MMM D") }} +
+
+
+
+
+
+
+

+ TOP 5 PRODUCTS + + by Revenue + +

+

{{ moment().subtract(7, "d").format("MMM D") }} - {{ moment().subtract(1, "d").format("MMM D") }}

+
+ +
+
+
+
+
+
+

+ TOP TERRITORY + + by Revenue + +

+

{{ moment().subtract(7, "d").format("MMM D") }} - {{ moment().subtract(1, "d").format("MMM D") }}

+
+ +
+
+
+

+ TOP PRODUCTS + + by Revenue + +

+

{{ moment().subtract(7, "d").format("MMM D") }} - {{ moment().subtract(1, "d").format("MMM D") }}

+
+
+ + + + + + + + + + +
RankProductsRevenueUnits
+
+
+
+
+
+
+
+
+

+ TOP SALES PARTNER + + by Revenue + +

+

{{ moment().subtract(7, "d").format("MMM D") }} - {{ moment().subtract(1, "d").format("MMM D") }}

+
+ +
+
+
+

+ INVOICES + + by Status + +

+

{{ moment().subtract(7, "d").format("MMM D") }} - {{ moment().subtract(1, "d").format("MMM D") }}

+
+ +
+
+
+
+
+
+

+ TOP 10 CUSTOMERS + + by Revenue + +

+

{{ moment().subtract(7, "d").format("MMM D") }} - {{ moment().subtract(1, "d").format("MMM D") }}

+
+ +
+
+
\ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/page/insight_engine/insight_engine.js b/bloomstack_core/bloomstack_core/page/insight_engine/insight_engine.js new file mode 100644 index 000000000..63a13b641 --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/insight_engine/insight_engine.js @@ -0,0 +1,312 @@ +{% include "bloomstack_core/bloomstack_core/page/insight_engine/insight_engine.html" %} + +frappe.pages['insight-engine'].on_page_load = function(wrapper) { + var page = frappe.ui.make_app_page({ + parent: wrapper, + title: 'Dashboard', + single_column: true + }); + + wrapper.insight_engine = new InsightEngine(wrapper); +} + + +InsightEngine = class InsightEngine { + constructor(wrapper) { + this.setup(wrapper); + const assets = [ + 'assets/js/chart.js', + 'assets/bloomstack_core/css/insight_engine.css' + ]; + + frappe.require(assets, () => { + this.make(); + }); + } + + setup(wrapper) { + let me = this; + this.elements = { + parent: $(wrapper).find(".layout-main"), + refresh_btn: wrapper.page.set_primary_action(__("Refresh All"), () => { me.make() }, "fa fa-refresh"), + }; + + this.elements.no_data = $('
' + __("No Data") + '
') + .toggle(false) + .appendTo(this.elements.parent); + } + + async make() { + await this.getData(); + this.renderPage(); + this.renderCharts(); + } + + async getData() { + let me = this; + await frappe.call({ + method: "bloomstack_core.bloomstack_core.page.insight_engine.insight_engine.get_insight_engine_dashboards", + callback: (r) => { + if (!r.exc && r.message) { + me.dashboard_data = r.message; + } else { + me.elements.no_data.toggle(true); + } + } + }); + } + + getDateRangeAsArray(startDate, stopDate) { + let dateArray = []; + + // Default the dashboard input dates to a week + startDate = moment(startDate || moment().subtract(7, 'days')); + stopDate = moment(stopDate || moment().subtract(1, 'day')); + + while (startDate <= stopDate) { + dateArray.push(moment(startDate).format('MMM D')) + startDate = moment(startDate).add(1, 'day'); + } + + return dateArray; + } + + renderPage() { + let html = frappe.render_template("insight_engine", this.dashboard_data) + this.elements.parent.html(html); + } + + renderCharts() { + const opacity = 0.6; + const colors = { + hex: [ + // no opacity + '#F58767', + '#505362', + '#69829E', + '#80BD9E', + '#ADBD38', + '#598233', + // hack to repeat colors + '#F58767', + '#505362', + '#69829E', + '#80BD9E', + '#ADBD38', + '#598233' + ], + rgba: [ + // applied opacity + `rgba(245, 135, 103, ${opacity})`, + `rgba(80, 83, 98, ${opacity})`, + `rgba(105, 130, 158, ${opacity})`, + `rgba(128, 189, 158, ${opacity})`, + `rgba(173, 189, 56, ${opacity})`, + `rgba(89, 130, 5, ${opacity})`, + // hack to repeat colors + `rgba(245, 135, 103, ${opacity})`, + `rgba(80, 83, 98, ${opacity})`, + `rgba(105, 130, 158, ${opacity})`, + `rgba(128, 189, 158, ${opacity})`, + `rgba(173, 189, 56, ${opacity})`, + `rgba(89, 130, 5, ${opacity})` + ] + } + + // Top product trends in the last week + let datasets = []; + Object.keys(this.dashboard_data.top_products_by_time).forEach((item, i) => { + if(i < 5) { + datasets.push({ + label: item, + backgroundColor: colors.rgba[i], + borderColor: colors.hex[i], + borderWidth: 1.5, + fill: false, + data: this.dashboard_data.top_products_by_time[item] + }) + } + }); + + new Chart($(".chart-graphics"), { + type: 'line', + data: { + labels: this.getDateRangeAsArray(), + datasets: datasets + }, + options: { + legend: { position: 'bottom' }, + layout: { padding: 30 }, + scales: { + xAxes: [{ + gridLines: { display: false } + }], + yAxes: [{ + gridLines: { display: false }, + ticks: { + callback(value, index, values) { + return format_currency(value, null, 0); + } + } + }] + }, + tooltips: { + callbacks: { + label(tooltipItem, data) { + return format_currency(tooltipItem.value); + } + } + } + } + }); + + // Sales by territories + new Chart($(".category-product-info .donut-chart .graphics"), { + type: 'doughnut', + data: { + labels: this.dashboard_data.top_territories_by_revenue.map(elem => elem.territory), + datasets: [{ + data: this.dashboard_data.top_territories_by_revenue.map(elem => elem.grand_total), + backgroundColor: colors.rgba, + borderColor: colors.hex, + borderWidth: 1.5 + }] + }, + options: { + layout: { padding: 30 }, + legend: { position: 'left' }, + tooltips: { + callbacks: { + label(tooltipItem, data) { + return format_currency(data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]); + } + } + } + } + }); + + // Top products + this.dashboard_data.top_products_by_revenue.map((data, i) => { + let row = ` + + ${ (i+1) } + ${ data.item } + ${ format_currency(data.revenue) } + ${ data.volume } + + `; + $('.table-data tbody').append(row); + }); + + // Top sales partners + new Chart($(".bar-data .graphics"), { + type: 'horizontalBar', + data: { + labels: this.dashboard_data.top_sales_partners_by_revenue.map(elem => elem.sales_partner), + datasets: [{ + data: this.dashboard_data.top_sales_partners_by_revenue.map(elem => elem.grand_total), + backgroundColor: colors.rgba, + borderColor: colors.hex, + borderWidth: 1.5 + }] + }, + options: { + legend: { display: false }, + layout: { padding: 30 }, + scales: { + xAxes: [{ + gridLines: { display: false }, + barThickness: 30, + ticks: { + beginAtZero: true, + callback(value, index, values) { + return format_currency(value, null, 0); + } + } + }], + yAxes: [{ + gridLines: { display: false } + }] + }, + tooltips: { + callbacks: { + label(tooltipItem, data) { + return format_currency(tooltipItem.value); + } + } + } + } + }); + + // 2nd donut + new Chart($(".sales-partner-info .donut-chart .graphics"), { + type: 'doughnut', + data: { + labels: ['Paid', 'Unpaid', 'Overdue', 'Returned', 'Credit Issued'], + datasets: [{ + data: [ + this.dashboard_data.paid_invoices, + this.dashboard_data.unpaid_invoices, + this.dashboard_data.overdue_invoices, + this.dashboard_data.returned_invoices, + this.dashboard_data.credit_invoices + ], + backgroundColor: colors.rgba, + borderColor: colors.hex, + borderWidth: 1.5 + }] + }, + options: { + layout: { padding: 30 }, + legend: { position: 'left' }, + tooltips: { + callbacks: { + label(tooltipItem, data) { + return format_currency(data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]); + } + } + } + } + }); + + // Top customers + new Chart($(".graphical-distribution .graphics"), { + type: 'horizontalBar', + data: { + labels: this.dashboard_data.top_customers_by_revenue.map(elem => elem.customer), + datasets: [{ + data: this.dashboard_data.top_customers_by_revenue.map(elem => elem.grand_total), + backgroundColor: colors.rgba, + borderColor: colors.hex, + borderWidth: 1.5 + }] + }, + options: { + legend: { display: false }, + layout: { padding: 30 }, + scales: { + xAxes: [{ + gridLines: { display: false }, + barThickness: 30, + ticks: { + beginAtZero: true, + callback(value, index, values) { + return format_currency(value, null, 0); + } + } + }], + yAxes: [{ + gridLines: { display: false } + }] + }, + tooltips: { + callbacks: { + label(tooltipItem, data) { + return format_currency(tooltipItem.value); + } + } + } + } + }); + } +} diff --git a/bloomstack_core/bloomstack_core/page/insight_engine/insight_engine.json b/bloomstack_core/bloomstack_core/page/insight_engine/insight_engine.json new file mode 100644 index 000000000..9c0930f49 --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/insight_engine/insight_engine.json @@ -0,0 +1,23 @@ +{ + "content": null, + "creation": "2019-07-10 15:55:16.454251", + "docstatus": 0, + "doctype": "Page", + "idx": 0, + "modified": "2019-07-10 15:55:39.875772", + "modified_by": "Administrator", + "module": "Bloomstack Core", + "name": "insight-engine", + "owner": "Administrator", + "page_name": "Insight Engine", + "roles": [ + { + "role": "Analytics" + } + ], + "script": null, + "standard": "Yes", + "style": null, + "system_page": 0, + "title": "Insight Engine" +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/page/insight_engine/insight_engine.py b/bloomstack_core/bloomstack_core/page/insight_engine/insight_engine.py new file mode 100644 index 000000000..14fbc4395 --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/insight_engine/insight_engine.py @@ -0,0 +1,216 @@ +from datetime import timedelta + +import frappe +from erpnext.accounts.utils import get_balance_on +from frappe.utils import add_days, date_diff, getdate, nowdate + + +@frappe.whitelist() +def get_insight_engine_dashboards(start_date=None, end_date=None): + today = nowdate() + yesterday = add_days(today, -1) + last_week = add_days(today, -7) + last_month = add_days(today, -30) + + # Default the dates to a week + if not end_date: + end_date = today + if not start_date: + start_date = last_week + + date_range = (start_date, end_date) + + yesterdays_revenue = get_revenue_by_date(yesterday) + weekly_revenue = get_revenue_by_date_range(*date_range) + monthly_revenue = get_revenue_by_date_range(last_month, end_date) + top_products = get_top_products(*date_range) + top_customers = get_top_customers(*date_range) + top_territories = get_top_territories(*date_range) + top_sales_partners = get_top_sales_partners(*date_range) + pending_invoices = get_pending_invoices(*date_range) + cash_on_hand = get_cash_on_hand() + + return { + "yesterday_revenue": yesterdays_revenue, + "total_weekly_revenue": weekly_revenue.get("total", 0), + "average_weekly_revenue": weekly_revenue.get("average", 0), + "total_monthly_revenue": monthly_revenue.get("total", 0), + "average_monthly_revenue": monthly_revenue.get("average", 0), + "top_customers_by_revenue": top_customers.get("by_revenue"), + "top_territories_by_revenue": top_territories.get("by_revenue"), + "top_sales_partners_by_revenue": top_sales_partners.get("by_revenue"), + "top_products_by_revenue": top_products.get("by_revenue"), + "top_products_by_volume": top_products.get("by_volume"), + "top_products_by_time": top_products.get("by_time"), + "paid_invoices": pending_invoices.get("paid_invoices"), + "unpaid_invoices": pending_invoices.get("unpaid_invoices"), + "overdue_invoices": pending_invoices.get("overdue_invoices"), + "returned_invoices": pending_invoices.get("returned_invoices"), + "credit_invoices": pending_invoices.get("credit_invoices"), + "cash_on_hand": cash_on_hand + } + + +def get_revenue_by_date(date): + return frappe.db.get_value("Payment Entry", + {"posting_date": date, "docstatus": 1, "payment_type": "Receive"}, + "sum(paid_amount)") + + +def get_revenue_by_date_range(start_date, end_date): + payments = frappe.get_all("Payment Entry", + {"posting_date": ["BETWEEN", [start_date, end_date]], "docstatus": 1, "payment_type": "Receive"}, + ["sum(paid_amount) AS paid_amount"]) + + paid_amount = 0 + if payments: + paid_amount = payments[0].paid_amount or 0 + + average = paid_amount / date_diff(end_date, start_date) + + return { + "total": paid_amount, + "average": average + } + + +def get_cash_on_hand(): + cash_accounts = frappe.get_all("Account", filters={"account_type": "Cash", "root_type": "Asset", "is_group": 0}) + cash_on_hand = sum([get_balance_on(account.name) for account in cash_accounts]) + return cash_on_hand + + +def get_top_products(start_date, end_date, limit=10): + invoice_items_by_name = frappe.db.sql(""" + SELECT + si_item.item_name AS item, + SUM(si_item.net_amount) AS revenue, + SUM(si_item.qty) AS volume + FROM + `tabSales Invoice` si + LEFT JOIN `tabSales Invoice Item` si_item + ON si.name = si_item.parent + WHERE + si.docstatus = 1 + AND si.posting_date BETWEEN %(start_date)s AND %(end_date)s + GROUP BY + si_item.item_name + """, { + "start_date": start_date, + "end_date": end_date + }, as_dict=True) + + if not invoice_items_by_name: + return { + "by_revenue": [], + "by_volume": [], + "by_time": [] + } + + top_products_by_revenue = sorted(invoice_items_by_name, key=lambda item: item.revenue, reverse=True)[:limit] + top_products_by_volume = sorted(invoice_items_by_name, key=lambda item: item.volume, reverse=True)[:limit] + top_products = list(map(lambda d: d.get("item"), top_products_by_revenue))[:5] + + invoice_items_by_date = frappe.db.sql(""" + SELECT + si.posting_date AS date, + si_item.item_name AS item, + si_item.net_amount AS revenue, + si_item.qty AS volume + FROM + `tabSales Invoice` si + LEFT JOIN `tabSales Invoice Item` si_item + ON si.name = si_item.parent + WHERE + si.docstatus = 1 + AND si.posting_date BETWEEN %(start_date)s AND %(end_date)s + AND si_item.item_name IN %(top_products)s + ORDER BY + si.posting_date ASC + """, { + "start_date": start_date, + "end_date": end_date, + "top_products": top_products + }, as_dict=True) + + # Form a list of dates between the start and end dates + total_days = date_diff(end_date, start_date) + date_list = [getdate(start_date) + timedelta(days=x) for x in range(total_days)] + + # Form a dictionary of items and list of sales per day + top_products_by_time_and_revenue = {} + for product in top_products: + top_products_by_time_and_revenue[product] = {date: 0 for date in date_list} + + for invoice in invoice_items_by_date: + # Ensure only invoices with the requested dates get calculated + if invoice.date in top_products_by_time_and_revenue.get(invoice.item, {}): + top_products_by_time_and_revenue[invoice.item][invoice.date] += invoice.revenue + + # NOTE: Doing dates.values() returns a list of values in an arbitrary order + # ref: https://docs.python.org/2/library/stdtypes.html#dict.items + # Using list-comp with a sorted dict to get the values in right order + top_products_by_time_and_revenue = { + item: [dates.get(date) for date in sorted(dates)] + for item, dates in top_products_by_time_and_revenue.items() + } + + return { + "by_revenue": top_products_by_revenue, + "by_volume": top_products_by_volume, + "by_time": top_products_by_time_and_revenue + } + + +def get_top_customers(start_date, end_date, limit=10): + customers = get_invoices_by_field("customer", start_date, end_date) + + return { + "by_revenue": sorted(customers, key=lambda customer: customer.grand_total, reverse=True)[:limit] + } + + +def get_top_territories(start_date, end_date, limit=5): + territories = get_invoices_by_field("territory", start_date, end_date) + + return { + "by_revenue": sorted(territories, key=lambda customer: customer.grand_total, reverse=True)[:limit] + } + + +def get_top_sales_partners(start_date, end_date, limit=5): + sales_partners = get_invoices_by_field("sales_partner", start_date, end_date) + + return { + "by_revenue": sorted(sales_partners, key=lambda partner: partner.grand_total, reverse=True)[:limit] + } + + +def get_pending_invoices(start_date, end_date): + invoices = get_invoices_by_field("status", start_date, end_date) + + def get_invoice_totals_by_status(status): + return next((invoice.grand_total for invoice in invoices if invoice.status == status), 0) + + paid_invoices = get_invoice_totals_by_status("Paid") + unpaid_invoices = get_invoice_totals_by_status("Unpaid") + overdue_invoices = get_invoice_totals_by_status("Overdue") + returned_invoices = get_invoice_totals_by_status("Return") + credit_invoices = get_invoice_totals_by_status("Credit Note Issued") + + return { + "paid_invoices": paid_invoices, + "unpaid_invoices": unpaid_invoices, + "overdue_invoices": overdue_invoices, + "returned_invoices": returned_invoices, + "credit_invoices": credit_invoices + } + + +def get_invoices_by_field(field, start_date, end_date): + invoices = frappe.get_all("Sales Invoice", + filters={"posting_date": ["BETWEEN", [start_date, end_date]], "docstatus": 1}, + fields=[field, "SUM(grand_total) AS grand_total"], + group_by=field) + + return invoices diff --git a/bloomstack_core/bloomstack_core/page/track_and_trace/__init__.py b/bloomstack_core/bloomstack_core/page/track_and_trace/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/bloomstack_core/page/track_and_trace/modules.js b/bloomstack_core/bloomstack_core/page/track_and_trace/modules.js new file mode 100644 index 000000000..340844054 --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/track_and_trace/modules.js @@ -0,0 +1,257 @@ +/* global frappe, bloomstack */ +frappe.provide("bloomstack.track_and_trace"); + +bloomstack.get_doc = (cdt, cdn) => { + return Promise.resolve(frappe.call({ + method: "frappe.client.get", + args: { + doctype: cdt, + name: cdn + } + })).then(r => { + return r.message; + }); +} + +bloomstack.get_value = (doctype, fieldname, filters, parent) => { + return Promise.resolve(frappe.call({ + method: "frappe.client.get_value", + args: { + doctype, + fieldname, + filters, + parent + } + })).then(r => { + return r.message; + }); +} + +bloomstack.track_and_trace.default_module = { + has_route: true, + + route(dt, dn) { + frappe.set_route("Form", dt, dn); + }, + + after_render(dt, dn, $el) { + let me = this; + if ( this.has_route ) { + let $link = $('') + $el.find('.title').append($link); + $link.click(function(e) { + e.preventDefault(); + me.route(dt, dn); + return false; + }); + } + + $el.find('[data-route-dt]').click(function(e) { + let routeDT = $(this).attr('data-route-dt'); + let routeDN = $(this).attr('data-route-dn'); + if ( routeDT && routeDN ) { + e.preventDefault(); + me.route(routeDT, routeDN); + return false; + } + }) + } +} + +bloomstack.track_and_trace.ModulesManager = class { + constructor() { + this.modules = {}; + } + + add(dt, customization) { + if ( !this.modules.hasOwnProperty(dt) ) { + this.modules[dt] = []; + } + + customization = Object.assign({}, bloomstack.track_and_trace.default_module, customization); + + this.modules[dt].push(customization); + } + + render(dt, dn, data) { + let render_data = Object.assign({ + format(value, fieldtype) { + if ( !fieldtype ) { + return value; + } + + return frappe.format(value, { fieldtype }, { only_value: true }); + } + }, data); + + if ( this.modules.hasOwnProperty(dt) ) { + const parentHash = `${dt}/${dn}`; + if ( (data.parents || {}).hasOwnProperty(parentHash) ) { + return Promise.resolve(""); + } + + return this.modules[dt].reduce((p, c) => { + if ( c.hasOwnProperty("render" ) ) { + return p.then((html) => c.render(dt, dn, render_data, html)); + } else if ( c.hasOwnProperty("template") ) { + return p.then((html) => frappe.render_template(c.template, render_data)); + } + + return p.then(html => frappe.render_template("track_and_trace_module_generic", render_data)); + }, Promise.resolve()) + } + + return Promise.resolve(frappe.render_template("track_and_trace_module_generic", render_data)); + } + + after_render(dt, dn, $el) { + if ( this.modules.hasOwnProperty(dt) ) { + return this.modules[dt].reduce((p, c) => { + if ( c.hasOwnProperty("after_render" ) ) { + return p.then(($el) => c.after_render(dt, dn, $el)); + } + + return p; + }, Promise.resolve($el)) + } + + return Promise.resolve(); + } + + query(dt, dn, data) { + if ( typeof data === undefined ) { + data = {}; + } + + let result = null; + + if ( this.modules.hasOwnProperty(dt) ) { + result = this.modules[dt].reduce((p, c) => { + if ( c.hasOwnProperty("query" ) ) { + if ( data.query !== false ) { + return p.then((data) => Promise.resolve(c.query(dt, dn, data))); + } + } else { + if ( data.query !== false ) { + return p.then((data) => this.default_query(dt, dn, data, c)); + } + } + + return p; + }, Promise.resolve(data || {})); + } else if ( data.query !== false ) { + + result = this.default_query(dt, dn, data); + } else { + result = Promise.resolve(data); + } + + return result.then((r) => { + r.search_dt = data.search_dt; + r.search_dn = data.search_dn; + r.parents = Object.assign({}, data.parents || {}); + this.dedupe_parents(r); + return r; + }); + } + + dedupe_parents(node) { + if ( node.children && node.children.length > 0 ) { + const parentHash = `${node.dt}/${node.dn}`; + node.children = node.children.reduce((new_list, child) => { + let chHash = `${child.dt}/${child.dn}`; + if ( !node.parents.hasOwnProperty(chHash) ) { + child.parents = Object.assign({}, node.parents || {}, { + [parentHash]: true + }); + new_list.push(child); + } + + return new_list + }, []); + } + } + + format(data) { + const dt = data.dt; + const dn = data.dn; + + if ( dt && dn && this.modules.hasOwnProperty(dt) ) { + return this.modules[dt].reduce((p, c) => { + if ( c.hasOwnProperty("format" ) ) { + return p.then((data) => Promise.resolve(c.format(data))); + } + + return p; + }, Promise.resolve(data)) + .then((r) => { + this.dedupe_parents(r); + return r; + }); + } + + return Promise.resolve(data) + .then((r) => { + this.dedupe_parents(r); + return r; + }) + } + + default_query(dt, dn, query_data, c) { + return bloomstack.get_doc(dt, dn) + .then((data) => { + let children = []; + if ( data.items ) { + + children = data.items.map((item) => { + let childFields = []; + let childIcon = c?c.icon || "fa fa-question": "fa fa-question"; + if ( this.modules.hasOwnProperty(item.doctype) ) { + childFields = this.modules[item.doctype].reduce((p, c) => { + if ( c.hasOwnProperty("icon") ) { + childIcon = c.icon; + } + + if ( c.hasOwnProperty("fields") ) { + for(let field of c.fields) { + let existingIdx = p.findIndex((f) => f.field === field.field); + if ( existingIdx > -1 ) { + p.splice(existingIdx, 1, field); + } else { + p.push(field); + } + } + } + return p; + }, []); + } + return { + search_dt: query_data.search_dt, + search_dn: query_data.search_dn, + query: false, + dt: item.doctype, + dn: item.name, + image_path: null, + icon: childIcon, + title: `${item.doctype}: ${item.name}`, + fields: childFields, + data: item, + children: [] + } + }); + } + return { + search_dt: query_data.search_dt, + search_dn: query_data.search_dn, + dt, + dn, + image_path: null, + icon: c?c.icon || "fa fa-question": "fa fa-question", + title: `${data.doctype}: ${data.name}`, + fields: (c?c.fields || []: []).slice(), + data, + children + } + }); + } +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/page/track_and_trace/modules/batch.js b/bloomstack_core/bloomstack_core/page/track_and_trace/modules/batch.js new file mode 100644 index 000000000..9c2291eb6 --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/track_and_trace/modules/batch.js @@ -0,0 +1,105 @@ +/* global frappe, bloomstack */ + +bloomstack.track_and_trace.modules.add("Batch", { + fields: [ + { field: "item", label: "Item" }, + { field: "manufacturing_date", label: "Manufacturing Date", fieldtype: "Date" }, + { field: "supplier", label: "Supplier" }, + ], + + icon: "fa fa-th-large", + + format(data) { + let batch = data.data; + + + if ( batch.reference_doctype && batch.reference_name ) { + data.children.push({ + query: true, + dt: batch.reference_doctype, + dn: batch.reference_name, + search_dt: data.search_dt, + search_dn: data.search_dn + }); + } + + return bloomstack.get_value("Item", "item_name", { name: batch.item}) + .then((v) => { + batch.item = `${v.item_name} (${batch.item})`; + }) + .then(() => { + return Promise.resolve(frappe.call({ + method: "frappe.client.get_list", + args: { + doctype: "Stock Ledger Entry", + fields: ["name"], + filters: [["batch_no", "=", batch.name], ["actual_qty", ">", 0]], + order_by: "creation DESC", + limit_page_length: 9999 + } + })); + }) + .then((r) => { + if ( r.message ) { + data.children.push({ + query: false, + dt: "report#Stock Ledger/Positive", + dn: data.dn, + search_dt: data.search_dt, + search_dn: data.search_dn, + image_path: null, + icon: "fa fa-arrow-up positive", + title: "Was used to manufacture", + fields: [], + parents: Object.assign({}, data.parents || {}), + children: r.message.map((row) => ({ + query: true, + dt: "Stock Ledger Entry", + dn: row.name, + search_dt: data.search_dt, + search_dn: data.search_dn + })) + }) + } + }) + .then(() => { + return Promise.resolve(frappe.call({ + method: "frappe.client.get_list", + args: { + doctype: "Stock Ledger Entry", + fields: ["name"], + filters: [["batch_no", "=", batch.name], ["actual_qty", "<", 0]], + order_by: "creation DESC", + limit_page_length: 9999 + } + })); + }) + .then((r) => { + if ( r.message ) { + data.children.push({ + query: false, + dt: "report#Stock Ledger/Negative", + dn: data.dn, + search_dt: data.search_dt, + search_dn: data.search_dn, + image_path: null, + icon: "fa fa-arrow-down negative", + title: "Was manufactured from", + fields: [], + parents: Object.assign({}, data.parents || {}), + children: r.message.map((row) => ({ + query: true, + dt: "Stock Ledger Entry", + dn: row.name, + search_dt: data.search_dt, + search_dn: data.search_dn + })) + }) + } + }) + .then(() => { + return data; + }); + } + +}); \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/page/track_and_trace/modules/delivery_note.js b/bloomstack_core/bloomstack_core/page/track_and_trace/modules/delivery_note.js new file mode 100644 index 000000000..60213c333 --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/track_and_trace/modules/delivery_note.js @@ -0,0 +1,57 @@ +/* global frappe, bloomstack */ + +bloomstack.track_and_trace.modules.add("Delivery Note", { + fields: [ + { field: "posting_date", label: "Posting Date", fieldtype: "Date" }, + { field: "customer", label: "Customer" }, + { field: "set_warehouse", label: "Source Warehouse" }, + { field: "to_warehouse", label: "To Warehouse" }, + { field: "grand_total", label: "Grand Total", fieldtype: "Currency" }, + { field: "status", label: "Status" } + ], + + icon: "fa fa-truck" + +}); + +bloomstack.track_and_trace.modules.add("Delivery Note Item", { + fields: [ + { field: "barcode", label: "Barcode"}, + { field: "item_code", label: "Item Code"}, + { field: "qty", label: "Qty"}, + { field: "uom", label: "UOM"}, + { field: "batch_no", label: "Batch No"}, + { field: "serial_no", label: "Serial No"} + ], + + icon: "fa fa-list", + + has_route: false, + + format(data) { + let dni = data.data; + + data.title = `Delivery Node Item: ${dni.item_code}`; + + if ( dni.batch_no ) { + data.children.push({ + dt: "Batch", + dn: dni.batch_no, + search_dt: data.search_dt, + search_dn: data.search_dn + }) + } + + if ( dni.serial_no ) { + data.children.push({ + dt: "Serial No", + dn: dni.serial_no.split(/\s+/g)[0], + search_dt: data.search_dt, + search_dn: data.search_dn + }) + } + + return data; + } + +}); \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/page/track_and_trace/modules/index.js b/bloomstack_core/bloomstack_core/page/track_and_trace/modules/index.js new file mode 100644 index 000000000..64c79e09c --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/track_and_trace/modules/index.js @@ -0,0 +1,7 @@ +{% include "bloomstack_core/bloomstack_core/page/track_and_trace/templates/track_and_trace_module_generic.html" %} +{% include "bloomstack_core/bloomstack_core/page/track_and_trace/modules/serial_no.js" %} +{% include "bloomstack_core/bloomstack_core/page/track_and_trace/modules/stock_entry.js" %} +{% include "bloomstack_core/bloomstack_core/page/track_and_trace/modules/stock_ledger_entry.js" %} +{% include "bloomstack_core/bloomstack_core/page/track_and_trace/modules/batch.js" %} +{% include "bloomstack_core/bloomstack_core/page/track_and_trace/modules/delivery_note.js" %} +{% include "bloomstack_core/bloomstack_core/page/track_and_trace/modules/purchase_receipt.js" %} diff --git a/bloomstack_core/bloomstack_core/page/track_and_trace/modules/purchase_receipt.js b/bloomstack_core/bloomstack_core/page/track_and_trace/modules/purchase_receipt.js new file mode 100644 index 000000000..c2a32b8d2 --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/track_and_trace/modules/purchase_receipt.js @@ -0,0 +1,33 @@ +/* global frappe, bloomstack */ + +bloomstack.track_and_trace.modules.add("Purchase Receipt", { + fields: [ + { field: "work_order", label: "Work Order" }, + { field: "posting_date", label: "Posting Date", fieldtype: "Date" } + ], + + icon: "fa fa-book" +}); + +bloomstack.track_and_trace.modules.add("Purchase Receipt Item", { + fields: [ + { field: "item_name", label: "Item Name" }, + { field: "qty", label: "Qty" }, + { field: "stock_uom", label: "UOM" }, + { field: "rate", label: "Rate", fieldtype: "Currency" }, + { field: "amount", label: "Amount", fieldtype: "Currency" }, + { field: "purchase_order", label: "Purchase Order" } + ], + + icon: "fa fa-file-text-o", + + has_route: false, + + format(data) { + let item = data.data; + data.title = `${item.item_code}: ${item.item_name}`; + + return data; + } + +}); \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/page/track_and_trace/modules/serial_no.js b/bloomstack_core/bloomstack_core/page/track_and_trace/modules/serial_no.js new file mode 100644 index 000000000..fb30fabbe --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/track_and_trace/modules/serial_no.js @@ -0,0 +1,31 @@ +/* global frappe, bloomstack */ + +bloomstack.track_and_trace.modules.add("Serial No", { + fields: [ + { field: "item_code", label: "Item Code"}, + { field: "item_name", label: "Item Name"}, + { field: "warehouse", label: "Warehouse"} + ], + + icon: "fa fa-barcode", + + query(dt, dn, data) { + return bloomstack.track_and_trace.modules + .default_query(dt, dn, data, this) + .then((result) => { + let children = []; + let serial = result.data; + if ( serial.purchase_document_type ) { + children.push({ + query: true, + search_dt: result.search_dt, + search_dn: result.search_dn, + dt: serial.purchase_document_type, + dn: serial.purchase_document_no + }) + } + result.children = result.children.concat(children); + return result; + }); + } +}); diff --git a/bloomstack_core/bloomstack_core/page/track_and_trace/modules/stock_entry.js b/bloomstack_core/bloomstack_core/page/track_and_trace/modules/stock_entry.js new file mode 100644 index 000000000..d588677af --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/track_and_trace/modules/stock_entry.js @@ -0,0 +1,86 @@ +/* global frappe, bloomstack */ + +bloomstack.track_and_trace.modules.add("Stock Entry", { + fields: [ + { field: "work_order", label: "Work Order"}, + { field: "posting_date", label: "Posting Date", fieldtype: "Date"} + ], + + icon: "fa fa-archive" + +}); + +bloomstack.track_and_trace.modules.add("Stock Entry Detail", { + fields: [ + { field: "s_warehouse", label: "Source Warehouse" }, + { field: "t_warehouse", label: "Target Warehouse" }, + { field: "item_name", label: "Item Name" }, + { field: "qty", label: "Qty" }, + { field: "stock_uom", label: "UOM" }, + { field: "batch_no", label: "Batch No" }, + { field: "serial_no", label: "Serial No" } + ], + + icon: "fa fa-archive", + + has_route: false, + + format(data) { + + let entry = data.data; + data.title = `${entry.item_code}: ${entry.item_name}`; + + if ( data.data.serial_no ) { + let serials = data.data.serial_no.trim().split(/\\n+|,/); + if ( serials.length === 1 ) { + if ( serials[0] === data.search_dn ) { + data.data.serial_no = data.search_dn; + } + } else { + data.data.serial_no = "MULTIPLE"; + } + + if ( serials.length > 0 ) { + for(let serial of serials) { + data.children.push({ + query: true, + search_dt: data.search_dt, + search_dn: data.search_dn, + dt: "Serial No", + dn: serial.trim() + }) + } + } + } + + if ( data.data.batch_no ) { + // preemptively adds a child node to be queried when this node is + // expanded by the user. + data.children.push({ + query: true, + search_dt: data.search_dt, + search_dn: data.search_dn, + dt: "Batch", + dn: data.data.batch_no + }) + } + + // remove source warehouse from fields if not present + if ( entry.s_warehouse ) { + // we'll pepper in additional icon for input for UX + data.title = `
  • ${data.title}`; + } + + // remove target warehouse from fields if not present + if ( entry.t_warehouse ) { + // we'll pepper in additional icon for outpuy for UX + data.title = `
  • ${data.title}`; + } + + return bloomstack.get_value("Item", "image", { name: entry.item_code }) + .then((result) => { + data.image_path = result.image; + return data; + }) + } +}); diff --git a/bloomstack_core/bloomstack_core/page/track_and_trace/modules/stock_ledger_entry.js b/bloomstack_core/bloomstack_core/page/track_and_trace/modules/stock_ledger_entry.js new file mode 100644 index 000000000..b4dc4d7b9 --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/track_and_trace/modules/stock_ledger_entry.js @@ -0,0 +1,41 @@ +/* global frappe, bloomstack */ + +bloomstack.track_and_trace.modules.add("Stock Ledger Entry", { + fields: [ + { field: "actual_qty", label: "Qty" }, + { field: "stock_uom", label: "UOM" }, + { field: "warehouse", label: "Warehouse" }, + { field: "item_code", label: "Item" } + ], + + icon: "fa fa-pencil-square-o", + + has_route: false, + + format(data) { + let entry = data.data; + + if ( entry.voucher_no && entry.voucher_type ) { + let qty_arrow = (entry.actual_qty > 0)?"fa-arrow-up positive":(entry.actual_qty < 0)?"fa-arrow-down negative":""; + let from_to_lbl = (entry.actual_qty > 0)?"FROM":(entry.actual_qty < 0)?"TO":""; + data.title = `${from_to_lbl} ${entry.voucher_type}: ${entry.voucher_no}`; + + data.children.push({ + query: true, + dt: entry.voucher_type, + dn: entry.voucher_no, + search_dt: data.search_dt, + search_dn: data.search_dn + }); + + } + + return bloomstack.get_value("Item", "name", { item_code: entry.item_code }) + .then((v) => { + entry.item_name = `${entry.item_code}`; + + return data; + }) + } + +}); diff --git a/bloomstack_core/bloomstack_core/page/track_and_trace/templates/track_and_trace_main.html b/bloomstack_core/bloomstack_core/page/track_and_trace/templates/track_and_trace_main.html new file mode 100644 index 000000000..64608318d --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/track_and_trace/templates/track_and_trace_main.html @@ -0,0 +1,23 @@ +
    +
    + +
    +
    +

    Welcome to the Bloomstack Track & Trace report. Please type in a serial number or a batch number in the box above to get started.

    +

    This report helps your track the exact chain of movement associated with any serial number or batch of marijuana. All products used to manufacture (and manufactured from) the above item will be displayed here.

    +
    + +
    \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/page/track_and_trace/templates/track_and_trace_module_generic.html b/bloomstack_core/bloomstack_core/page/track_and_trace/templates/track_and_trace_module_generic.html new file mode 100644 index 000000000..a55e376f7 --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/track_and_trace/templates/track_and_trace_module_generic.html @@ -0,0 +1,41 @@ +
  • +
    +
    +
    +
    {% if ( children.length > 0 ) { %}{% } %}
    +
    +

    + + {%= title %} + + + + +

    +
    + {% if ( image_path ) { %} + + {% } %} +
      + {% for(let i in fields) { %} + {% if ( data[fields[i].field] !== undefined && data[fields[i].field] !== null && data[fields[i].field] !== "" ) { %} +
    • {%= fields[i].label %}: {%= format(data[fields[i].field], fields[i].fieldtype) %}
    • + {% } %} + {% } %} +
    +
    +
    +
    +
      +
      +
    • \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/page/track_and_trace/templates/track_and_trace_pagination.html b/bloomstack_core/bloomstack_core/page/track_and_trace/templates/track_and_trace_pagination.html new file mode 100644 index 000000000..d75272b2e --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/track_and_trace/templates/track_and_trace_pagination.html @@ -0,0 +1,24 @@ +{% if ( total_pages > 1 ) { %} + +{% } %} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/page/track_and_trace/track_and_trace.js b/bloomstack_core/bloomstack_core/page/track_and_trace/track_and_trace.js new file mode 100644 index 000000000..f960e2c76 --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/track_and_trace/track_and_trace.js @@ -0,0 +1,376 @@ +/* global frappe, bloomstack */ +frappe.provide("bloomstack.track_and_trace"); + +{% include "bloomstack_core/bloomstack_core/page/track_and_trace/modules.js" %} + +bloomstack.track_and_trace.modules = new bloomstack.track_and_trace.ModulesManager(); + +{% include "bloomstack_core/bloomstack_core/page/track_and_trace/modules/index.js" %} +{% include "bloomstack_core/bloomstack_core/page/track_and_trace/templates/track_and_trace_main.html" %} +{% include "bloomstack_core/bloomstack_core/page/track_and_trace/templates/track_and_trace_pagination.html" %} + +frappe.pages['track-and-trace'].on_page_load = function(wrapper) { + var page = frappe.ui.make_app_page({ + parent: wrapper, + title: '', + single_column: true + }); + + wrapper.TraceAndTrack = new bloomstack.track_and_trace.TraceAndTrack(wrapper); +} + +frappe.pages['track-and-trace'].refresh = function (wrapper) { + $(window).on('beforeunload', function() { + wrapper.TraceAndTrack.beforeunload() + }); +} + +bloomstack.delay = function(milliseconds) { + return new Promise((resolve) => { + setTimeout(function() { + resolve(milliseconds); + }, milliseconds); + }); +} + +bloomstack.cancelable = function(pr) { + const _cancelable = { + was_canceled: false, + ifNotCanceled(fn) { + return (data) => { + if ( !_cancelable.was_canceled ) { + return fn(data); + } + } + }, + + ifCanceled(fn) { + return (data) => { + if ( _cancelable.was_canceled ) { + return fn(data); + } + } + } + }; + + _cancelable.promise = new Promise(function(resolve, reject) { + _cancelable.cancel = function() { + _cancelable.was_canceled = true; + _cancelable.reason = 'canceled'; + reject(_cancelable); + } + + pr.then((data) => { + _cancelable.data = data; + if ( _cancelable.was_canceled ) { + reject(_cancelable); + } else { + resolve(_cancelable); + } + + return data; + }, (err) => { + _cancelable.err = err; + _cancelable.reason = 'error'; + reject(_cancelable); + }); + }); + + return _cancelable; +}; + +bloomstack.track_and_trace.TraceAndTrack = class { + constructor(wrapper) { + this.wrapper = $(wrapper).find('.layout-main-section'); + this.page = wrapper.page; + this.search_delay = null; + this.search_query = null; + this.current_page = 0; + this.total_pages = 0; + this.page_size = 20; + + const assets = [ + 'assets/bloomstack_core/css/track_and_trace.css' + ]; + + frappe.require(assets, () => { + this.make(); + }); + } + + make() { + return frappe.run_serially([ + () => frappe.dom.freeze(), + () => { + this.prepare_dom(); + }, + () => { + frappe.dom.unfreeze(); + }, + () => this.page.set_title(__('Track And Trace')) + ]); + } + + prepare_dom() { + let me = this; + let html = frappe.render_template('track_and_trace_main', this); + this.wrapper.empty().append(html); + + this.wrapper.find('input.search-input:first') + .focus() + .on('keyup', function(e) { + me.search($(this).val()); + }); + + this.wrapper.find('.collapse-fields button').click(function() { + if ( $(this).data('hidden') ) { + me.wrapper.find('.results .node').removeClass('hide-fields'); + $(this).data('hidden', false); + } else { + me.wrapper.find('.results .node').addClass('hide-fields'); + $(this).data('hidden', true); + } + + me.update_field_toggle_label(); + + }); + + this.update_field_toggle_label(); + } + + update_field_toggle() { + // makes sure that field toggle is predictable, even if one node + // has visible fields, next toggle click will close first. + this.wrapper.find('.collapse-fields button') + .data('hidden', this.wrapper.find('.node.hide-fields').length > 0); + + this.update_field_toggle_label(); + } + + update_field_toggle_label() { + let label = this.wrapper.find('.collapse-fields button').data('hidden') === true?'Show':'Hide'; + this.wrapper.find('.collapse-fields button').text(`${label} Fields`); + } + + _render_node($container, dt, dn, query_data, cancelable) { + const me = this; + let ifNotCanceled = (fn) => (data) => fn(data); + if ( cancelable !== undefined ) { + ifNotCanceled = cancelable.ifNotCanceled; + } + + return bloomstack.track_and_trace.modules + .query(dt, dn, query_data) + .then((data) => { + // keeping microtemplate happy... + data.is_first = query_data.is_first !== undefined?query_data.is_first: false; + data.is_last = query_data.is_last !== undefined?query_data.is_last: false; + data.tree_depth = query_data.tree_depth || 0; + return data; + }) + .then(ifNotCanceled((data) => bloomstack.track_and_trace.modules.format(data))) + .then(ifNotCanceled((data) => { + return Promise.resolve(bloomstack.track_and_trace.modules.render(dt, dn, data)) + .then((html) => { + return { + html, + data + } + }); + })) + .then(ifNotCanceled((result) => { + const { html, data } = result; + if ( html ) { + let $el = $(html); + $container.append($el); + $el.data('query_data', data); + $el.find('.node-handle').click(function() { + me.toggle_node($el); + }); + + // default field toggle to current global field toggle setting + if ( this.wrapper.find('.collapse-fields button').data('hidden') ) { + $el.addClass('hide-fields') + } else { + $el.removeClass('hide-fields') + } + + $el.find('.leaf:first > .content .actions .field-collapse').click(function(e) { + $el.toggleClass('hide-fields'); + if ( e.ctrlKey ) { + if ( $el.hasClass('hide-fields') ) { + $el.find('.node').addClass('hide-fields'); + } else { + $el.find('.node').removeClass('hide-fields'); + } + } + + me.update_field_toggle(); + e.stopPropagation(); + return false; + }); + bloomstack.track_and_trace.modules.after_render(dt, dn, $el) + return $el; + } + })); + } + + _run_search(text, current_page) { + if ( typeof current_page === undefined ) { + current_page = this.current_page; + } + + if ( current_page < 0 ) { + current_page = 0; + } + + if ( current_page > this.total_pages ) { + current_page = this.total_pages - 1; + } + + let _cancelable = bloomstack.cancelable( + frappe.call({ + method: 'bloomstack_core.bloomstack_core.page.track_and_trace.track_and_trace.search', + freeze: false, + args: { + text, + start: current_page * this.page_size, + limit: this.page_size + } + }) + ); + + _cancelable.promise.then((c) => { + let data = c.data.message; + + this.wrapper.find('.results').empty(); + if ( data.length > 0 ) { + this.current_page = current_page; + this.total_pages = Math.ceil(data[0][2] / this.page_size); + if ( this.current_page >= this.total_pages ) { + this.current_page = total_pages - 1; + } + + this.render_pager({ + current_page: this.current_page, + total_pages: this.total_pages, + search: text + }); + } + + let p = Promise.resolve(); + data.forEach((row) => { + const dt = row[0]; + const dn = row[1]; + + p = p.then(() => + this._render_node(this.wrapper.find('.results'), dt, dn, { + parents: {}, + search_dt: dt, + search_dn: dn + }, _cancelable) + ); + }); + }); + + return _cancelable; + } + + render_pager(paginator_data) { + let me = this; + let $paginator = this.wrapper.find('.paginator-top').empty(); + let $paginator_controls = $(frappe.render_template("track_and_trace_pagination", paginator_data)); + $paginator.append($paginator_controls); + + $paginator_controls.find('.first').click(function() { + me._pagination_go_to_page(paginator_data.search, 0); + }) + + $paginator_controls.find('.prev').click(function() { + me._pagination_go_to_page(paginator_data.search, paginator_data.current_page - 1); + }) + + $paginator_controls.find('.last').click(function() { + me._pagination_go_to_page(paginator_data.search, paginator_data.total_pages - 1); + }) + + $paginator_controls.find('.next').click(function() { + me._pagination_go_to_page(paginator_data.search, paginator_data.current_page + 1); + }) + + $paginator_controls.find('.current-page').change(function(e) { + let page = parseInt($(this).val() || 1) - 1; + me._pagination_go_to_page(paginator_data.search, page); + }); + } + + _pagination_go_to_page(text, page) { + if ( this.search_query ) { + this.search_query.cancel(); + } + + this.search_query = this._run_search(text, page); + } + + toggle_node($el) { + let data = $el.data('query_data'); + let $container = $el.find('.children:first'); + if ( $el.hasClass('children-loaded') ) { + if ( $el.hasClass('open') ) { + $container.slideUp(200); + $el.removeClass('open'); + } else { + $container.slideDown(200); + $el.addClass('open'); + } + } else { + $container.slideDown(200); + $el.addClass('children-loaded') + $el.addClass('open') + $el.addClass('loading') + + if ( data.children.length > 0 ) { + data.children.reduce((p, ch, index, allChildren) => { + ch.is_first = index === 0; + ch.is_last = index === allChildren.length - 1; + ch.tree_depth = (data.tree_depth || 0) + 1; + return p.then(() => this._render_node($container, ch.dt, ch.dn, ch)); + }, Promise.resolve()) + .then(()=> { + $el.removeClass('loading'); + }); + } + } + } + + search(text) { + if ( this.search_delay ) { + this.search_delay.cancel(); + this.search_delay = null; + } + + if ( text ) { + + this.search_delay = bloomstack.cancelable(bloomstack.delay(500)); + this.search_delay + .promise.then((c) => { + this.search_query = this._run_search(text, 0); + }) + .catch((c) => { + if ( c.err ) { + console.error(c.err); + } else if ( !c.was_canceled ) { + console.error(c); + } + if ( c.was_canceled && this.search_query ) { + this.search_query.cancel(); + } + }); + + } + } + + beforeunload() { + + } +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/page/track_and_trace/track_and_trace.json b/bloomstack_core/bloomstack_core/page/track_and_trace/track_and_trace.json new file mode 100644 index 000000000..e1f8ae75a --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/track_and_trace/track_and_trace.json @@ -0,0 +1,19 @@ +{ + "content": null, + "creation": "2018-12-28 11:05:57.762000", + "docstatus": 0, + "doctype": "Page", + "idx": 0, + "modified": "2019-07-15 06:15:56.406778", + "modified_by": "Administrator", + "module": "Bloomstack Core", + "name": "track-and-trace", + "owner": "Administrator", + "page_name": "track-and-trace", + "roles": [], + "script": null, + "standard": "Yes", + "style": null, + "system_page": 0, + "title": "Track and Trace" +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/page/track_and_trace/track_and_trace.py b/bloomstack_core/bloomstack_core/page/track_and_trace/track_and_trace.py new file mode 100644 index 000000000..76f22d3b7 --- /dev/null +++ b/bloomstack_core/bloomstack_core/page/track_and_trace/track_and_trace.py @@ -0,0 +1,36 @@ +from __future__ import unicode_literals + +import frappe +from frappe.utils import cint + +@frappe.whitelist() +def search(text, start=0, limit=10): + + # This could be changed to text matching instead of strictly searching doc names + sql = """ + WITH search AS ( + SELECT * FROM ( + SELECT 'Serial No' as doctype, name as docname FROM `tabSerial No` + UNION + SELECT 'Batch' as doctype, name as docname FROM `tabBatch` + ) q + WHERE + q.docname LIKE %(text)s + ) + SELECT + *, + (SELECT COUNT(0) FROM search) as total_rows + FROM search + ORDER BY + docname ASC + LIMIT + %(start)s, %(limit)s; + """ + + results = frappe.db.sql(sql, { + "text": "%" + text + "%", + "start": cint(start), + "limit": cint(limit) + }, as_list=1, debug=1) + + return results \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/print_format/__init__.py b/bloomstack_core/bloomstack_core/print_format/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/bloomstack_core/print_format/shipping_manifest/__init__.py b/bloomstack_core/bloomstack_core/print_format/shipping_manifest/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/bloomstack_core/print_format/shipping_manifest/shipping_manifest.json b/bloomstack_core/bloomstack_core/print_format/shipping_manifest/shipping_manifest.json new file mode 100644 index 000000000..5b77e7c4e --- /dev/null +++ b/bloomstack_core/bloomstack_core/print_format/shipping_manifest/shipping_manifest.json @@ -0,0 +1,23 @@ +{ + "align_labels_right": 0, + "creation": "2018-08-22 00:30:43.714613", + "css": ".print-format {\n font-size: 10px;\n padding: 0.45in;\n}\n\n.table {\n margin: 0 0 2em 0;\n page-break-inside: avoid;\n}\n\n.table td {\n font-size: 0.9em;\n line-height: 1em !important;\n}\n\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > td,\n.table-bordered > tbody > tr > th {\n border: 1px solid black !important;\n}\n\n.manifest-header {\n font-size: 1.4em;\n}\n\n.manifest-disclaimer {\n font-size: 0.8em;\n}\n\n.section-header {\n font-size: 1em;\n}\n\n.section-subheader {\n font-size: 0.9em;\n font-weight: normal;\n}\n\n.table-left {\n padding-left: 0;\n}\n\n.table-right {\n padding-right: 0;\n}", + "custom_format": 1, + "disabled": 0, + "doc_type": "Delivery Note", + "docstatus": 0, + "doctype": "Print Format", + "font": "Default", + "html": "
      \n

      SALES INVOICE / SHIPPING MANIFEST

      \n

      PLEASE USE PERMANENT INK FOR ALL ITEMS

      \n
      \n
      \n
      \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      INVOICE/MANIFEST NUMBER:\n {% set invoices = [] %}\n {% for item in doc.items if item.against_sales_invoice %}\n {% if item.against_sales_invoice not in invoices %}\n {% set __ = invoices.append(item.against_sales_invoice) %}\n {% endif %}\n {% endfor %}\n {{ \",\".join(invoices) }}\n
      SALES ORDER/DELIVERY NOTE:\n {% set orders = [] %}\n {% for item in doc.items if item.against_sales_order %}\n {% if item.against_sales_order not in orders %}\n {% set __ = orders.append(item.against_sales_order) %}\n {% endif %}\n {% endfor %}\n {{ \",\".join(orders) }} / {{ doc.name }}\n
      \n
      \n
      \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      ACTUAL DATE/TIME OF DEPARTURE:{{ doc.lr_date or \"\" }}
      ESTIMATED DATE/TIME OF ARRIVAL:{{ frappe.db.get_value(\"Delivery Stop\", {\"delivery_note\": doc.name}, \"estimated_arrival\") or \"\" }}
      \n
      \n
      \n
      \n
      \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      SHIPPER INFORMATION
      STATE LICENSE #{{ frappe.db.get_value(\"Compliance Info\", { \"entity\": doc.company}, \"license_number\") or \"\" }}
      TYPE OF LICENSE{{ frappe.db.get_value(\"Compliance Info\", { \"entity\": doc.company}, \"license_number\") or \"\" }}
      BUSINESS NAME{{ doc.company or \"\" }}
      BUSINESS ADDRESS{{ frappe.db.get_value(\"Address\", {\"is_your_company_address\": 1}, \"address_line1\") or \"\" }}
      CITY, STATE, ZIP CODE\n {{ frappe.db.get_value(\"Address\", {\"is_your_company_address\": 1}, \"city\") or \"\" }}\n {{ frappe.db.get_value(\"Address\", {\"is_your_company_address\": 1}, \"state\") or \"\" }}\n {{ frappe.db.get_value(\"Address\", {\"is_your_company_address\": 1}, \"pincode\") or \"\" }}\n
      PHONE NUMBER{{ frappe.db.get_value(\"Company\", doc.company, \"phone_no\") or \"\" }}
      CONTACT NAME{{ frappe.db.get_value(\"Company\", doc.company, \"contact_name\") or \"\" }}
      \n
      \n
      \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      RECEIVER INFORMATION
      STATE LICENSE #{{ frappe.db.get_value(\"Compliance Info\", { \"entity\": doc.customer}, \"license_number\") or \"\" }}
      TYPE OF LICENSE{{ frappe.db.get_value(\"Compliance Info\", { \"entity\": doc.customer}, \"license_type\") or \"\" }}
      BUSINESS NAME{{ doc.customer_name or \"\" }}
      DELIVERY ADDRESS{{ frappe.db.get_value(\"Address\", doc.shipping_address_name, \"address_line1\") or \"\" }}
      CITY, STATE, ZIP CODE\n {{ frappe.db.get_value(\"Address\", doc.shipping_address_name, \"city\") or \"\" }}\n {{ frappe.db.get_value(\"Address\", doc.shipping_address_name, \"state\") or \"\" }}\n {{ frappe.db.get_value(\"Address\", doc.shipping_address_name, \"pincode\") or \"\" }}\n
      PHONE NUMBER{{ frappe.db.get_value(\"Address\", doc.shipping_address_name, \"phone\") or \"\" }}
      CONTACT NAME{{ frappe.db.get_value(\"Customer\", doc.customer, \"customer_primary_contact\") or \"\" }}
      \n
      \n
      \n
      \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      DISTRIBUTOR INFORMATION
      STATE LICENSE #{{ frappe.db.get_value(\"Compliance Info\", { \"entity\": doc.company}, \"license_number\") or \"\" }}DRIVER'S NAME{{ doc.driver_name or \"\" }}
      BUSINESS NAME{{ doc.company or \"\" }}CA DRIVER'S LIC. #{{ frappe.db.get_value(\"Driver\", doc.driver, \"license_number\") or \"\" }}
      STREET ADDRESS{{ frappe.db.get_value(\"Address\", {\"is_your_company_address\": 1}, \"address_line1\") or \"\" }}VEHICLE MAKE{{ frappe.db.get_value(\"Vehicle\", doc.vehicle_no, \"make\") or \"\" }}
      CITY, STATE, ZIP\n {{ frappe.db.get_value(\"Address\", {\"is_your_company_address\": 1}, \"city\") or \"\" }}\n {{ frappe.db.get_value(\"Address\", {\"is_your_company_address\": 1}, \"state\") or \"\" }}\n {{ frappe.db.get_value(\"Address\", {\"is_your_company_address\": 1}, \"pincode\") or \"\" }}\n VEHICLE MODEL{{ frappe.db.get_value(\"Vehicle\", doc.vehicle_no, \"model\") or \"\" }}
      PHONE NUMBER{{ frappe.db.get_value(\"Company\", doc.company, \"phone_no\") or \"\" }}VEHICLE LIC. PLATE #{{ frappe.db.get_value(\"Vehicle\", doc.vehicle_no, \"name\") or \"\" }}
      CONTACT NAME{{ frappe.db.get_value(\"Company\", doc.company, \"contact_name\") or \"\" }}ACTUAL TIME OF ARR.:
      \n
      \n
      \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {% for item in doc.items %}\n \n \n \n \n \n \n \n \n \n \n {% endfor %}\n {% if doc.taxes %}\n \n \n \n \n \n \n {% for tax in doc.taxes %}\n \n \n \n \n \n \n {% endfor %}\n {% endif %}\n \n \n \n \n \n \n \n
      \n

      PRODUCT SHIPPED DETAILS

      \n
      UID TAG NUMBER
      (IF APPLICABLE)
      ITEM NAME AND
      PRODUCT DESCRIPTION
      (INCLUDE WEIGHT OR COUNT)
      QTY ORDEREDQTY REC'DUNIT COSTTOTAL COSTRETAIL ONLY
      UNIT VALUETOTAL VALUE
      {{ item.batch_no }}{{ item.item_name }}{{ item.qty }}{{ item.get_formatted(\"rate\", doc) }}{{ item.get_formatted(\"amount\", doc) }}
      SUBTOTAL:{{ doc.get_formatted(\"total\", doc) }}
      {{ tax.description }} {% if tax.rate %} (@{{ tax.rate }}%) {% endif %}:{{ tax.get_formatted(\"tax_amount\", doc) }}
      TOTAL:{{ doc.get_formatted(\"grand_total\", doc) }}
      \n
      \n
      \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
      PRODUCT REJECTION
      IF PRODUCTS ARE REJECTED, PLEASE CIRCLE THE ITEMS BEING REJECTED IN THE PRODUCT SHIPPED DETAILS SECTION\n ABOVE\n
      REASON FOR REJECTION:
      PRODUCT RECEIPT CONFIRMATION
      \n I CONFIRM THAT THE CONTENTS OF THIS SHIPMENT MATCH IN WEIGHT AND COUNT AS INDICATED ABOVE.\n I AGREE TO TAKE CUSTODY OF ALL ITEMS AS INDICATED RECEIVED ABOVE \u2013 AND WHICH ARE NOT CIRCLED.\n THE PRODUCTS CIRCLED ABOVE ARE REJECTED FOR DELIVERY AND REMAIN IN THE CUSTODY OF THE DISTRIBUTOR\n FOR RETURN TO THE SHIPPER AS INDICATED ON THIS FORM AND ALL ATTACHED PRODUCT DETAILS SHEET(S).\n
      NAME OF PERSON RECEIVING AND/OR REJECTING PRODUCT:PHONE NUMBER:
      SIGNATURE OF PERSON RECEIVING AND/OR REJECTING PRODUCT:DATE SIGNED:
      \n
      ", + "idx": 0, + "line_breaks": 0, + "modified": "2019-07-09 03:33:59.121871", + "modified_by": "Administrator", + "module": "Bloomstack Core", + "name": "Shipping Manifest", + "owner": "Administrator", + "print_format_builder": 0, + "print_format_type": "Server", + "show_section_headings": 0, + "standard": "Yes" +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/report/delivered_sales/__init__.py b/bloomstack_core/bloomstack_core/report/delivered_sales/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/bloomstack_core/report/delivered_sales/delivered_sales.js b/bloomstack_core/bloomstack_core/report/delivered_sales/delivered_sales.js new file mode 100644 index 000000000..4679f1a3e --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/delivered_sales/delivered_sales.js @@ -0,0 +1,9 @@ +// Copyright (c) 2016, Bloom Stack, Inc and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["Delivered Sales"] = { + "filters": [ + + ] +} diff --git a/bloomstack_core/bloomstack_core/report/delivered_sales/delivered_sales.json b/bloomstack_core/bloomstack_core/report/delivered_sales/delivered_sales.json new file mode 100644 index 000000000..e134d121e --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/delivered_sales/delivered_sales.json @@ -0,0 +1,21 @@ +{ + "add_total_row": 1, + "creation": "2019-01-23 01:43:06.159270", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "letter_head": "Delta9", + "modified": "2019-07-09 03:18:15.935132", + "modified_by": "Administrator", + "module": "Bloomstack Core", + "name": "Delivered Sales", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Delivery Note", + "report_name": "Delivered Sales", + "report_type": "Script Report", + "roles": [] +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/report/delivered_sales/delivered_sales.py b/bloomstack_core/bloomstack_core/report/delivered_sales/delivered_sales.py new file mode 100644 index 000000000..3059b55ac --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/delivered_sales/delivered_sales.py @@ -0,0 +1,9 @@ +# Copyright (c) 2013, Bloom Stack, Inc and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe + +def execute(filters=None): + columns, data = [], [] + return columns, data diff --git a/bloomstack_core/bloomstack_core/report/driver_collection/__init__.py b/bloomstack_core/bloomstack_core/report/driver_collection/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/bloomstack_core/report/driver_collection/driver_collection.js b/bloomstack_core/bloomstack_core/report/driver_collection/driver_collection.js new file mode 100644 index 000000000..35fcc4cb2 --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/driver_collection/driver_collection.js @@ -0,0 +1,129 @@ +// Copyright (c) 2016, Neil Lasrado and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["Driver Collection"] = { + "filters": [ + { + "fieldname": "driver", + "label": __("Driver"), + "fieldtype": "Link", + "options": "Driver", + "get_query": () => { + return { filters: { "status": "Active" } } + } + }, + { + "fieldname": "date_range", + "label": __("Delivery Date Range"), + "fieldtype": "DateRange", + "default": [frappe.datetime.get_today(), frappe.datetime.get_today()], + "reqd": 1 + }, + { + "fieldname": "period", + "label": __("Delivery Period"), + "fieldtype": "Select", + "options": [ + { "value": "Today", "label": __("Today") }, + { "value": "Last 7 Days", "label": __("Last 7 Days") }, + { "value": "Month to Date", "label": __("Month to Date") }, + { "value": "Last 30 Days", "label": __("Last 30 Days") }, + { "value": "Last 90 Days", "label": __("Last 90 Days") }, + { "value": "Year to Date", "label": __("Year to Date") }, + { "value": "Last 365 Days", "label": __("Last 365 Days") } + ], + "default": "Today", + on_change: () => { + let period = frappe.query_report.get_filter_value('period'); + const now_date = frappe.datetime.nowdate() + + decrement = { + "Today": 0, + "Last 7 Days": 7, + "Month to Date": frappe.datetime.get_day_diff(now_date, frappe.datetime.month_start()), + "Last 30 Days": 30, + "Last 90 Days": 90, + "Year to Date": frappe.datetime.get_day_diff(now_date, frappe.datetime.year_start()), + "Last 365 Days": 365 + }[period] + + frappe.query_report.set_filter_value('date_range', [ + frappe.datetime.add_days(now_date, -decrement), + now_date + ]); + } + }, + { + "fieldname": "show_individual_stops", + "label": __("Show Individual Stops"), + "fieldtype": "Check" + }, + ], + "formatter": function (value, row, column, data, default_formatter) { + value = default_formatter(value, row, column, data); + if (["expected_amount", "total_payment"].includes(column.fieldname) && data) { + // compare values with precision of 2 + if (data.expected_amount.toFixed(2) > data.total_payment.toFixed(2)) { + value = "" + value + ""; + } else { + value = "" + value + ""; + } + } + + return value; + }, + get_chart_data: (columns, result) => { + let results = {} + for (let row of result) { + // Since the total row is last, break loop + if (["Total", "'Total'"].includes(row[0])) { break; }; + + let pending = row.total_payment < row.expected_amount ? row.expected_amount - row.total_payment : 0; + + results[row.driver] = results[row.driver] || { + unprocessed: 0, + processed: 0, + pending: 0 + } + results[row.driver].unprocessed += row.payment_received; + results[row.driver].processed += row.payment_processed; + results[row.driver].pending += pending; + } + + const labels = Object.keys(results); + const values = Object.values(results); + + return { + data: { + labels: labels, + datasets: [ + { + name: "Unprocessed", + values: values.map(row => row.unprocessed), + chartType: "bar" + }, + { + name: "Processed", + values: values.map(row => row.processed), + chartType: "bar" + }, + { + name: "Pending", + values: values.map(row => row.pending), + chartType: "bar" + } + ] + }, + type: "axis-mixed", + colors: ["yellow", "green", "red"], + barOptions: { + spaceRatio: 0.6, + stacked: 1 + }, + tooltipOptions: { + formatTooltipY: d => format_currency(d), + } + } + } +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/report/driver_collection/driver_collection.json b/bloomstack_core/bloomstack_core/report/driver_collection/driver_collection.json new file mode 100644 index 000000000..bd5d293a8 --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/driver_collection/driver_collection.json @@ -0,0 +1,27 @@ +{ + "add_total_row": 1, + "creation": "2018-09-19 06:28:25.125367", + "disable_prepared_report": 1, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "modified": "2019-08-02 08:16:15.785685", + "modified_by": "Administrator", + "module": "Bloomstack Core", + "name": "Driver Collection", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Delivery Trip", + "report_name": "Driver Collection", + "report_type": "Script Report", + "roles": [ + { + "role": "Fulfillment User" + }, + { + "role": "Stock User" + } + ] +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/report/driver_collection/driver_collection.py b/bloomstack_core/bloomstack_core/report/driver_collection/driver_collection.py new file mode 100644 index 000000000..f75f7b7b6 --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/driver_collection/driver_collection.py @@ -0,0 +1,289 @@ +# Copyright (c) 2013, Neil Lasrado and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals + +import frappe +from frappe import _ +from frappe.utils import flt, global_date_format + + +def execute(filters=None): + filters = filters or {} + + columns = get_columns(filters) + data = get_collections(filters.get("date_range"), filters.get("driver"), filters.get("show_individual_stops")) + + return columns, data + + +def get_collections(date_range, driver, show_individual_stops=False): + data = [] + + filters = { + "departure_time": ["between", date_range], + "driver": driver, + "docstatus": 1 + } + + delivery_trips = frappe.get_all("Delivery Trip", filters=filters) + + for trip in delivery_trips: + delivery_trip = frappe.get_doc("Delivery Trip", trip.name) + + sales_invoices = [] + delivery_amount = tax_amount = promotional_amount = unprocessed_amount = processed_amount = paid_amount = returned_amount = cancelled_amount = 0.0 + + for stop in delivery_trip.delivery_stops: + if stop.delivery_note: + # Base amounts + discount_stop_amount = promotional_stop_amount = 0.0 + is_promotional_delivery = frappe.db.get_value("Delivery Note", stop.delivery_note, "new_order_type") == "Promotional" + + if stop.grand_total == 0: + discount_stop_amount = frappe.db.get_value("Delivery Note", stop.delivery_note, "discount_amount") + + if is_promotional_delivery: + promotional_stop_amount = discount_stop_amount + + # TODO: Replace promotional amount with full discount, and breakdown each + # discount as a separate column, if D9 wants to + delivery_stop_amount = stop.grand_total + promotional_stop_amount + + amount_under_terms = get_amount_under_terms(stop.sales_invoice) + tax_stop_amount = get_tax_amount(stop.sales_invoice) if stop.sales_invoice else 0.0 + + # Paid amounts + unprocessed_stop_amount = get_paid_amount(stop.sales_invoice, stop.delivery_note, docstatus=0) + processed_stop_amount = get_paid_amount(stop.sales_invoice, stop.delivery_note, docstatus=1) + paid_stop_amount = unprocessed_stop_amount + processed_stop_amount + + # Returned amounts + returned_stop_amount = abs(frappe.db.get_value("Delivery Note", + {"docstatus": 1, "return_against": stop.delivery_note, "issue_credit_note": 0}, + "sum(grand_total)") or 0) + cancelled_stop_amount = abs(frappe.db.get_value("Delivery Note", + {"docstatus": 1, "return_against": stop.delivery_note, "issue_credit_note": 1}, + "sum(grand_total)") or 0) + + if driver or show_individual_stops: + # Append individual driver collections + data.append({ + "driver": delivery_trip.driver_name, + "delivery_trip": trip.name, + "delivery_date": global_date_format(delivery_trip.departure_time), + "sales_invoices": stop.sales_invoice, + "customer": stop.customer, + "total_amount": delivery_stop_amount, + "tax_amount": tax_stop_amount, + "promotional_amount": promotional_stop_amount, + "amount_under_terms": amount_under_terms, + "cancelled_amount": cancelled_stop_amount, + "expected_amount": stop.grand_total - amount_under_terms - cancelled_stop_amount, + "returned_amount": returned_stop_amount, + "payment_received": unprocessed_stop_amount, + "payment_processed": processed_stop_amount, + "total_payment": paid_stop_amount + }) + else: + delivery_amount += delivery_stop_amount + tax_amount += tax_stop_amount + promotional_amount += promotional_stop_amount + returned_amount += returned_stop_amount + cancelled_amount += cancelled_stop_amount + unprocessed_amount += unprocessed_stop_amount + processed_amount += processed_stop_amount + paid_amount += paid_stop_amount + + if stop.sales_invoice: + sales_invoices.append(stop.sales_invoice) + + if not driver and not show_individual_stops: + # Append cumulative collections for each Trip + amount_under_terms = get_amount_under_terms(sales_invoices) + sales_invoices = ", ".join(sales_invoices) + + data.append({ + "driver": delivery_trip.driver_name, + "delivery_trip": trip.name, + "delivery_date": global_date_format(delivery_trip.departure_time), + "sales_invoices": sales_invoices, + "total_amount": delivery_amount, + "tax_amount": tax_amount, + "promotional_amount": promotional_amount, + "amount_under_terms": amount_under_terms, + "cancelled_amount": cancelled_amount, + "expected_amount": delivery_trip.package_total - amount_under_terms - cancelled_amount, + "returned_amount": returned_amount, + "payment_received": unprocessed_amount, + "payment_processed": processed_amount, + "total_payment": paid_amount + }) + + return data + + +def get_amount_under_terms(invoice): + amount_under_terms = 0.0 + + if not invoice: + return amount_under_terms + + if isinstance(invoice, list): + for inv in invoice: + payment_terms_template, outstanding_amount = frappe.db.get_value( + "Sales Invoice", inv, ["payment_terms_template", "outstanding_amount"]) + + if payment_terms_template: + amount_under_terms += outstanding_amount + else: + payment_terms_template, outstanding_amount = frappe.db.get_value( + "Sales Invoice", invoice, ["payment_terms_template", "outstanding_amount"]) + + if payment_terms_template: + amount_under_terms = outstanding_amount + + return amount_under_terms + + +def get_tax_amount(invoice): + tax_accounts = [account.name for account in frappe.get_all("Account", filters={"account_type": "Tax"})] + + tax_amounts = frappe.get_all("Sales Taxes and Charges", + filters={"parent": invoice, "account_head": ["IN", tax_accounts]}, + fields=["tax_amount"]) + + tax_amount = sum([tax.tax_amount for tax in tax_amounts if tax.tax_amount]) + + return tax_amount + + +def get_paid_amount(sales_invoice, delivery_note, docstatus): + paid_amount = 0.0 + invoices = [] + + if sales_invoice: + invoices = [sales_invoice] + elif delivery_note: + dn_items = frappe.get_all("Delivery Note Item", + filters={"parent": delivery_note}, + fields=["distinct(against_sales_invoice)"]) + + invoices = [item.against_sales_invoice for item in dn_items if item.against_sales_invoice] + + for invoice in invoices: + payments = frappe.get_all("Payment Entry Reference", + filters={"reference_name": invoice, "docstatus": docstatus}, + fields=["distinct(parent)"]) + + for payment in payments: + paid_amount += frappe.db.get_value("Payment Entry", payment.parent, "paid_amount") or 0.0 + + return paid_amount + + +def get_columns(filters): + columns = [ + { + "label": _("Driver"), + "fieldname": "driver", + "fieldtype": "Data", + "width": 150 + }, + { + "label": _("Delivery Trip"), + "fieldname": "delivery_trip", + "fieldtype": "Link", + "options": "Delivery Trip", + "width": 120 + }, + { + "label": _("Delivery Date"), + "fieldname": "delivery_date", + "fieldtype": "Data", + "width": 130 + }, + { + "label": _("Sales Invoice(s)"), + "fieldname": "sales_invoices", + "fieldtype": "Link" if filters.get("show_individual_stops") else "Data", + "options": "Sales Invoice" if filters.get("show_individual_stops") else "", + "width": 150 if filters.get("show_individual_stops") else 200 + } + ] + + if filters.get("driver") or filters.get("show_individual_stops"): + columns.extend([ + { + "label": _("Customer"), + "fieldname": "customer", + "fieldtype": "Link", + "options": "Customer", + "width": 200 + } + ]) + + columns.extend([ + { + "label": _("Total Delivery Value (A)"), + "fieldname": "total_amount", + "fieldtype": "Currency", + "width": 140 + }, + { + "label": _("Taxes Due"), + "fieldname": "tax_amount", + "fieldtype": "Currency", + "width": 100 + }, + { + "label": _("Promotions (B)"), + "fieldname": "promotional_amount", + "fieldtype": "Currency", + "width": 100 + }, + { + "label": _("Amount under Terms (C)"), + "fieldname": "amount_under_terms", + "fieldtype": "Currency", + "width": 140 + }, + { + "label": _("Cancelled Amount (D)"), + "fieldname": "cancelled_amount", + "fieldtype": "Currency", + "width": 100 + }, + { + "label": _("Expected Amount (A - B - C - D)"), + "fieldname": "expected_amount", + "fieldtype": "Currency", + "width": 100 + }, + { + "label": _("Returned Amount"), + "fieldname": "returned_amount", + "fieldtype": "Currency", + "width": 100 + }, + { + "label": _("Payment Received (X)"), + "fieldname": "payment_received", + "fieldtype": "Currency", + "width": 100 + }, + { + "label": _("Payment Processed (Y)"), + "fieldname": "payment_processed", + "fieldtype": "Currency", + "width": 100 + }, + { + "label": _("Total Payment (X + Y)"), + "fieldname": "total_payment", + "fieldtype": "Currency", + "width": 100 + } + ]) + + return columns \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/report/item_wise_sales/__init__.py b/bloomstack_core/bloomstack_core/report/item_wise_sales/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/bloomstack_core/report/item_wise_sales/item_wise_sales.js b/bloomstack_core/bloomstack_core/report/item_wise_sales/item_wise_sales.js new file mode 100644 index 000000000..5b45691a2 --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/item_wise_sales/item_wise_sales.js @@ -0,0 +1,9 @@ +// Copyright (c) 2016, Bloom Stack, Inc and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["Item-wise Sales"] = { + "filters": [ + + ] +} diff --git a/bloomstack_core/bloomstack_core/report/item_wise_sales/item_wise_sales.json b/bloomstack_core/bloomstack_core/report/item_wise_sales/item_wise_sales.json new file mode 100644 index 000000000..ecd57690a --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/item_wise_sales/item_wise_sales.json @@ -0,0 +1,21 @@ +{ + "add_total_row": 1, + "creation": "2018-11-21 01:59:14.304982", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 2, + "is_standard": "Yes", + "letter_head": "Delta9", + "modified": "2019-07-09 03:17:47.502284", + "modified_by": "Administrator", + "module": "Bloomstack Core", + "name": "Item-wise Sales", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Sales Order", + "report_name": "Item-wise Sales", + "report_type": "Script Report", + "roles": [] +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/report/item_wise_sales/item_wise_sales.py b/bloomstack_core/bloomstack_core/report/item_wise_sales/item_wise_sales.py new file mode 100644 index 000000000..3059b55ac --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/item_wise_sales/item_wise_sales.py @@ -0,0 +1,9 @@ +# Copyright (c) 2013, Bloom Stack, Inc and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe + +def execute(filters=None): + columns, data = [], [] + return columns, data diff --git a/bloomstack_core/bloomstack_core/report/macro_sales/__init__.py b/bloomstack_core/bloomstack_core/report/macro_sales/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/bloomstack_core/report/macro_sales/macro_sales.js b/bloomstack_core/bloomstack_core/report/macro_sales/macro_sales.js new file mode 100644 index 000000000..3d185f19a --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/macro_sales/macro_sales.js @@ -0,0 +1,9 @@ +// Copyright (c) 2016, Bloom Stack, Inc and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["Macro Sales"] = { + "filters": [ + + ] +} diff --git a/bloomstack_core/bloomstack_core/report/macro_sales/macro_sales.json b/bloomstack_core/bloomstack_core/report/macro_sales/macro_sales.json new file mode 100644 index 000000000..943e29fb3 --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/macro_sales/macro_sales.json @@ -0,0 +1,21 @@ +{ + "add_total_row": 1, + "creation": "2019-03-25 03:05:05.325011", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "letter_head": "Delta9", + "modified": "2019-07-09 03:18:43.869011", + "modified_by": "Administrator", + "module": "Bloomstack Core", + "name": "Macro Sales", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Quotation", + "report_name": "Macro Sales", + "report_type": "Script Report", + "roles": [] +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/report/macro_sales/macro_sales.py b/bloomstack_core/bloomstack_core/report/macro_sales/macro_sales.py new file mode 100644 index 000000000..3059b55ac --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/macro_sales/macro_sales.py @@ -0,0 +1,9 @@ +# Copyright (c) 2013, Bloom Stack, Inc and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe + +def execute(filters=None): + columns, data = [], [] + return columns, data diff --git a/bloomstack_core/bloomstack_core/report/pending_deliveries/__init__.py b/bloomstack_core/bloomstack_core/report/pending_deliveries/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/bloomstack_core/report/pending_deliveries/pending_deliveries.json b/bloomstack_core/bloomstack_core/report/pending_deliveries/pending_deliveries.json new file mode 100644 index 000000000..ebbe5a970 --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/pending_deliveries/pending_deliveries.json @@ -0,0 +1,32 @@ +{ + "add_total_row": 1, + "creation": "2019-03-28 02:35:53.693315", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "letter_head": "Delta9", + "modified": "2019-07-09 03:19:02.218192", + "modified_by": "Administrator", + "module": "Bloomstack Core", + "name": "Pending Deliveries", + "owner": "Administrator", + "prepared_report": 0, + "query": "SELECT\n dt.name AS \"Delivery Trip:Link/Delivery Trip:100\",\n dt.status AS \"Status::100\",\n ds.customer AS \"Customer:Link/Customer:150\",\n ds.sales_invoice AS \"Sales Invoice:Link/Sales Invoice:150\",\n ds.grand_total AS \"Delivery Amount:Currency:100\",\n dt.driver_name AS \"Driver::150\",\n dt.departure_time AS \"Departure Time:Date:150\",\n dn.territory AS \"Territory:Link/Territory:100\"\nFROM\n `tabDelivery Trip` AS dt\n JOIN `tabDelivery Stop` ds ON dt.name = ds.parent\n JOIN `tabDelivery Note` dn ON ds.delivery_note = dn.name\nWHERE\n dt.docstatus = 1\n AND dt.status IN (\"Scheduled\", \"In Transit\")\n AND dt.creation BETWEEN %(from_date)s AND %(to_date)s\n AND ds.visited = 0\nORDER BY\n dt.departure_time asc", + "ref_doctype": "Delivery Trip", + "report_name": "Pending Deliveries", + "report_type": "Query Report", + "roles": [ + { + "role": "Fulfillment User" + }, + { + "role": "Stock User" + }, + { + "role": "Driver" + } + ] +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/report/sales_summary/__init__.py b/bloomstack_core/bloomstack_core/report/sales_summary/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/bloomstack_core/report/sales_summary/sales_summary.js b/bloomstack_core/bloomstack_core/report/sales_summary/sales_summary.js new file mode 100644 index 000000000..782452e39 --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/sales_summary/sales_summary.js @@ -0,0 +1,9 @@ +// Copyright (c) 2016, Bloom Stack, Inc and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["Sales Summary"] = { + "filters": [ + + ] +} diff --git a/bloomstack_core/bloomstack_core/report/sales_summary/sales_summary.json b/bloomstack_core/bloomstack_core/report/sales_summary/sales_summary.json new file mode 100644 index 000000000..8270764eb --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/sales_summary/sales_summary.json @@ -0,0 +1,21 @@ +{ + "add_total_row": 1, + "creation": "2019-01-24 01:00:50.590728", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 2, + "is_standard": "Yes", + "letter_head": "Delta9", + "modified": "2019-07-09 03:18:30.599151", + "modified_by": "Administrator", + "module": "Bloomstack Core", + "name": "Sales Summary", + "owner": "Administrator", + "prepared_report": 0, + "ref_doctype": "Sales Order", + "report_name": "Sales Summary", + "report_type": "Script Report", + "roles": [] +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/report/sales_summary/sales_summary.py b/bloomstack_core/bloomstack_core/report/sales_summary/sales_summary.py new file mode 100644 index 000000000..3059b55ac --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/sales_summary/sales_summary.py @@ -0,0 +1,9 @@ +# Copyright (c) 2013, Bloom Stack, Inc and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe + +def execute(filters=None): + columns, data = [], [] + return columns, data diff --git a/bloomstack_core/bloomstack_core/report/stale_quotations/__init__.py b/bloomstack_core/bloomstack_core/report/stale_quotations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/bloomstack_core/report/stale_quotations/stale_quotations.js b/bloomstack_core/bloomstack_core/report/stale_quotations/stale_quotations.js new file mode 100644 index 000000000..bda772219 --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/stale_quotations/stale_quotations.js @@ -0,0 +1,9 @@ +// Copyright (c) 2016, Bloom Stack, Inc and contributors +// For license information, please see license.txt +/* eslint-disable */ + +frappe.query_reports["Stale Quotations"] = { + "filters": [ + + ] +} diff --git a/bloomstack_core/bloomstack_core/report/stale_quotations/stale_quotations.json b/bloomstack_core/bloomstack_core/report/stale_quotations/stale_quotations.json new file mode 100644 index 000000000..c1a77de39 --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/stale_quotations/stale_quotations.json @@ -0,0 +1,22 @@ +{ + "add_total_row": 0, + "creation": "2018-10-26 01:06:02.571304", + "disable_prepared_report": 0, + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 1, + "is_standard": "Yes", + "letter_head": "Delta9", + "modified": "2019-07-09 03:17:27.326247", + "modified_by": "Administrator", + "module": "Bloomstack Core", + "name": "Stale Quotations", + "owner": "Administrator", + "prepared_report": 0, + "query": "", + "ref_doctype": "Quotation", + "report_name": "Stale Quotations", + "report_type": "Script Report", + "roles": [] +} \ No newline at end of file diff --git a/bloomstack_core/bloomstack_core/report/stale_quotations/stale_quotations.py b/bloomstack_core/bloomstack_core/report/stale_quotations/stale_quotations.py new file mode 100644 index 000000000..3059b55ac --- /dev/null +++ b/bloomstack_core/bloomstack_core/report/stale_quotations/stale_quotations.py @@ -0,0 +1,9 @@ +# Copyright (c) 2013, Bloom Stack, Inc and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe + +def execute(filters=None): + columns, data = [], [] + return columns, data diff --git a/bloomstack_core/compliance/doctype/waste_disposal/waste_disposal.py b/bloomstack_core/compliance/doctype/waste_disposal/waste_disposal.py index eb64123cc..ed8b576b7 100644 --- a/bloomstack_core/compliance/doctype/waste_disposal/waste_disposal.py +++ b/bloomstack_core/compliance/doctype/waste_disposal/waste_disposal.py @@ -18,7 +18,8 @@ class WasteDisposal(Document): @frappe.whitelist() def create_stock_entry_for_waste_disposal(doc): - doc = frappe._dict(json.loads(doc)) + if isinstance(doc, str): + doc = frappe._dict(json.loads(doc)) stock_entry = get_mapped_doc("Waste Disposal", doc.name, { "Waste Disposal": { diff --git a/bloomstack_core/hook_events/contract.py b/bloomstack_core/hook_events/contract.py new file mode 100644 index 000000000..0a5784ee4 --- /dev/null +++ b/bloomstack_core/hook_events/contract.py @@ -0,0 +1,71 @@ +import frappe +from erpnext.controllers.accounts_controller import get_payment_terms +from frappe import _ +from frappe.model.mapper import get_mapped_doc +from frappe.utils import add_days, getdate, now + + +def create_project_against_contract(contract, method): + if not contract.project_template: + return + + if not contract.is_signed: + return + + # Get the tasks for the project + project_tasks = [] + base_date = getdate(now()) + project_template = frappe.get_doc("Project Template", contract.project_template) + + for task in project_template.tasks: + project_tasks.append({ + "title": task.task_name, + "start_date": add_days(base_date, task.days_to_task_start) if task.days_to_task_start else None, + "end_date": add_days(base_date, task.days_to_task_end) if task.days_to_task_end else None, + "task_weight": task.weight, + "description": task.description + }) + + # Get project and party details + project_name = "{} - {}".format(contract.party_name, project_template.template_name) + if frappe.db.exists("Project", project_name): + count = len(frappe.get_all("Project", filters={"name": ["like", "%{}%".format(project_name)]})) + project_name = "{} - {}".format(project_name, count) + + expected_start_date = min([task.get("start_date") for task in project_tasks if task.get("start_date")]) + expected_end_date = max([task.get("end_date") for task in project_tasks if task.get("end_date")]) + + project = frappe.new_doc("Project") + project.update({ + "project_name": project_name, + "expected_start_date": expected_start_date, + "expected_end_date": expected_end_date, + "customer": contract.party_name if contract.party_type == "Customer" else None, + "tasks": project_tasks + }) + project.insert() + + # Link the contract with the project + contract.db_set("project", project.name) + + +def create_order_against_contract(contract, method): + def set_missing_values(source, target): + target.delivery_date = frappe.db.get_value("Project", contract.project, "expected_end_date") + target.append("items", { + "item_code": source.payment_item, + "qty": 1, + "rate": frappe.db.get_value("Item", source.payment_item, "standard_rate") + }) + + if contract.party_type == "Customer": + sales_order = get_mapped_doc("Contract", contract.name, { + "Contract": { + "doctype": "Sales Order", + "field_map": { + "party_name": "customer" + } + } + }, postprocess=set_missing_values) + sales_order.save() + sales_order.submit() diff --git a/bloomstack_core/hook_events/delivery_note.py b/bloomstack_core/hook_events/delivery_note.py new file mode 100644 index 000000000..87f20f561 --- /dev/null +++ b/bloomstack_core/hook_events/delivery_note.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2019, Bloom Stack and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals + +import frappe +from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice +from frappe import _ +from frappe.utils import get_link_to_form + + +def link_invoice_against_delivery_note(delivery_note, method): + for item in delivery_note.items: + if item.against_sales_order and not item.against_sales_invoice: + sales_invoice = frappe.get_all("Sales Invoice Item", + filters={"docstatus": 1, "sales_order": item.against_sales_order}, + fields=["distinct(parent)"]) + + if sales_invoice and len(sales_invoice) == 1: + item.against_sales_invoice = sales_invoice[0].parent + + +def make_sales_invoice_for_delivery(delivery_note, method): + if not frappe.db.get_single_value("Accounts Settings", "auto_create_invoice_on_delivery_note_submit"): + return + + # If the delivery is already billed, don't create a Sales Invoice + if delivery_note.per_billed == 100: + return + + # Picking up sales orders for 2 reasons: + # 1. A Delivery Note can be made against multiple orders, so they all need to be invoiced + # 2. Using the `make_sales_invoice` in `delivery_note.py` doesn't consider already invoiced orders + sales_orders = [item.against_sales_order for item in delivery_note.items if item.against_sales_order] + sales_orders = list(set(sales_orders)) + + new_invoices = [] + for order in sales_orders: + invoice = make_sales_invoice(order) + + if len(invoice.items) > 0: + invoice.set_posting_time = True + invoice.posting_date = delivery_note.posting_date + invoice.posting_time = delivery_note.posting_time + + invoice.save() + invoice.submit() + + new_invoices.append(get_link_to_form("Sales Invoice", invoice.name)) + + if new_invoices: + new_invoices = ", ".join(str(invoice) for invoice in new_invoices) + frappe.msgprint(_("The following Sales Invoice(s) were automatically created: {0}".format(new_invoices))) diff --git a/bloomstack_core/hook_events/delivery_trip.py b/bloomstack_core/hook_events/delivery_trip.py new file mode 100644 index 000000000..c0425ba6b --- /dev/null +++ b/bloomstack_core/hook_events/delivery_trip.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Bloom Stack and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals + +from requests.utils import quote + +import frappe +from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry +from erpnext.accounts.doctype.sales_invoice.sales_invoice import get_bank_cash_account +from erpnext.accounts.party import get_due_date +from frappe.utils import flt, nowdate, today + + +def generate_directions_url(delivery_trip, method): + if method == "validate": + if not frappe.db.get_single_value("Google Maps Settings", "enabled"): + return + + if delivery_trip.delivery_stops: + route_list = delivery_trip.form_route_list(optimize=False) + + if not route_list: + return + + route_list = route_list[0] + + context = { + "key": frappe.db.get_single_value("Google Maps Settings", "client_key"), + "origin": quote(route_list[0], safe=''), + "destination": quote(route_list[-1], safe=''), + "waypoints": quote('|'.join(route_list[1:-1]), safe='') + } + + map_data = frappe.render_template("templates/includes/google_maps_embed.html", context) + delivery_trip.map_embed = map_data + + +def link_invoice_against_trip(delivery_trip, method): + for delivery_stop in delivery_trip.delivery_stops: + if delivery_stop.delivery_note: + sales_invoice = frappe.get_all("Delivery Note Item", filters={"docstatus":1, "parent": delivery_stop.delivery_note},fields=["distinct(against_sales_invoice)"]) + if sales_invoice and len(sales_invoice)==1: + delivery_stop.sales_invoice = sales_invoice[0].against_sales_invoice + + +@frappe.whitelist() +def make_payment_entry(payment_amount, sales_invoice, delivery_trip): + payment_entry = get_payment_entry("Sales Invoice", sales_invoice, party_amount=flt(payment_amount)) + payment_entry.paid_amount = payment_amount + + territory = frappe.db.get_value("Sales Invoice", sales_invoice, "territory") + mode_of_payment = frappe.db.get_value("Territory", territory, "mode_of_payment") or "Cash" + + payment_entry.mode_of_payment = mode_of_payment + account = get_bank_cash_account(payment_entry.mode_of_payment, payment_entry.company) + if account: + payment_entry.paid_to = account.get("account") + payment_entry.reference_date = today() + payment_entry.reference_no = delivery_trip + payment_entry.flags.ignore_permissions = True + payment_entry.save() + + return payment_entry.name + + +@frappe.whitelist() +def update_payment_due_date(sales_invoice): + invoice = frappe.get_doc("Sales Invoice", sales_invoice) + + if not invoice.payment_terms_template: + return + + due_date = get_due_date(invoice.posting_date, "Customer", invoice.customer, bill_date=frappe.utils.add_days(nowdate(), 7)) + + # Update due date in both parent and child documents + invoice.due_date = due_date + for term in invoice.payment_schedule: + term.due_date = due_date + + invoice.save() + + +def set_vehicle_last_odometer_value(trip, method): + if trip.actual_distance_travelled: + frappe.db.set_value('Vehicle', trip.vehicle, 'last_odometer', trip.odometer_stop_value) diff --git a/bloomstack_core/hook_events/item.py b/bloomstack_core/hook_events/item.py new file mode 100644 index 000000000..d0fe13d44 --- /dev/null +++ b/bloomstack_core/hook_events/item.py @@ -0,0 +1,45 @@ +import json + +import frappe +from bloomstack_core.utils import get_abbr +from erpnext import get_default_company +from erpnext.accounts.utils import get_company_default + + +@frappe.whitelist() +def autoname_item(item): + item = frappe._dict(json.loads(item)) + item_code = autoname(item) + + return item_code + + +def autoname(item, method=None): + """ + Item Code = a + b + c + d + e, where + a = abbreviated Company; all caps. + b = abbreviated Brand; all caps. + c = abbreviated Item Group; all caps. + d = abbreviated Item Name; all caps. + e = variant ID number; has to be incremented. + """ + + # Get abbreviations + company_abbr = get_company_default(get_default_company(), "abbr") + brand_abbr = get_abbr(item.brand, max_length=len(company_abbr)) + brand_abbr = brand_abbr if company_abbr != brand_abbr else None + item_group_abbr = get_abbr(item.item_group) + item_name_abbr = get_abbr(item.item_name, 3) + + params = list(filter(None, [company_abbr, brand_abbr, item_group_abbr, item_name_abbr])) + item_code = "-".join(params) + + # Get count + count = len(frappe.get_all("Item", filters={"name": ["like", "%{}%".format(item_code)]})) + count = "{:04d}".format(count + 1) + + # Set item document name + item_code = "-".join([item_code, count]) + item.name = item.item_code = item_code + + return item_code diff --git a/bloomstack_core/hook_events/packing_slip.py b/bloomstack_core/hook_events/packing_slip.py new file mode 100644 index 000000000..bfa0b437a --- /dev/null +++ b/bloomstack_core/hook_events/packing_slip.py @@ -0,0 +1,33 @@ +import frappe +from frappe.model.mapper import get_mapped_doc + + +def create_stock_entry(packing_slip_doc, method, target_doc = None): + def set_missing_values(source, target): + target.purpose = "Material Transfer" + target.company = frappe.db.get_value("Delivery Note", source.delivery_note, "company") + packing_warehouse = frappe.db.get_single_value("Delivery Settings", "packing_warehouse") + + for item in target.items: + if not item.t_warehouse: + item.t_warehouse = packing_warehouse + + doc = get_mapped_doc("Packing Slip", packing_slip_doc.name, { + "Packing Slip": { + "doctype": "Stock Entry", + "validation": { + "docstatus": ["=", 1] + } + }, + "Packing Slip Item": { + "doctype": "Stock Entry Detail", + "field_map": { + "serial_no": "serial_no", + "batch_no": "batch_no", + "source_warehouse": "s_warehouse", + "target_warehouse": "t_warehouse" + }, + } + }, target_doc, set_missing_values) + doc.save() + doc.submit() diff --git a/bloomstack_core/hook_events/sales_invoice.py b/bloomstack_core/hook_events/sales_invoice.py new file mode 100644 index 000000000..7775cf0e7 --- /dev/null +++ b/bloomstack_core/hook_events/sales_invoice.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2019, Bloom Stack and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals + +import frappe + + +def set_invoice_status(sales_invoice, method): + sales_invoice.set_status() + sales_invoice.set_indicator() \ No newline at end of file diff --git a/bloomstack_core/hooks.py b/bloomstack_core/hooks.py index 376d0a103..6d4eef15f 100755 --- a/bloomstack_core/hooks.py +++ b/bloomstack_core/hooks.py @@ -54,9 +54,15 @@ "User": "public/js/user.js", "Customer": "public/js/customer.js", "Company": "public/js/company.js", + "Delivery Note": "public/js/delivery_note.js", + "Delivery Trip": "public/js/delivery_trip.js", "Supplier": "public/js/supplier.js", "Item": "public/js/item.js", - "Batch": "public/js/batch.js" + "Batch": "public/js/batch.js", + "Quotation": "public/js/quotation.js", + "Contract": "public/js/contract.js", + "Delivery Trip": "public/js/delivery_trip.js", + "Packing Slip": "public/js/packing_slip.js" } # doctype_list_js = {"doctype" : "public/js/doctype_list.js"} # doctype_tree_js = {"doctype" : "public/js/doctype_tree.js"} @@ -111,11 +117,40 @@ # Hook on document methods and events doc_events = { + "Item": { + "autoname": "bloomstack_core.hook_events.item.autoname" + }, + "Contract": { + "on_update_after_submit": [ + "bloomstack_core.hook_events.contract.create_project_against_contract", + "bloomstack_core.hook_events.contract.create_order_against_contract" + ] + }, + "Delivery Note": { + "validate": "bloomstack_core.hook_events.delivery_note.link_invoice_against_delivery_note", + "before_submit": [ + "bloomstack_core.hook_events.delivery_note.make_sales_invoice_for_delivery", + "bloomstack_core.hook_events.delivery_note.link_invoice_against_delivery_note" + ] + }, + "Delivery Trip": { + "validate": [ + "bloomstack_core.hook_events.delivery_trip.generate_directions_url", + "bloomstack_core.hook_events.delivery_trip.link_invoice_against_trip" + ], + "on_update_after_submit": "bloomstack_core.hook_events.delivery_trip.set_vehicle_last_odometer_value" + }, "Purchase Receipt": { - "on_submit": "bloomstack_core.hook_events.purchase_receipt.set_package_tags", + "on_submit": "bloomstack_core.hook_events.purchase_receipt.set_package_tags" + }, + "Sales Invoice": { + "before_update_after_submit": "bloomstack_core.hook_events.sales_invoice.set_invoice_status" }, "Stock Entry": { "on_submit": "bloomstack_core.compliance.package.create_package" + }, + "Packing Slip": { + "on_submit": "bloomstack_core.hook_events.packing_slip.create_stock_entry" } } diff --git a/bloomstack_core/public/build.json b/bloomstack_core/public/build.json new file mode 100644 index 000000000..2a4d0b5a5 --- /dev/null +++ b/bloomstack_core/public/build.json @@ -0,0 +1,5 @@ +{ + "js/chart.js": [ + "node_modules/chart.js/dist/Chart.min.js" + ] +} diff --git a/bloomstack_core/public/css/insight_engine.css b/bloomstack_core/public/css/insight_engine.css new file mode 100644 index 000000000..456c4e235 --- /dev/null +++ b/bloomstack_core/public/css/insight_engine.css @@ -0,0 +1,149 @@ +.row { margin: 0; } + +.wrapper { + width: 100%; + margin: 30px auto; +} + +.page-title, +.page-actions { + padding-right: 0; + padding-left: 0; +} + +.revenue-section .row { margin: 20px 0; } + +.revenue-section .container { + width: 100%; + padding: 20px; + border-radius: 15px; + box-shadow: 0 1px 6px #bfbdbd; + display: inline-block; + vertical-align: top; +} + +.revenue-section .row .col-md-4:first-of-type { padding-left: 0; } + +.revenue-section .row .col-md-4:last-of-type { padding-right: 0; } + +.revenue-section .container span { display: block; } + +.revenue-section .container .amount { + color: #707070; + font-size: 22px; + font-weight: 700; +} + +.revenue-section .container .name { + margin-top: 7px; + color: #8c8c8c; + font-size: 15px; +} + +.revenue-section .container .description { + margin-top: 7px; + color: #8c8c8c; + font-size: 10px; +} + +.canvas { + height: 80vh; + width: 80vw; +} + +.parent-container .row { display: flex; } + +.chart-container, +.graphical-distribution { + border-radius: 15px; + box-shadow: 0 1px 6px #bfbdbd; +} + +.chart-container .row, +.graphical-distribution .row { + margin: 0; + display: block; +} + +.parent-container .row [class*="col-"] { + padding: 0; + border-radius: 15px; + margin: 0 15px; + box-shadow: 0 1px 6px #bfbdbd; + flex: 1; +} + +.category-product-info .row .donut-chart, +.sales-partner-info .row .bar-data { margin-left: 0; } + +.category-product-info .row .table-data, +.sales-partner-info .row .donut-chart { margin-right: 0; } + +.parent-container { margin: 30px 0; } + +.parent-container .section-heading p { margin: 0; } + +.parent-container .section-heading { + border-top-left-radius: 15px; + border-top-right-radius: 15px; + background: #474650; +} + +.parent-container .graphics { + border-bottom-right-radius: 15px; + border-bottom-left-radius: 15px; +} + +.parent-container .section-heading p { + margin: 0; + font-size: 16px; +} + +.parent-container .section-heading p.heading { + margin: 15px 0 15px 20px; + display: inline-block; + color: #fff; +} + +.parent-container .section-heading p.heading span { font-size: 12px; } + +.parent-container .section-heading p.duration { + margin: 15px 20px 15px 0; + float: right; + color: #fff; +} + +.parent-container .table-data table th, +.parent-container .table-data table td { + padding: 5px 20px; + font-size: 11px; +} + +.parent-container .table-data table th { height: 50px; } + +.parent-container .table-data table tbody tr:last-of-type { + height: 50px; + vertical-align: top; +} + +@media only screen and (max-width: 991px) { + .revenue-section .row { margin: 0; } + + .revenue-section .col-xs-12 { + padding: 0; + margin: 15px 0; + } + + .parent-container { margin: 15px 0; } + + .parent-container .row { + margin: 0; + display: block; + } + + .parent-container .row [class*="col-"] { margin: 15px 0; } +} + +@media only screen and (max-width: 767px) { + .page-title { padding-left: 15px; } +} \ No newline at end of file diff --git a/bloomstack_core/public/css/track_and_trace.css b/bloomstack_core/public/css/track_and_trace.css new file mode 100644 index 000000000..4c9adabfe --- /dev/null +++ b/bloomstack_core/public/css/track_and_trace.css @@ -0,0 +1,314 @@ + +#track-and-trace .intro { + padding: 1rem 2rem; +} + +#track-and-trace .results { + padding: 5px 18px; +} + +#track-and-trace .results li, +#track-and-trace .results ul { + list-style: none; + margin: 0; + padding: 0; +} + +#track-and-trace .node h2 { + padding: 0; + margin: 0 0 15px 0; + display: flex; + flex-direction: row; + align-items: center; +} + +#track-and-trace .node h2 .title { + flex: 1 1 auto; + margin-left: 5px; +} + +#track-and-trace .results .node .doctype-link { + font-size: .7em; + margin-left: 10px; + padding: 0 5px; + cursor: pointer; +} + +#track-and-trace .node h2 > .actions { + flex: 0 0 auto; + align-self: flex-end; +} + +/* field collapse chevron setup */ +#track-and-trace .node > .item > .leaf > .content h2 > .actions > .field-collapse { + cursor: pointer; +} + +#track-and-trace .node > .item > .leaf > .content h2 > .actions > .field-collapse > .if-open { + display: inline-block; +} + +#track-and-trace .node > .item > .leaf > .content h2 > .actions > .field-collapse > .if-closed { + display: none; +} + +#track-and-trace .node.hide-fields > .item > .leaf > .content h2 > .actions > .field-collapse > .if-open { + display: none; +} + +#track-and-trace .node.hide-fields > .item > .leaf > .content h2 > .actions > .field-collapse > .if-closed { + display: inline-block; +} + + +#track-and-trace .node { + list-style: none; + margin: 0; + padding: 0; + display: flex; + flex-direction: row; +} + +#track-and-trace .node > .item { + display: flex; + flex-direction: column; + flex: 1 1 auto; +} + +/* Leaf container setup */ +#track-and-trace .node > .item > .leaf { + display: flex; + flex-direction: row; +} + +#track-and-trace .node > .item > .leaf:hover { + background-color: rgb(220, 226, 226); +} + +#track-and-trace .node > .item > .leaf > .branch { + display: flex; + flex-direction: column; +} + +/* node handle setup */ +#track-and-trace .node > .item > .leaf > .branch > .node-handle { + height: 14px; +} + +#track-and-trace .node > .item > .leaf > .branch > .node-handle > i { + width: 16px; + height: 14px; + flex: 0 0 auto; +} + +#track-and-trace .node.has-children > .item > .leaf > .content > .node-handle { + cursor: pointer; +} + +#track-and-trace .node.open > .item > .leaf > .branch > .node-handle > i.if-open { + display: inline-block; +} + +#track-and-trace .node > .item > .leaf > .branch > .node-handle > i.if-open { + display: none; +} + +#track-and-trace .node.open > .item > .leaf > .branch > .node-handle > i.if-closed { + display: none; +} + +#track-and-trace .node > .item > .leaf > .branch > .node-handle > i.if-closed { + display: inline-block; +} + +/* Details section setup */ +#track-and-trace .details { + display: flex; + margin-bottom: 15px; +} + +#track-and-trace .node.hide-fields > .item > .leaf > .content > .details { + display: none; +} + +/* Image is left align static flex box */ +#track-and-trace .details > img { + flex: 0 0 auto; + margin: 5px; + height: 80px; +} + +/* field ul container is a dynamic stretch flex fox */ +#track-and-trace .details > ul { + flex: 1 1 auto; + column-count: 3; + margin: 0; + padding: 0; +} + +#track-and-trace .details > ul > li { + margin: 0; + padding: 0; + list-style: none; +} + +#track-and-trace .details > ul > li .field { + font-weight: bold; +} + +#track-and-trace .details > ul > li .value { + white-space: nowrap; +} + +#track-and-trace .node > .item > .leaf > .branch { + position: relative; + display: flex; + flex-direction: column; + min-width: 16px; + flex: 0 0 auto; + align-items: flex-end; +} + +#track-and-trace .node > .item > .leaf > .content { + flex: 1 1 auto; +} + +/* crazy tree branching setup */ +#track-and-trace .node.has-children > .item > .leaf > .branch::after { + width: 16px; +} + +#track-and-trace .node.has-children.open > .item > .leaf > .branch::after { + background-image: url('/assets/bloomstack_core/images/tree-sprite.png'); + background-repeat: repeat-y; + content: ''; + flex: 1 1 auto; + background-position-x: 64px; +} + +#track-and-trace .node-padding { + display: flex; + flex-direction: column; +} + +#track-and-trace .node.open.has-children > .item > .children > .node > .node-padding > span { + background-image: url('/assets/bloomstack_core/images/tree-sprite.png'); + background-repeat: repeat-y; + display: block; + width: 16px; + flex: 1 1 auto; +} + +#track-and-trace .node.open.has-children > .item > .children > .node.is-last > .node-padding > span:first-child { + flex: 0 0 auto; +} + +#track-and-trace .node.open.has-children:not(.is-last) > .item > .children > .node > .node-padding > span { + flex: 1 1 auto; + background-position-x: 0; + background-repeat: repeat-y; +} + +#track-and-trace .node.open.has-children > .item > .children > .node > .node-padding > span:first-child { + height: 16px; + background-position-x: -16px; + flex: 0 0 auto; +} + +#track-and-trace .node.open.has-children > .item > .children > .node.is-last > .node-padding > span:first-child { + background-position-x: -32px; +} + +#track-and-trace .node.open.has-children > .item > .children > .node > .node-padding > span:not(:first-child) { + background-position-x: 0px; +} + +#track-and-trace .node.open.has-children > .item > .children > .node.is-last > .node-padding > span:not(:first-child) { + background-image: none; +} + +#track-and-trace .node.open.has-children > .item > .leaf > .branch::after { + background-image: url('/assets/bloomstack_core/images/tree-sprite.png'); + background-repeat: repeat-y; + background-position-x: 0; + display: block; + content: ''; + width: 16px; + flex: 1 1 auto; +} + +/* search section fixed setup, reserve search bar height to push content away from bottom + of search bar. */ +#track-and-trace > div:first-child { + height: 40px; +} + +#track-and-trace #search-bar { + position: fixed; + background: #f5f7fa; + z-index: 1; + margin: 0; + padding: 0; +} + +/* because we can't use boostrap container(due to frappe parent padding) we define + breakpoints for search bar manually */ +@media (min-width: 576px) { + #track-and-trace #search-bar { + max-width: 576px; + } +} + +@media (min-width: 768px) { + #track-and-trace #search-bar { + max-width: 718px; + } +} + +@media (min-width: 992px) { + #track-and-trace #search-bar { + max-width: 938px; + } +} + +@media (min-width: 1200px) { + #track-and-trace #search-bar { + max-width: 1138px; + } +} + +/* Paginator widget setup */ +#track-and-trace .paginator { + list-style: none; + display: flex; + flex-direction: row; + margin: 0; + padding: 0; + align-items: center; +} + +#track-and-trace .paginator li { + list-style: none; + margin: 0 2px; +} + +#track-and-trace .paginator .pagination-target { + padding-left: 0; + padding-right: 0; +} + +#track-and-trace .paginator .pagination-target .list-item__content { + margin-right: 0; +} + +#track-and-trace .paginator .pagination-target input { + width: 5rem; +} + +#track-and-trace .positive { + color: #55b7b3; +} + +#track-and-trace .negative { + color: #ce2b2b; +} \ No newline at end of file diff --git a/bloomstack_core/public/images/desk.png b/bloomstack_core/public/images/desk.png old mode 100755 new mode 100644 index e5f998140..90fa479be Binary files a/bloomstack_core/public/images/desk.png and b/bloomstack_core/public/images/desk.png differ diff --git a/bloomstack_core/public/images/tree-sprite.png b/bloomstack_core/public/images/tree-sprite.png new file mode 100644 index 000000000..ba06c9f06 Binary files /dev/null and b/bloomstack_core/public/images/tree-sprite.png differ diff --git a/bloomstack_core/public/js/conf.js b/bloomstack_core/public/js/conf.js index 3348dc330..37dacbd6e 100755 --- a/bloomstack_core/public/js/conf.js +++ b/bloomstack_core/public/js/conf.js @@ -24,8 +24,8 @@ $(document).bind('toolbar_setup', () => { .insertAfter($help_menu) // replace Report Issue menu item - const $report_issue_menu_item = $(`
    • ${__('Contact Support')}
    • `) - .click(report_issue) + const $report_issue_menu_item = $(`
    • ${__('Contact Support')}
    • `) + // .click(report_issue) .insertAfter($bcc_site); // link to Growth Guide diff --git a/bloomstack_core/public/js/contract.js b/bloomstack_core/public/js/contract.js new file mode 100644 index 000000000..93d368b92 --- /dev/null +++ b/bloomstack_core/public/js/contract.js @@ -0,0 +1,61 @@ +frappe.ui.form.on("Contract", { + refresh: (frm) => { + // Make "Signed" field read-only if a project is created against it + frm.toggle_enable("is_signed", !(frm.doc.is_signed && frm.doc.project)); + + if (!frm.is_new() && frm.doc.docstatus === 0) { + if (!frm.doc.customer_signature) { + frm.add_custom_button(__("Authorize"), () => { + frappe.prompt([ + { + "label": "Contact Email", + "fieldtype": "Data", + "options": "Email", + "fieldname": "contact_email", + "default": frm.doc.party_user, + "reqd": 1 + }, + { + "label": "Contact Person", + "fieldtype": "Data", + "fieldname": "contact_person", + "default": frm.doc.party_name + } + ], + function (data) { + frappe.call({ + method: "bloomstack_core.utils.create_authorization_request", + args: { + dt: frm.doc.doctype, + dn: frm.doc.name, + contact_email: data.contact_email, + contact_name: data.contact_person + }, + callback: (r) => { + if (!r.exc) { + frappe.msgprint(__(`${frm.doc.name} has been successfully sent to ${data.contact_email}`)) + } + } + }) + }, + __("Send Authorization Request")) + }).addClass("btn-primary"); + + } + } + }, + + payment_terms_template: (frm) => { + if (frm.doc.payment_terms_template) { + frappe.model.with_doc("Payment Terms Template", frm.doc.payment_terms_template, function () { + var tabletransfer = frappe.model.get_doc("Payment Terms Template", frm.doc.payment_terms_template); + + frm.doc.payment_terms = []; + $.each(tabletransfer.terms, function (index, row) { + frm.add_child("payment_terms", row); + frm.refresh_field("payment_terms"); + }); + }); + } + } +}); \ No newline at end of file diff --git a/bloomstack_core/public/js/customer.js b/bloomstack_core/public/js/customer.js index 2a56465b8..7a6ffc404 100644 --- a/bloomstack_core/public/js/customer.js +++ b/bloomstack_core/public/js/customer.js @@ -1,4 +1,8 @@ frappe.ui.form.on("Customer", { + setup: (frm) => { + frm.set_query("territory", { "is_group": 0 }); + }, + refresh: (frm) => { if (!frm.is_new()) { frm.add_custom_button(__("License Info"), () => { diff --git a/bloomstack_core/public/js/delivery_note.js b/bloomstack_core/public/js/delivery_note.js new file mode 100644 index 000000000..a1a7bb0e0 --- /dev/null +++ b/bloomstack_core/public/js/delivery_note.js @@ -0,0 +1,12 @@ +frappe.ui.form.on('Delivery Note', { + refresh: (frm) => { + if (frm.doc.is_return) { + // Default all returns to be issued with credit notes + frm.doc.issue_credit_note = 1; + + // Change label for warehouse fields in case of returns + frm.set_df_property("set_warehouse", "label", "Set Return Warehouse"); + frm.toggle_display("to_warehouse"); + } + } +}); \ No newline at end of file diff --git a/bloomstack_core/public/js/delivery_trip.js b/bloomstack_core/public/js/delivery_trip.js new file mode 100644 index 000000000..f52de3acc --- /dev/null +++ b/bloomstack_core/public/js/delivery_trip.js @@ -0,0 +1,152 @@ +frappe.ui.form.on('Delivery Trip', { + refresh: (frm) => { + if (frm.doc.docstatus == 1 && frm.doc.status != "Completed") { + if (frm.doc.odometer_start_value == 0) { + frm.add_custom_button(__("Start"), () => { + frappe.prompt({ + "label": "Odometer Start Value", + "fieldtype": "Int", + "fieldname": "odometer_start_value", + "reqd": 1 + }, + (data) => { + frm.set_value('odometer_start_value', data.odometer_start_value); + frm.set_value('odometer_start_time', frappe.datetime.now_datetime()); + frm.dirty(); + frm.save_or_update(); + }, + __("Enter Odometer Value")); + }).addClass("btn-primary"); + } else if (frm.doc.odometer_start_value > 0 && frm.doc.odometer_stop_value == 0) { + frm.add_custom_button(__("Stop"), () => { + frappe.prompt({ + "label": "Odometer Stop Value", + "fieldtype": "Int", + "fieldname": "odometer_stop_value", + "reqd": 1 + }, + (data) => { + if (data.odometer_stop_value > frm.doc.odometer_start_value) { + frm.set_value('odometer_stop_value', data.odometer_stop_value); + frm.set_value('odometer_stop_time', frappe.datetime.now_datetime()); + frm.set_value('actual_distance_travelled', (data.odometer_stop_value - frm.doc.odometer_start_value)); + frm.dirty(); + frm.save_or_update(); + } else { + frappe.throw("The stop value cannot be lower than the start value"); + } + }, + __("Enter Odometer Value")); + }).addClass("btn-primary"); + } + } + + frappe.db.get_value("Google Maps Settings", { name: "Google Maps Settings" }, "enabled", (r) => { + if (r.enabled == 0) { + // Hide entire Map section if Google Maps is disabled + let wrapper = frm.fields_dict.sb_map.wrapper + wrapper.hide() + } else { + // Inject Google Maps data into map embed field + let wrapper = frm.fields_dict.map_html.$wrapper; + wrapper.html(frm.doc.map_embed); + } + }); + + // Print delivery manifests + if (frm.doc.docstatus === 1) { + if (frm.doc.delivery_stops.length > 0) { + let deliveryNotes = frm.doc.delivery_stops.map(stop => stop.delivery_note); + deliveryNotes = [...new Set(deliveryNotes)]; + deliveryNotes = deliveryNotes.filter(Boolean); + + frm.add_custom_button(__("Print Shipping Manifests"), () => { + if (deliveryNotes.length == 0) { + frappe.msgprint(__("There are no Delivery Notes linked to any stop(s)")) + } else { + const w = window.open('/api/method/frappe.utils.print_format.download_multi_pdf?' + + 'doctype=' + encodeURIComponent("Delivery Note") + + '&name=' + encodeURIComponent(JSON.stringify(deliveryNotes)) + + '&format=' + encodeURIComponent(frm.doc.shipping_manifest_template || "")); + + if (!w) { + frappe.msgprint(__('Please enable pop-ups')); + return; + } + } + }).addClass("btn-primary"); + }; + } + }, + + force_save_or_update: function (frm, cdt, cdn) { + // `model.set_value` doesn't trigger a form change, so + // force-dirty to allow the form to be saved or updated + frm.dirty(); + frm.save_or_update(); + } +}); + +frappe.ui.form.on("Delivery Stop", { + visited: function (frm, cdt, cdn) { + var row = locals[cdt][cdn]; + + if (row.visited && row.sales_invoice) { + if (row.paid_amount !== row.grand_total) { + frappe.call({ + method: "bloomstack_core.hook_events.delivery_trip.update_payment_due_date", + args: { + sales_invoice: row.sales_invoice + } + }) + } + } + }, + + make_payment_entry: function (frm, cdt, cdn) { + var row = locals[cdt][cdn]; + + let dialog = frappe.prompt({ + "label": "Payment Amount", + "fieldtype": "Currency", + "fieldname": "payment_amount", + "reqd": 1 + }, + function (data) { + if (data.payment_amount === 0) { + frappe.confirm( + __("Are you sure you want to complete this delivery without a payment?"), + () => { + frappe.model.set_value(cdt, cdn, "visited", true); + frappe.model.set_value(cdt, cdn, "paid_amount", 0); + frm.trigger("force_save_or_update"); + } + ); + } else { + frappe.call({ + method: "bloomstack_core.hook_events.delivery_trip.make_payment_entry", + args: { + "payment_amount": data.payment_amount, + "sales_invoice": row.sales_invoice, + "delivery_trip": frm.doc.name + }, + callback: function (r) { + if (!r.exc) { + frappe.msgprint(__(`Payment Entry ${r.message} created.`)); + frappe.model.set_value(cdt, cdn, "visited", true); + frappe.model.set_value(cdt, cdn, "paid_amount", data.payment_amount); + frm.trigger("force_save_or_update"); + } + } + }) + } + }, + __("Make Payment Entry")); + + dialog.$wrapper.on("shown.bs.modal", function() { + if (frappe.is_mobile()) { + dialog.$wrapper.find($('input[data-fieldtype="Currency"]')).attr('type', 'number'); + } + }); + } +}); \ No newline at end of file diff --git a/bloomstack_core/public/js/item.js b/bloomstack_core/public/js/item.js index 0ef7eb0fe..b5595c1d5 100644 --- a/bloomstack_core/public/js/item.js +++ b/bloomstack_core/public/js/item.js @@ -17,5 +17,29 @@ frappe.ui.form.on('Item', { }; }) } + }, + + item_name: (frm) => { + frm.trigger("build_item_code"); + }, + + item_group: (frm) => { + frm.trigger("build_item_code"); + }, + + brand: (frm) => { + frm.trigger("build_item_code"); + }, + + build_item_code: (frm) => { + frappe.call({ + method: "bloomstack_core.hook_events.item.autoname_item", + args: { item: frm.doc }, + callback: (r) => { + if (r.message) { + frm.set_value("item_code", r.message); + } + } + }) } }); \ No newline at end of file diff --git a/bloomstack_core/public/js/packing_slip.js b/bloomstack_core/public/js/packing_slip.js new file mode 100644 index 000000000..b5fa6ca4e --- /dev/null +++ b/bloomstack_core/public/js/packing_slip.js @@ -0,0 +1,26 @@ +frappe.ui.form.on('Packing Slip', { + delivery_note: function (frm) { + if (frm.doc.delivery_note) { + frappe.db.get_value('Delivery Note', { name: frm.doc.delivery_note }, 'company', (r) => { + frm.set_value("company", r.company); + }); + erpnext.queries.setup_queries(frm, "Warehouse", function () { + return erpnext.queries.warehouse(frm.doc); + }); + } + }, + source_warehouse: function (frm) { + if (frm.doc.source_warehouse) { + $.each(frm.doc.items || [], function (i, item) { + frappe.model.set_value(frm.doctype + " Item", item.name, "source_warehouse", frm.doc.source_warehouse); + }); + } + }, + target_warehouse: function (frm) { + if (frm.doc.target_warehouse) { + $.each(frm.doc.items || [], function (i, item) { + frappe.model.set_value(frm.doctype + " Item", item.name, "target_warehouse", frm.doc.target_warehouse); + }); + } + } +}); diff --git a/bloomstack_core/public/js/quotation.js b/bloomstack_core/public/js/quotation.js new file mode 100644 index 000000000..fd4510ddb --- /dev/null +++ b/bloomstack_core/public/js/quotation.js @@ -0,0 +1,64 @@ +frappe.ui.form.on('Quotation', { + refresh: (frm) => { + if (!frm.is_new() && frm.doc.docstatus === 0) { + if (!frm.doc.customer_signature) { + frm.add_custom_button(__("Authorize"), () => { + frappe.prompt([ + { + "label": "Contact Email", + "fieldtype": "Data", + "options": "Email", + "fieldname": "contact_email", + "default": frm.doc.contact_email, + "reqd": 1 + }, + { + "label": "Contact Person", + "fieldtype": "Data", + "fieldname": "contact_person", + "default": frm.doc.contact_person + } + ], + function (data) { + frappe.call({ + method: "bloomstack_core.utils.create_authorization_request", + args: { + dt: frm.doc.doctype, + dn: frm.doc.name, + contact_email: data.contact_email, + contact_name: data.contact_person + }, + callback: (r) => { + if (!r.exc) { + frappe.msgprint(__(`The document ${frm.doc.name} has been successfully emailed to ${data.contact_person}`)) + } + } + }) + }, + __("Send Authorization Request")) + }).addClass("btn-primary"); + + } + } + }, + + no_charge_order: (frm) => { + frm.trigger("set_promotional_discount"); + }, + + set_promotional_discount: (frm) => { + let percentage_discount = 0; + + if (frm.doc.no_charge_order) { + frm.set_value("apply_discount_on", "Grand Total"); + percentage_discount = 100; + } + + frm.set_value("additional_discount_percentage", percentage_discount); + + frappe.show_alert({ + indicator: 'green', + message: __(`${percentage_discount}% discount applied`) + }); + } +}); diff --git a/bloomstack_core/public/js/sales_order.js b/bloomstack_core/public/js/sales_order.js new file mode 100644 index 000000000..a4b5c1863 --- /dev/null +++ b/bloomstack_core/public/js/sales_order.js @@ -0,0 +1,23 @@ +/* global frappe, erpnext, _ */ + +frappe.ui.form.on('Sales Order', { + no_charge_order: (frm) => { + frm.trigger("set_promotional_discount"); + }, + + set_promotional_discount: (frm) => { + let percentage_discount = 0; + + if (frm.doc.no_charge_order) { + frm.set_value("apply_discount_on", "Grand Total"); + percentage_discount = 100; + } + + frm.set_value("additional_discount_percentage", percentage_discount); + + frappe.show_alert({ + indicator: 'green', + message: __(`${percentage_discount}% discount applied`) + }); + } +}); \ No newline at end of file diff --git a/bloomstack_core/services/__init__.py b/bloomstack_core/services/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/services/issues.py b/bloomstack_core/services/issues.py new file mode 100644 index 000000000..f90d40b40 --- /dev/null +++ b/bloomstack_core/services/issues.py @@ -0,0 +1,9 @@ +import frappe + +@frappe.whitelist(allow_guest=True) +def issue_status_list(): + """ + Returns an array of statuses available on the Issues doctype. + """ + meta = frappe.get_meta("Issue") + return meta.get_options("status").split("\n") diff --git a/bloomstack_core/templates/emails/authorization_request.html b/bloomstack_core/templates/emails/authorization_request.html new file mode 100644 index 000000000..cc97a5d61 --- /dev/null +++ b/bloomstack_core/templates/emails/authorization_request.html @@ -0,0 +1,971 @@ + + + + + + + + + *|MC:SUBJECT|* + + + + + + +
      + + + + +
      + + + + + + + + + + + +
      + + + + + +
      + + + + + +
      + + + + +
      + + + + + +
      +
      + +
      + + + + + +
      + + + + + +
      + + + + + + + + +
      + +

      Authorization Request

      + +
      + + + +
      + + + + + +
      + + + + +
      + +
      + +
      + + + + + +
      + + + + + + + + +
      + +
      +You are requested to authorize a document.

      +
      + + + +
      + + + + + +
      + + + + + + +

      + View Document +
      +
      + + + + + +
      + + + + + + + + +
      + + Happy Blooming!
      +Bloom Bot
      +
      +PS: This is an auto-generated email. If you'd like any technical support, please send an email to my humans - support@bloomstack.com +
      + + + +
      + + + + + +
      + + + + +
      + +
      + +
      + + + + + +
      + + + + +
      + +
      + +
      + +
      + + + + + +
      + + + + + +
      + + + + +
      + + + + +
      + + + + +
      + + + + + + + + + +
      + + + + +
      + + + + + + + +
      + +
      +
      +
      + + + + + + + + + + +
      + + + + +
      + + + + + + + +
      + +
      +
      +
      + + + + + + + + + + +
      + + + + +
      + + + + + + + +
      + +
      +
      +
      + + + + + + + + + + +
      + + + + +
      + + + + + + + +
      + +
      +
      +
      + + + + +
      +
      +
      + +
      + + + + + +
      + + + + +
      + +
      + +
      + + + + + +
      + + + + + + + + +
      + + Copyright ©2019 Bloomstack Inc, All rights reserved.
      +
      +Our mailing address is:
      +support@bloomstack.com
      +
      +  +
      + + + +
      + +
      + +
      +
      + + diff --git a/bloomstack_core/templates/includes/google_maps_embed.html b/bloomstack_core/templates/includes/google_maps_embed.html new file mode 100644 index 000000000..d3e6fb0f1 --- /dev/null +++ b/bloomstack_core/templates/includes/google_maps_embed.html @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/bloomstack_core/templates/includes/sign_document.js b/bloomstack_core/templates/includes/sign_document.js new file mode 100644 index 000000000..425a9d207 --- /dev/null +++ b/bloomstack_core/templates/includes/sign_document.js @@ -0,0 +1,43 @@ +$(document).ready(function () { + var $sigdiv = $("#signature"); + $sigdiv.jSignature(); // inits the jSignature widget. + $sigdiv.jSignature("reset"); // clears the canvas and rerenders the decor on it. + + $("#approveDocument").on("click", function () { + var sign = $sigdiv.jSignature("getData"); + var signee = $("#signee").val(); + if ($sigdiv.jSignature('getData', 'native').length != 0 && signee) { // proceed only if user has put signature and signee name. + $(".user-signature").hide(); + frappe.call({ + method: "bloomstack_core.utils.authorize_document", + args: { + sign: sign, + signee: signee, + docname: "{{ auth_req_docname }}", + }, + freeze: true, + callback: (r) => { + frappe.msgprint(__("The document has been approved by you!")); + } + }); + } + else { + + frappe.throw(__("Please put your name and signature!")); + } + }); + + $("#rejectDocument").on("click", function () { + $(".user-signature").hide(); + frappe.call({ + method: "bloomstack_core.utils.reject_document", + args: { + docname: "{{ auth_req_docname }}", + }, + freeze: true, + callback: (r) => { + frappe.msgprint(__("The document has been rejected by you!")); + } + }) + }); +}); \ No newline at end of file diff --git a/bloomstack_core/utils.py b/bloomstack_core/utils.py index 531252c49..e6b2309d4 100755 --- a/bloomstack_core/utils.py +++ b/bloomstack_core/utils.py @@ -2,6 +2,8 @@ import json +from six import string_types + import frappe from erpnext.stock.doctype.batch.batch import get_batch_qty from python_metrc import METRC @@ -31,6 +33,46 @@ def login_as(user): return False +def get_abbr(txt, max_length=2): + """ + Extract abbreviation from the given string as: + - Single-word strings abbreviate to the letters of the string, upto the max length + - Multi-word strings abbreviate to the initials of each word, upto the max length + + Args: + txt (str): The string to abbreviate + max_length (int, optional): The max length of the abbreviation. Defaults to 2. + + Returns: + str: The abbreviated string, in uppercase + """ + + if not txt: + return + + if not isinstance(txt, string_types): + try: + txt = str(txt) + except: + return + + abbr = "" + words = txt.split(" ") + + if len(words) > 1: + for word in words: + if len(abbr) >= max_length: + break + + if word.strip(): + abbr += word.strip()[0] + else: + abbr = txt[:max_length] + + abbr = abbr.upper() + return abbr + + @frappe.whitelist() def move_expired_batches(source_name, target_doc=None): batch_details = get_batch_qty(source_name) @@ -81,3 +123,40 @@ def log_request(endpoint, request_data, response, ref_dt=None, ref_dn=None): }) request.insert() frappe.db.commit() + + +@frappe.whitelist(allow_guest=True) +def authorize_document(sign=None, signee=None, docname=None): + if frappe.db.exists("Authorization Request", docname): + authorization_request = frappe.get_doc("Authorization Request", docname) + authorization_request.signature = sign + authorization_request.signee_name = signee + authorization_request.status = "Approved" + authorization_request.flags.ignore_permissions = True + authorization_request.save() + + authorized_doc = frappe.get_doc(authorization_request.linked_doctype, authorization_request.linked_docname) + if hasattr(authorized_doc, "is_signed") and hasattr(authorized_doc, "authorizer_signature") and hasattr(authorized_doc, "signee"): + if authorized_doc.is_signed == 0: + authorized_doc.is_signed = 1 + authorized_doc.authorizer_signature = sign + authorized_doc.signee = signee + + authorized_doc.submit() + + +@frappe.whitelist(allow_guest=True) +def reject_document(docname): + if frappe.db.exists("Authorization Request", docname): + authorization_request = frappe.get_doc("Authorization Request", docname) + authorization_request.status = "Rejected" + authorization_request.save() + + +@frappe.whitelist() +def create_authorization_request(dt, dn, contact_email, contact_name=None): + new_authorization_request = frappe.new_doc("Authorization Request") + new_authorization_request.linked_doctype = dt + new_authorization_request.linked_docname = dn + new_authorization_request.authorizer_email = contact_email + new_authorization_request.save() diff --git a/bloomstack_core/www/__init__.py b/bloomstack_core/www/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bloomstack_core/www/authorize_document.html b/bloomstack_core/www/authorize_document.html new file mode 100644 index 000000000..fb85bea75 --- /dev/null +++ b/bloomstack_core/www/authorize_document.html @@ -0,0 +1,260 @@ +{% extends "templates/web.html" %} +{% block title %} Authorize Document {% endblock %} +{% block style %} + +{% endblock %} +{% block page_content %} +{% if error %} +{{ error }} +{% else %} +
      +
      +

      {{company}} has requested you to authorize a {{doc.doctype}}


      +
      +
      + +
      +
      + {{ print_doc }} +
      +
      + +
      +
      + Your Name:

      +


      + Signature: +



      +
      + Approve + Reject +
      +
      + +
      +{% endif %} +{% endblock %} + +{% block script %} + + +{% endblock %} \ No newline at end of file diff --git a/bloomstack_core/www/authorize_document.py b/bloomstack_core/www/authorize_document.py new file mode 100644 index 000000000..0a0c091af --- /dev/null +++ b/bloomstack_core/www/authorize_document.py @@ -0,0 +1,27 @@ +from __future__ import unicode_literals +from erpnext import get_default_company +import frappe +import re +no_cache = 1 + + +def get_context(context): + token = frappe.local.request.args.get("token") + docname = frappe.local.request.args.get("name") + auth_req = frappe.get_doc("Authorization Request", docname) + + if not token or token != auth_req.token: + context.error = "Token is not valid. Click here to re-send email" + + elif auth_req.status == "Approved": + context.error = "This document has already been authorized by you!" + + elif auth_req.status == "Rejected": + context.error = "This document has already been rejected by you!" + + frappe.local.flags.ignore_print_permissions = True + print_doc = frappe.get_print(auth_req.linked_doctype, auth_req.linked_docname) + context.print_doc = print_doc[print_doc.find('')+len(''):len(print_doc)-len('')] + context.doc = frappe.get_doc(auth_req.linked_doctype, auth_req.linked_docname) + context.company = context.doc.company if hasattr(context.doc, 'company') else get_default_company() + context.auth_req_docname = docname diff --git a/package.json b/package.json new file mode 100644 index 000000000..23e59357e --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "bloomstack_core", + "repository": { + "type": "git", + "url": "git+https://github.com/DigiThinkIT/bloomstack_core.git" + }, + "author": "DigiThinkIT Technologies Pvt. Ltd.", + "license": "MIT", + "bugs": { + "url": "https://github.com/DigiThinkIT/bloomstack_core/issues" + }, + "dependencies": { + "chart.js": "^2.8.0" + }, + "devDependencies": { + "chart.js": "^2.8.0" + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000..909dd2a45 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,41 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +chart.js@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.8.0.tgz#b703b10d0f4ec5079eaefdcd6ca32dc8f826e0e9" + integrity sha512-Di3wUL4BFvqI5FB5K26aQ+hvWh8wnP9A3DWGvXHVkO13D3DSnaSsdZx29cXlEsYKVkn1E2az+ZYFS4t0zi8x0w== + dependencies: + chartjs-color "^2.1.0" + moment "^2.10.2" + +chartjs-color-string@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz#1df096621c0e70720a64f4135ea171d051402f71" + integrity sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A== + dependencies: + color-name "^1.0.0" + +chartjs-color@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/chartjs-color/-/chartjs-color-2.3.0.tgz#0e7e1e8dba37eae8415fd3db38bf572007dd958f" + integrity sha512-hEvVheqczsoHD+fZ+tfPUE+1+RbV6b+eksp2LwAhwRTVXEjCSEavvk+Hg3H6SZfGlPh/UfmWKGIvZbtobOEm3g== + dependencies: + chartjs-color-string "^0.6.0" + color-convert "^0.5.3" + +color-convert@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-0.5.3.tgz#bdb6c69ce660fadffe0b0007cc447e1b9f7282bd" + integrity sha1-vbbGnOZg+t/+CwAHzER+G59ygr0= + +color-name@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +moment@^2.10.2: + version "2.24.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" + integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==