diff --git a/posawesome/fixtures/custom_field.json b/posawesome/fixtures/custom_field.json
index 2e00aea31..33909f1ca 100644
--- a/posawesome/fixtures/custom_field.json
+++ b/posawesome/fixtures/custom_field.json
@@ -1,4 +1,58 @@
[
+ {
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "collapsible_depends_on": null,
+ "columns": 0,
+ "default": null,
+ "depends_on": null,
+ "description": null,
+ "docstatus": 0,
+ "doctype": "Custom Field",
+ "dt": "POS Profile",
+ "fetch_from": null,
+ "fetch_if_empty": 0,
+ "fieldname": "custom_pezesha_channel_id",
+ "fieldtype": "Data",
+ "hidden": 0,
+ "hide_border": 0,
+ "hide_days": 0,
+ "hide_seconds": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_preview": 0,
+ "in_standard_filter": 0,
+ "insert_after": "customer",
+ "is_system_generated": 0,
+ "is_virtual": 0,
+ "label": "Pezesha Channel ID",
+ "length": 0,
+ "mandatory_depends_on": null,
+ "modified": "2024-03-26 13:01:54.453466",
+ "module": null,
+ "name": "POS Profile-custom_pezesha_channel_id",
+ "no_copy": 0,
+ "non_negative": 0,
+ "options": null,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": null,
+ "read_only": 0,
+ "read_only_depends_on": null,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "sort_options": 0,
+ "translatable": 1,
+ "unique": 0,
+ "width": null
+ },
{
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
@@ -350,7 +404,7 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "company_address",
+ "insert_after": "custom_closing_shift_time",
"is_system_generated": 0,
"is_virtual": 0,
"label": "POS Awesome Settings",
@@ -384,16 +438,16 @@
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
- "default": null,
+ "default": "0",
"depends_on": null,
- "description": "For POS Closing Shift Payment Reconciliation",
+ "description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "POS Profile",
+ "dt": "Customer",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_cash_mode_of_payment",
- "fieldtype": "Link",
+ "fieldname": "posa_discount",
+ "fieldtype": "Float",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -404,18 +458,18 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_pos_awesome_settings",
+ "insert_after": "lead_name",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Cash Mode of Payment",
+ "label": "Discount %",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-03-06 00:29:24.240940",
+ "modified": "2021-06-04 21:02:31.784347",
"module": null,
- "name": "POS Profile-posa_cash_mode_of_payment",
+ "name": "Customer-posa_discount",
"no_copy": 0,
- "non_negative": 0,
- "options": "Mode of Payment",
+ "non_negative": 1,
+ "options": null,
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -443,10 +497,10 @@
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "Customer",
+ "dt": "Batch",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_discount",
+ "fieldname": "posa_batch_price",
"fieldtype": "Float",
"hidden": 0,
"hide_border": 0,
@@ -458,17 +512,17 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "lead_name",
+ "insert_after": "manufacturing_date",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Discount %",
+ "label": "Price",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-06-04 21:02:31.784347",
+ "modified": "2020-10-26 02:31:58.913688",
"module": null,
- "name": "Customer-posa_discount",
+ "name": "Batch-posa_batch_price",
"no_copy": 0,
- "non_negative": 1,
+ "non_negative": 0,
"options": null,
"permlevel": 0,
"precision": "",
@@ -492,16 +546,16 @@
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
- "default": "0",
+ "default": null,
"depends_on": null,
- "description": null,
+ "description": "For POS Closing Shift Payment Reconciliation",
"docstatus": 0,
"doctype": "Custom Field",
"dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_allow_delete",
- "fieldtype": "Check",
+ "fieldname": "posa_cash_mode_of_payment",
+ "fieldtype": "Link",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -512,18 +566,18 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_cash_mode_of_payment",
+ "insert_after": "posa_pos_awesome_settings",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Auto Delete Draft Invoice",
+ "label": "Cash Mode of Payment",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2020-10-09 16:01:30.649938",
+ "modified": "2021-03-06 00:29:24.240940",
"module": null,
- "name": "POS Profile-posa_allow_delete",
+ "name": "POS Profile-posa_cash_mode_of_payment",
"no_copy": 0,
"non_negative": 0,
- "options": null,
+ "options": "Mode of Payment",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -551,11 +605,11 @@
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "Batch",
+ "dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_batch_price",
- "fieldtype": "Float",
+ "fieldname": "posa_allow_delete",
+ "fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -566,15 +620,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "manufacturing_date",
+ "insert_after": "posa_cash_mode_of_payment",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Price",
+ "label": "Auto Delete Draft Invoice",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2020-10-26 02:31:58.913688",
+ "modified": "2020-10-09 16:01:30.649938",
"module": null,
- "name": "Batch-posa_batch_price",
+ "name": "POS Profile-posa_allow_delete",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -816,16 +870,16 @@
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
- "default": "221",
+ "default": null,
"depends_on": null,
- "description": "It is best not to use more than four numbers",
+ "description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "POS Profile",
+ "dt": "Sales Invoice",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_scale_barcode_start",
- "fieldtype": "Int",
+ "fieldname": "posa_pos_opening_shift",
+ "fieldtype": "Data",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -835,31 +889,31 @@
"in_global_search": 0,
"in_list_view": 0,
"in_preview": 0,
- "in_standard_filter": 0,
- "insert_after": "posa_max_discount_allowed",
+ "in_standard_filter": 1,
+ "insert_after": "pos_profile",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Scale Barcode Start With",
+ "label": "POS Shift",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2020-10-30 03:54:32.270370",
+ "modified": "2020-09-27 03:15:11.844405",
"module": null,
- "name": "POS Profile-posa_scale_barcode_start",
- "no_copy": 0,
+ "name": "Sales Invoice-posa_pos_opening_shift",
+ "no_copy": 1,
"non_negative": 0,
"options": null,
"permlevel": 0,
"precision": "",
- "print_hide": 0,
+ "print_hide": 1,
"print_hide_if_no_value": 0,
"print_width": null,
- "read_only": 0,
+ "read_only": 1,
"read_only_depends_on": null,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"sort_options": 0,
- "translatable": 0,
+ "translatable": 1,
"unique": 0,
"width": null
},
@@ -870,16 +924,16 @@
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
- "default": null,
+ "default": "",
"depends_on": null,
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "POS Profile",
+ "dt": "Address",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_allow_change_posting_date",
- "fieldtype": "Check",
+ "fieldname": "posa_delivery_charges",
+ "fieldtype": "Link",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -890,18 +944,18 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_scale_barcode_start",
+ "insert_after": "is_shipping_address",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Allow Change Posting Date",
+ "label": "Delivery Charges",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2022-12-16 11:20:05.134781",
+ "modified": "2022-07-24 17:20:00.246026",
"module": null,
- "name": "POS Profile-posa_allow_change_posting_date",
+ "name": "Address-posa_delivery_charges",
"no_copy": 0,
"non_negative": 0,
- "options": null,
+ "options": "Delivery Charges",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -924,16 +978,16 @@
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
- "default": null,
+ "default": "221",
"depends_on": null,
- "description": null,
+ "description": "It is best not to use more than four numbers",
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "Sales Invoice",
+ "dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_pos_opening_shift",
- "fieldtype": "Data",
+ "fieldname": "posa_scale_barcode_start",
+ "fieldtype": "Int",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -943,31 +997,31 @@
"in_global_search": 0,
"in_list_view": 0,
"in_preview": 0,
- "in_standard_filter": 1,
- "insert_after": "pos_profile",
+ "in_standard_filter": 0,
+ "insert_after": "posa_max_discount_allowed",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "POS Shift",
+ "label": "Scale Barcode Start With",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2020-09-27 03:15:11.844405",
+ "modified": "2020-10-30 03:54:32.270370",
"module": null,
- "name": "Sales Invoice-posa_pos_opening_shift",
- "no_copy": 1,
+ "name": "POS Profile-posa_scale_barcode_start",
+ "no_copy": 0,
"non_negative": 0,
"options": null,
"permlevel": 0,
"precision": "",
- "print_hide": 1,
+ "print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": null,
- "read_only": 1,
+ "read_only": 0,
"read_only_depends_on": null,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"sort_options": 0,
- "translatable": 1,
+ "translatable": 0,
"unique": 0,
"width": null
},
@@ -978,16 +1032,16 @@
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
- "default": "",
+ "default": null,
"depends_on": null,
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "Address",
+ "dt": "Sales Invoice",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_delivery_charges",
- "fieldtype": "Link",
+ "fieldname": "posa_is_printed",
+ "fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -997,25 +1051,25 @@
"in_global_search": 0,
"in_list_view": 0,
"in_preview": 0,
- "in_standard_filter": 0,
- "insert_after": "is_shipping_address",
+ "in_standard_filter": 1,
+ "insert_after": "posa_pos_opening_shift",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Delivery Charges",
+ "label": "Printed",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2022-07-24 17:20:00.246026",
+ "modified": "2020-11-02 02:48:23.877227",
"module": null,
- "name": "Address-posa_delivery_charges",
+ "name": "Sales Invoice-posa_is_printed",
"no_copy": 0,
"non_negative": 0,
- "options": "Delivery Charges",
+ "options": null,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": null,
- "read_only": 0,
+ "read_only": 1,
"read_only_depends_on": null,
"report_hide": 0,
"reqd": 0,
@@ -1040,7 +1094,7 @@
"dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_default_card_view",
+ "fieldname": "posa_allow_change_posting_date",
"fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
@@ -1052,15 +1106,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_allow_change_posting_date",
+ "insert_after": "posa_scale_barcode_start",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Default Card View",
+ "label": "Allow Change Posting Date",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2023-03-12 14:03:44.088542",
+ "modified": "2022-12-16 11:20:05.134781",
"module": null,
- "name": "POS Profile-posa_default_card_view",
+ "name": "POS Profile-posa_allow_change_posting_date",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -1091,10 +1145,10 @@
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "Sales Invoice",
+ "dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_is_printed",
+ "fieldname": "posa_default_card_view",
"fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
@@ -1105,16 +1159,16 @@
"in_global_search": 0,
"in_list_view": 0,
"in_preview": 0,
- "in_standard_filter": 1,
- "insert_after": "posa_pos_opening_shift",
+ "in_standard_filter": 0,
+ "insert_after": "posa_allow_change_posting_date",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Printed",
+ "label": "Default Card View",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2020-11-02 02:48:23.877227",
+ "modified": "2023-03-12 14:03:44.088542",
"module": null,
- "name": "Sales Invoice-posa_is_printed",
+ "name": "POS Profile-posa_default_card_view",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -1123,7 +1177,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": null,
- "read_only": 1,
+ "read_only": 0,
"read_only_depends_on": null,
"report_hide": 0,
"reqd": 0,
@@ -1947,7 +2001,7 @@
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
- "collapsible": 0,
+ "collapsible": 1,
"collapsible_depends_on": null,
"columns": 0,
"default": null,
@@ -1955,11 +2009,11 @@
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "POS Profile",
+ "dt": "Company",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_column_break_112",
- "fieldtype": "Column Break",
+ "fieldname": "posa_referral_section",
+ "fieldtype": "Section Break",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -1970,15 +2024,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "hide_expected_amount",
+ "insert_after": "total_monthly_sales",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "",
+ "label": "Referral Code",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-06-23 22:48:40.886230",
+ "modified": "2021-07-29 23:04:22.290849",
"module": null,
- "name": "POS Profile-posa_column_break_112",
+ "name": "Company-posa_referral_section",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -2012,8 +2066,8 @@
"dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_allow_sales_order",
- "fieldtype": "Check",
+ "fieldname": "posa_column_break_112",
+ "fieldtype": "Column Break",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -2024,15 +2078,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_column_break_112",
+ "insert_after": "hide_expected_amount",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Allow Create Sales Order",
+ "label": "",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-06-22 03:02:27.784096",
+ "modified": "2021-06-23 22:48:40.886230",
"module": null,
- "name": "POS Profile-posa_allow_sales_order",
+ "name": "POS Profile-posa_column_break_112",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -2051,64 +2105,11 @@
"unique": 0,
"width": null
},
- {
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "collapsible_depends_on": null,
- "columns": 0,
- "default": null,
- "depends_on": null,
- "description": null,
- "docstatus": 0,
- "doctype": "Custom Field",
- "dt": "POS Profile",
- "fetch_from": null,
- "fetch_if_empty": 0,
- "fieldname": "custom_allow_select_sales_order",
- "fieldtype": "Check",
- "hidden": 0,
- "hide_border": 0,
- "hide_days": 0,
- "hide_seconds": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_preview": 0,
- "in_standard_filter": 0,
- "insert_after": "posa_allow_sales_order",
- "is_system_generated": 0,
- "is_virtual": 0,
- "label": "Allow Select Sales Order",
- "length": 0,
- "mandatory_depends_on": null,
- "modified": "2023-11-13 12:16:27.784096",
- "module": null,
- "name": "POS Profile-custom_allow_select_sales_order",
- "no_copy": 0,
- "non_negative": 0,
- "options": null,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "print_width": null,
- "read_only": 0,
- "read_only_depends_on": null,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "translatable": 0,
- "unique": 0,
- "width": null
-},
{
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
- "collapsible": 1,
+ "collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
"default": null,
@@ -2119,8 +2120,8 @@
"dt": "Company",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_referral_section",
- "fieldtype": "Section Break",
+ "fieldname": "posa_auto_referral",
+ "fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -2131,15 +2132,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "total_monthly_sales",
+ "insert_after": "posa_referral_section",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Referral Code",
+ "label": "Auto Create Referral For New Customers",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-07-29 23:04:22.290849",
+ "modified": "2021-07-29 23:07:08.681215",
"module": null,
- "name": "Company-posa_referral_section",
+ "name": "Company-posa_auto_referral",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -2173,7 +2174,7 @@
"dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_show_template_items",
+ "fieldname": "posa_allow_sales_order",
"fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
@@ -2185,15 +2186,69 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_allow_sales_order",
+ "insert_after": "posa_column_break_112",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Show Template Items",
+ "label": "Allow Create Sales Order",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-06-23 22:48:41.288938",
+ "modified": "2021-06-22 03:02:27.784096",
"module": null,
- "name": "POS Profile-posa_show_template_items",
+ "name": "POS Profile-posa_allow_sales_order",
+ "no_copy": 0,
+ "non_negative": 0,
+ "options": null,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": null,
+ "read_only": 0,
+ "read_only_depends_on": null,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "sort_options": 0,
+ "translatable": 0,
+ "unique": 0,
+ "width": null
+ },
+ {
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 1,
+ "collapsible_depends_on": null,
+ "columns": 0,
+ "default": null,
+ "depends_on": null,
+ "description": null,
+ "docstatus": 0,
+ "doctype": "Custom Field",
+ "dt": "Sales Order",
+ "fetch_from": null,
+ "fetch_if_empty": 0,
+ "fieldname": "posa_additional_notes_section",
+ "fieldtype": "Section Break",
+ "hidden": 0,
+ "hide_border": 0,
+ "hide_days": 0,
+ "hide_seconds": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_preview": 0,
+ "in_standard_filter": 0,
+ "insert_after": "items",
+ "is_system_generated": 0,
+ "is_virtual": 0,
+ "label": "Additional Notes",
+ "length": 0,
+ "mandatory_depends_on": null,
+ "modified": "2021-06-21 16:11:59.366893",
+ "module": null,
+ "name": "Sales Order-posa_additional_notes_section",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -2227,8 +2282,8 @@
"dt": "Company",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_auto_referral",
- "fieldtype": "Check",
+ "fieldname": "posa_column_break_22",
+ "fieldtype": "Column Break",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -2239,15 +2294,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_referral_section",
+ "insert_after": "posa_auto_referral",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Auto Create Referral For New Customers",
+ "label": "",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-07-29 23:07:08.681215",
+ "modified": "2021-07-29 23:11:04.558635",
"module": null,
- "name": "Company-posa_auto_referral",
+ "name": "Company-posa_column_break_22",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -2274,14 +2329,14 @@
"collapsible_depends_on": null,
"columns": 0,
"default": null,
- "depends_on": "posa_show_template_items",
+ "depends_on": null,
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
"dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_hide_variants_items",
+ "fieldname": "custom_allow_select_sales_order",
"fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
@@ -2293,15 +2348,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_show_template_items",
+ "insert_after": "posa_allow_sales_order",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Hide Variants Items",
+ "label": "Allow Select Sales Order",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-06-24 03:24:52.591942",
+ "modified": "2023-11-13 12:16:27.784096",
"module": null,
- "name": "POS Profile-posa_hide_variants_items",
+ "name": "POS Profile-custom_allow_select_sales_order",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -2324,7 +2379,7 @@
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
- "collapsible": 1,
+ "collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
"default": null,
@@ -2335,8 +2390,8 @@
"dt": "Sales Order",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_additional_notes_section",
- "fieldtype": "Section Break",
+ "fieldname": "posa_notes",
+ "fieldtype": "Small Text",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -2347,15 +2402,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "items",
+ "insert_after": "posa_additional_notes_section",
"is_system_generated": 0,
"is_virtual": 0,
"label": "Additional Notes",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-06-21 16:11:59.366893",
+ "modified": "2021-06-21 16:11:59.829304",
"module": null,
- "name": "Sales Order-posa_additional_notes_section",
+ "name": "Sales Order-posa_notes",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -2370,7 +2425,7 @@
"reqd": 0,
"search_index": 0,
"sort_options": 0,
- "translatable": 0,
+ "translatable": 1,
"unique": 0,
"width": null
},
@@ -2382,15 +2437,15 @@
"collapsible_depends_on": null,
"columns": 0,
"default": null,
- "depends_on": null,
+ "depends_on": "posa_auto_referral",
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
"dt": "Company",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_column_break_22",
- "fieldtype": "Column Break",
+ "fieldname": "posa_customer_offer",
+ "fieldtype": "Link",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -2401,18 +2456,18 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_auto_referral",
+ "insert_after": "posa_column_break_22",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "",
+ "label": "Final Customer Offer",
"length": 0,
- "mandatory_depends_on": null,
- "modified": "2021-07-29 23:11:04.558635",
+ "mandatory_depends_on": "posa_auto_referral",
+ "modified": "2021-07-29 23:11:04.891539",
"module": null,
- "name": "Company-posa_column_break_22",
+ "name": "Company-posa_customer_offer",
"no_copy": 0,
"non_negative": 0,
- "options": null,
+ "options": "POS Offer",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -2443,7 +2498,7 @@
"dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_fetch_coupon",
+ "fieldname": "posa_show_template_items",
"fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
@@ -2455,15 +2510,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_hide_variants_items",
+ "insert_after": "custom_allow_select_sales_order",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Auto Fetch Coupon Gifts",
+ "label": "Show Template Items",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-07-29 22:58:10.372543",
+ "modified": "2021-06-23 22:48:41.288938",
"module": null,
- "name": "POS Profile-posa_fetch_coupon",
+ "name": "POS Profile-posa_show_template_items",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -2494,11 +2549,11 @@
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "Sales Order",
+ "dt": "Customer",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_notes",
- "fieldtype": "Small Text",
+ "fieldname": "posa_birthday",
+ "fieldtype": "Date",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -2509,15 +2564,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_additional_notes_section",
+ "insert_after": "contact_html",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Additional Notes",
+ "label": "Birthday",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-06-21 16:11:59.829304",
+ "modified": "2021-07-31 00:12:09.417519",
"module": null,
- "name": "Sales Order-posa_notes",
+ "name": "Customer-posa_birthday",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -2532,7 +2587,7 @@
"reqd": 0,
"search_index": 0,
"sort_options": 0,
- "translatable": 1,
+ "translatable": 0,
"unique": 0,
"width": null
},
@@ -2551,7 +2606,7 @@
"dt": "Company",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_customer_offer",
+ "fieldname": "posa_primary_offer",
"fieldtype": "Link",
"hidden": 0,
"hide_border": 0,
@@ -2563,15 +2618,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_column_break_22",
+ "insert_after": "posa_customer_offer",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Final Customer Offer",
+ "label": "Primary Customer Offer",
"length": 0,
- "mandatory_depends_on": "posa_auto_referral",
- "modified": "2021-07-29 23:11:04.891539",
+ "mandatory_depends_on": null,
+ "modified": "2021-07-29 23:11:05.290809",
"module": null,
- "name": "Company-posa_customer_offer",
+ "name": "Company-posa_primary_offer",
"no_copy": 0,
"non_negative": 0,
"options": "POS Offer",
@@ -2598,15 +2653,15 @@
"collapsible_depends_on": null,
"columns": 0,
"default": null,
- "depends_on": null,
+ "depends_on": "posa_show_template_items",
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "Customer",
+ "dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_birthday",
- "fieldtype": "Date",
+ "fieldname": "posa_hide_variants_items",
+ "fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -2617,15 +2672,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "contact_html",
+ "insert_after": "posa_show_template_items",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Birthday",
+ "label": "Hide Variants Items",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-07-31 00:12:09.417519",
+ "modified": "2021-06-24 03:24:52.591942",
"module": null,
- "name": "Customer-posa_birthday",
+ "name": "POS Profile-posa_hide_variants_items",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -2648,19 +2703,19 @@
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
- "collapsible": 0,
+ "collapsible": 1,
"collapsible_depends_on": null,
"columns": 0,
- "default": "0",
+ "default": null,
"depends_on": null,
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "POS Profile",
+ "dt": "Customer",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_allow_customer_purchase_order",
- "fieldtype": "Check",
+ "fieldname": "posa_referral_section",
+ "fieldtype": "Section Break",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -2671,15 +2726,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_fetch_coupon",
+ "insert_after": "posa_birthday",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Allow Customer Purchase Order",
+ "label": "Referral Code",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-12-16 16:27:32.300240",
+ "modified": "2021-07-29 23:23:04.910503",
"module": null,
- "name": "POS Profile-posa_allow_customer_purchase_order",
+ "name": "Customer-posa_referral_section",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -2705,7 +2760,7 @@
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
- "default": null,
+ "default": "",
"depends_on": "posa_auto_referral",
"description": null,
"docstatus": 0,
@@ -2713,7 +2768,7 @@
"dt": "Company",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_primary_offer",
+ "fieldname": "posa_referral_campaign",
"fieldtype": "Link",
"hidden": 0,
"hide_border": 0,
@@ -2725,18 +2780,18 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_customer_offer",
+ "insert_after": "posa_primary_offer",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Primary Customer Offer",
+ "label": "Referral Campaign",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-07-29 23:11:05.290809",
+ "modified": "2021-07-29 23:11:05.723688",
"module": null,
- "name": "Company-posa_primary_offer",
+ "name": "Company-posa_referral_campaign",
"no_copy": 0,
"non_negative": 0,
- "options": "POS Offer",
+ "options": "Campaign",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -2756,7 +2811,7 @@
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
- "collapsible": 1,
+ "collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
"default": null,
@@ -2764,11 +2819,11 @@
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "Customer",
+ "dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_referral_section",
- "fieldtype": "Section Break",
+ "fieldname": "posa_fetch_coupon",
+ "fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -2779,15 +2834,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_birthday",
+ "insert_after": "posa_hide_variants_items",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Referral Code",
+ "label": "Auto Fetch Coupon Gifts",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-07-29 23:23:04.910503",
+ "modified": "2021-07-29 22:58:10.372543",
"module": null,
- "name": "Customer-posa_referral_section",
+ "name": "POS Profile-posa_fetch_coupon",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -2807,22 +2862,22 @@
"width": null
},
{
- "allow_in_quick_entry": 0,
+ "allow_in_quick_entry": 1,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
- "default": "0",
+ "default": null,
"depends_on": null,
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "POS Profile",
+ "dt": "Customer",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_allow_print_last_invoice",
- "fieldtype": "Check",
+ "fieldname": "posa_referral_code",
+ "fieldtype": "Data",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -2833,16 +2888,16 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_allow_customer_purchase_order",
+ "insert_after": "posa_referral_section",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Allow Print Last Invoice",
+ "label": "Referral Code",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-12-16 18:00:40.631156",
+ "modified": "2021-07-29 22:42:57.772021",
"module": null,
- "name": "POS Profile-posa_allow_print_last_invoice",
- "no_copy": 0,
+ "name": "Customer-posa_referral_code",
+ "no_copy": 1,
"non_negative": 0,
"options": null,
"permlevel": 0,
@@ -2856,7 +2911,7 @@
"reqd": 0,
"search_index": 0,
"sort_options": 0,
- "translatable": 0,
+ "translatable": 1,
"unique": 0,
"width": null
},
@@ -2867,16 +2922,16 @@
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
- "default": "",
- "depends_on": "posa_auto_referral",
+ "default": "0",
+ "depends_on": null,
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "Company",
+ "dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_referral_campaign",
- "fieldtype": "Link",
+ "fieldname": "posa_allow_customer_purchase_order",
+ "fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -2887,18 +2942,18 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_primary_offer",
+ "insert_after": "posa_fetch_coupon",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Referral Campaign",
+ "label": "Allow Customer Purchase Order",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-07-29 23:11:05.723688",
+ "modified": "2021-12-16 16:27:32.300240",
"module": null,
- "name": "Company-posa_referral_campaign",
+ "name": "POS Profile-posa_allow_customer_purchase_order",
"no_copy": 0,
"non_negative": 0,
- "options": "Campaign",
+ "options": null,
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -2917,7 +2972,7 @@
{
"allow_in_quick_entry": 1,
"allow_on_submit": 0,
- "bold": 0,
+ "bold": 1,
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
@@ -2929,8 +2984,8 @@
"dt": "Customer",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_referral_code",
- "fieldtype": "Data",
+ "fieldname": "posa_referral_company",
+ "fieldtype": "Link",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -2941,18 +2996,18 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_referral_section",
+ "insert_after": "posa_referral_code",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Referral Code",
+ "label": "Referral Company",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-07-29 22:42:57.772021",
+ "modified": "2021-07-29 23:24:11.207034",
"module": null,
- "name": "Customer-posa_referral_code",
+ "name": "Customer-posa_referral_company",
"no_copy": 1,
"non_negative": 0,
- "options": null,
+ "options": "Company",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -2964,7 +3019,7 @@
"reqd": 0,
"search_index": 0,
"sort_options": 0,
- "translatable": 1,
+ "translatable": 0,
"unique": 0,
"width": null
},
@@ -2980,11 +3035,11 @@
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "POS Profile",
+ "dt": "Sales Invoice Item",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_display_additional_notes",
- "fieldtype": "Check",
+ "fieldname": "posa_offers",
+ "fieldtype": "Small Text",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -2995,15 +3050,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_allow_print_last_invoice",
+ "insert_after": "pricing_rules",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Display Additional Notes",
+ "label": "POS Offers",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-12-19 16:54:32.986600",
+ "modified": "2021-06-07 01:51:16.390447",
"module": null,
- "name": "POS Profile-posa_display_additional_notes",
+ "name": "Sales Invoice Item-posa_offers",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -3012,33 +3067,33 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": null,
- "read_only": 0,
+ "read_only": 1,
"read_only_depends_on": null,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"sort_options": 0,
- "translatable": 0,
+ "translatable": 1,
"unique": 0,
"width": null
},
{
- "allow_in_quick_entry": 1,
+ "allow_in_quick_entry": 0,
"allow_on_submit": 0,
- "bold": 1,
+ "bold": 0,
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
- "default": null,
+ "default": "0",
"depends_on": null,
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "Customer",
+ "dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_referral_company",
- "fieldtype": "Link",
+ "fieldname": "posa_allow_print_last_invoice",
+ "fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -3049,18 +3104,18 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_referral_code",
+ "insert_after": "posa_allow_customer_purchase_order",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Referral Company",
+ "label": "Allow Print Last Invoice",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-07-29 23:24:11.207034",
+ "modified": "2021-12-16 18:00:40.631156",
"module": null,
- "name": "Customer-posa_referral_company",
- "no_copy": 1,
+ "name": "POS Profile-posa_allow_print_last_invoice",
+ "no_copy": 0,
"non_negative": 0,
- "options": "Company",
+ "options": null,
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -3088,10 +3143,10 @@
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "POS Profile",
+ "dt": "Sales Invoice Item",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_allow_write_off_change",
+ "fieldname": "posa_offer_applied",
"fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
@@ -3103,15 +3158,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_display_additional_notes",
+ "insert_after": "posa_offers",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Allow Write Off Change",
+ "label": "Offer Applied",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2022-02-12 04:26:04.003374",
+ "modified": "2021-06-12 00:12:28.473489",
"module": null,
- "name": "POS Profile-posa_allow_write_off_change",
+ "name": "Sales Invoice Item-posa_offer_applied",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -3120,7 +3175,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": null,
- "read_only": 0,
+ "read_only": 1,
"read_only_depends_on": null,
"report_hide": 0,
"reqd": 0,
@@ -3142,11 +3197,11 @@
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "Sales Invoice Item",
+ "dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_offers",
- "fieldtype": "Small Text",
+ "fieldname": "posa_display_additional_notes",
+ "fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -3157,15 +3212,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "pricing_rules",
+ "insert_after": "posa_allow_print_last_invoice",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "POS Offers",
+ "label": "Display Additional Notes",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-06-07 01:51:16.390447",
+ "modified": "2021-12-19 16:54:32.986600",
"module": null,
- "name": "Sales Invoice Item-posa_offers",
+ "name": "POS Profile-posa_display_additional_notes",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -3174,13 +3229,13 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": null,
- "read_only": 1,
+ "read_only": 0,
"read_only_depends_on": null,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"sort_options": 0,
- "translatable": 1,
+ "translatable": 0,
"unique": 0,
"width": null
},
@@ -3191,15 +3246,15 @@
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
- "default": "0",
+ "default": null,
"depends_on": null,
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "POS Profile",
+ "dt": "Sales Invoice Item",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_new_line",
+ "fieldname": "posa_is_offer",
"fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
@@ -3208,18 +3263,18 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_global_search": 0,
- "in_list_view": 0,
+ "in_list_view": 1,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_allow_write_off_change",
+ "insert_after": "posa_offer_applied",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Allow add New Items on New Line",
+ "label": "Is Offer",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2022-05-17 01:01:52.106645",
+ "modified": "2021-06-12 00:14:20.894553",
"module": null,
- "name": "POS Profile-posa_new_line",
+ "name": "Sales Invoice Item-posa_is_offer",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -3228,7 +3283,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": null,
- "read_only": 0,
+ "read_only": 1,
"read_only_depends_on": null,
"report_hide": 0,
"reqd": 0,
@@ -3250,10 +3305,10 @@
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "Sales Invoice Item",
+ "dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_offer_applied",
+ "fieldname": "posa_allow_write_off_change",
"fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
@@ -3265,15 +3320,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_offers",
+ "insert_after": "posa_display_additional_notes",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Offer Applied",
+ "label": "Allow Write Off Change",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-06-12 00:12:28.473489",
+ "modified": "2022-02-12 04:26:04.003374",
"module": null,
- "name": "Sales Invoice Item-posa_offer_applied",
+ "name": "POS Profile-posa_allow_write_off_change",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -3282,7 +3337,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": null,
- "read_only": 1,
+ "read_only": 0,
"read_only_depends_on": null,
"report_hide": 0,
"reqd": 0,
@@ -3299,16 +3354,16 @@
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
- "default": "0",
- "depends_on": null,
+ "default": null,
+ "depends_on": "",
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "POS Profile",
+ "dt": "Sales Invoice Item",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_input_qty",
- "fieldtype": "Check",
+ "fieldname": "posa_is_replace",
+ "fieldtype": "Data",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -3319,15 +3374,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_new_line",
+ "insert_after": "posa_is_offer",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Use QTY Input",
+ "label": "Is Offer Replace For item Row ID",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2022-05-17 02:17:13.591004",
+ "modified": "2021-06-17 18:10:36.233226",
"module": null,
- "name": "POS Profile-posa_input_qty",
+ "name": "Sales Invoice Item-posa_is_replace",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -3336,13 +3391,13 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": null,
- "read_only": 0,
+ "read_only": 1,
"read_only_depends_on": null,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"sort_options": 0,
- "translatable": 0,
+ "translatable": 1,
"unique": 0,
"width": null
},
@@ -3353,15 +3408,15 @@
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
- "default": null,
+ "default": "0",
"depends_on": null,
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "Sales Invoice Item",
+ "dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_is_offer",
+ "fieldname": "posa_new_line",
"fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
@@ -3370,18 +3425,18 @@
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_global_search": 0,
- "in_list_view": 1,
+ "in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_offer_applied",
+ "insert_after": "posa_allow_write_off_change",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Is Offer",
+ "label": "Allow add New Items on New Line",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-06-12 00:14:20.894553",
+ "modified": "2022-05-17 01:01:52.106645",
"module": null,
- "name": "Sales Invoice Item-posa_is_offer",
+ "name": "POS Profile-posa_new_line",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -3390,7 +3445,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": null,
- "read_only": 1,
+ "read_only": 0,
"read_only_depends_on": null,
"report_hide": 0,
"reqd": 0,
@@ -3407,7 +3462,7 @@
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
- "default": null,
+ "default": "0",
"depends_on": null,
"description": null,
"docstatus": 0,
@@ -3415,7 +3470,7 @@
"dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_allow_print_draft_invoices",
+ "fieldname": "posa_input_qty",
"fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
@@ -3427,15 +3482,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_input_qty",
+ "insert_after": "posa_new_line",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Allow Print Draft Invoices",
+ "label": "Use QTY Input",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2022-07-22 11:51:07.782265",
+ "modified": "2022-05-17 02:17:13.591004",
"module": null,
- "name": "POS Profile-posa_allow_print_draft_invoices",
+ "name": "POS Profile-posa_input_qty",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -3462,15 +3517,15 @@
"collapsible_depends_on": null,
"columns": 0,
"default": null,
- "depends_on": "",
+ "depends_on": null,
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "Sales Invoice Item",
+ "dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_is_replace",
- "fieldtype": "Data",
+ "fieldname": "posa_allow_print_draft_invoices",
+ "fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -3481,15 +3536,15 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_is_offer",
+ "insert_after": "posa_input_qty",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Is Offer Replace For item Row ID",
+ "label": "Allow Print Draft Invoices",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-06-17 18:10:36.233226",
+ "modified": "2022-07-22 11:51:07.782265",
"module": null,
- "name": "Sales Invoice Item-posa_is_replace",
+ "name": "POS Profile-posa_allow_print_draft_invoices",
"no_copy": 0,
"non_negative": 0,
"options": null,
@@ -3498,13 +3553,13 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": null,
- "read_only": 1,
+ "read_only": 0,
"read_only_depends_on": null,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"sort_options": 0,
- "translatable": 1,
+ "translatable": 0,
"unique": 0,
"width": null
},
@@ -4168,11 +4223,11 @@
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "POS Profile",
- "fetch_from": null,
- "fetch_if_empty": 0,
- "fieldname": "posa_search_batch_no",
- "fieldtype": "Check",
+ "dt": "Sales Invoice",
+ "fetch_from": "shipping_address_name.posa_delivery_charges",
+ "fetch_if_empty": 1,
+ "fieldname": "posa_delivery_charges",
+ "fieldtype": "Link",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -4183,18 +4238,18 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_search_serial_no",
+ "insert_after": "taxes_and_charges",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Search by Batch Number",
+ "label": "Delivery Charges",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2023-06-05 23:50:13.126933",
+ "modified": "2022-07-25 11:49:02.312879",
"module": null,
- "name": "POS Profile-posa_search_batch_no",
+ "name": "Sales Invoice-posa_delivery_charges",
"no_copy": 0,
"non_negative": 0,
- "options": null,
+ "options": "Delivery Charges",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -4222,11 +4277,11 @@
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "Sales Invoice",
- "fetch_from": "shipping_address_name.posa_delivery_charges",
- "fetch_if_empty": 1,
- "fieldname": "posa_delivery_charges",
- "fieldtype": "Link",
+ "dt": "POS Profile",
+ "fetch_from": null,
+ "fetch_if_empty": 0,
+ "fieldname": "posa_search_batch_no",
+ "fieldtype": "Check",
"hidden": 0,
"hide_border": 0,
"hide_days": 0,
@@ -4237,18 +4292,18 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "taxes_and_charges",
+ "insert_after": "posa_search_serial_no",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Delivery Charges",
+ "label": "Search by Batch Number",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2022-07-25 11:49:02.312879",
+ "modified": "2023-06-05 23:50:13.126933",
"module": null,
- "name": "Sales Invoice-posa_delivery_charges",
+ "name": "POS Profile-posa_search_batch_no",
"no_copy": 0,
"non_negative": 0,
- "options": "Delivery Charges",
+ "options": null,
"permlevel": 0,
"precision": "",
"print_hide": 0,
@@ -4271,17 +4326,17 @@
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
- "default": "1",
+ "default": null,
"depends_on": null,
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "POS Profile",
+ "dt": "Sales Invoice",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_tax_inclusive",
- "fieldtype": "Check",
- "hidden": 0,
+ "fieldname": "posa_delivery_charges_rate",
+ "fieldtype": "Currency",
+ "hidden": 1,
"hide_border": 0,
"hide_days": 0,
"hide_seconds": 0,
@@ -4291,24 +4346,24 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_search_batch_no",
+ "insert_after": "posa_delivery_charges",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Tax Inclusive",
+ "label": "Delivery Charges Rate",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2021-09-06 16:33:33.398280",
+ "modified": "2022-07-25 11:49:04.797031",
"module": null,
- "name": "POS Profile-posa_tax_inclusive",
+ "name": "Sales Invoice-posa_delivery_charges_rate",
"no_copy": 0,
"non_negative": 0,
- "options": null,
+ "options": "currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": null,
- "read_only": 0,
+ "read_only": 1,
"read_only_depends_on": null,
"report_hide": 0,
"reqd": 0,
@@ -4325,17 +4380,17 @@
"collapsible": 0,
"collapsible_depends_on": null,
"columns": 0,
- "default": null,
+ "default": "1",
"depends_on": null,
"description": null,
"docstatus": 0,
"doctype": "Custom Field",
- "dt": "Sales Invoice",
+ "dt": "POS Profile",
"fetch_from": null,
"fetch_if_empty": 0,
- "fieldname": "posa_delivery_charges_rate",
- "fieldtype": "Currency",
- "hidden": 1,
+ "fieldname": "posa_tax_inclusive",
+ "fieldtype": "Check",
+ "hidden": 0,
"hide_border": 0,
"hide_days": 0,
"hide_seconds": 0,
@@ -4345,24 +4400,24 @@
"in_list_view": 0,
"in_preview": 0,
"in_standard_filter": 0,
- "insert_after": "posa_delivery_charges",
+ "insert_after": "posa_search_batch_no",
"is_system_generated": 0,
"is_virtual": 0,
- "label": "Delivery Charges Rate",
+ "label": "Tax Inclusive",
"length": 0,
"mandatory_depends_on": null,
- "modified": "2022-07-25 11:49:04.797031",
+ "modified": "2021-09-06 16:33:33.398280",
"module": null,
- "name": "Sales Invoice-posa_delivery_charges_rate",
+ "name": "POS Profile-posa_tax_inclusive",
"no_copy": 0,
"non_negative": 0,
- "options": "currency",
+ "options": null,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"print_width": null,
- "read_only": 1,
+ "read_only": 0,
"read_only_depends_on": null,
"report_hide": 0,
"reqd": 0,
diff --git a/posawesome/hooks.py b/posawesome/hooks.py
index 75158395d..daeac3f0d 100644
--- a/posawesome/hooks.py
+++ b/posawesome/hooks.py
@@ -257,6 +257,7 @@
"POS Profile-posa_allow_reconcile_payments",
"POS Profile-column_break_uolvm",
"POS Profile-posa_allow_mpesa_reconcile_payments",
+ "POS Profile-custom_pezesha_channel_id",
),
]
],
@@ -265,4 +266,10 @@
"doctype": "Property Setter",
"filters": [["name", "in", ("Sales Invoice-posa_pos_opening_shift-no_copy")]],
},
+
]
+scheduler_events = {
+ "daily": [
+ "posawesome.posawesome.doctype.pezesha_settings.pezesha_settings.corn"
+ ]
+}
diff --git a/posawesome/posawesome/api/payment_entry.py b/posawesome/posawesome/api/payment_entry.py
index c7472615e..648bc149e 100644
--- a/posawesome/posawesome/api/payment_entry.py
+++ b/posawesome/posawesome/api/payment_entry.py
@@ -15,6 +15,75 @@
from erpnext.accounts.utils import QueryPaymentLedger, get_outstanding_invoices as _get_outstanding_invoices
+# def create_payment_entry(
+# company,
+# customer,
+# amount,
+# currency,
+# mode_of_payment,
+# reference_date=None,
+# reference_no=None,
+# posting_date=None,
+# cost_center=None,
+# submit=0,
+# ):
+# # TODO : need to have a better way to handle currency
+# date = nowdate() if not posting_date else posting_date
+# party_type = "Customer"
+# party_account = get_party_account(party_type, customer, company)
+# party_account_currency = get_account_currency(party_account)
+# if party_account_currency != currency:
+# frappe.throw(
+# _(
+# "Currency is not correct, party account currency is {party_account_currency} and transaction currency is {currency}"
+# ).format(party_account_currency=party_account_currency, currency=currency)
+# )
+# payment_type = "Receive"
+
+# bank = get_bank_cash_account(company, mode_of_payment)
+# company_currency = frappe.get_value("Company", company, "default_currency")
+# conversion_rate = get_exchange_rate(currency, company_currency, date, "for_selling")
+# paid_amount, received_amount = set_paid_amount_and_received_amount(
+# party_account_currency, bank, amount, payment_type, None, conversion_rate
+# )
+
+# pe = frappe.new_doc("Payment Entry")
+# pe.payment_type = payment_type
+# pe.company = company
+# pe.cost_center = cost_center or erpnext.get_default_cost_center(company)
+# pe.posting_date = date
+# pe.mode_of_payment = mode_of_payment
+# pe.party_type = party_type
+# pe.party = customer
+
+# pe.paid_from = party_account if payment_type == "Receive" else bank.account
+# pe.paid_to = party_account if payment_type == "Pay" else bank.account
+# pe.paid_from_account_currency = (
+# party_account_currency if payment_type == "Receive" else bank.account_currency
+# )
+# pe.paid_to_account_currency = (
+# party_account_currency if payment_type == "Pay" else bank.account_currency
+# )
+# pe.paid_amount = paid_amount
+# pe.received_amount = received_amount
+# pe.letter_head = frappe.get_value("Company", company, "default_letter_head")
+# pe.reference_date = reference_date
+# pe.reference_no = reference_no
+# if pe.party_type in ["Customer", "Supplier"]:
+# bank_account = get_party_bank_account(pe.party_type, pe.party)
+# pe.set("bank_account", bank_account)
+# pe.set_bank_account_data()
+
+# pe.setup_party_account_field()
+# pe.set_missing_values()
+
+# if party_account and bank:
+# pe.set_amounts()
+# if submit:
+# pe.docstatus = 1
+# pe.insert(ignore_permissions=True)
+# return pe
+
def create_payment_entry(
company,
customer,
@@ -27,22 +96,34 @@ def create_payment_entry(
cost_center=None,
submit=0,
):
- # TODO : need to have a better way to handle currency
- date = nowdate() if not posting_date else posting_date
+ # Use local variables to minimize repeated DB calls
+ date = posting_date or nowdate()
party_type = "Customer"
+
+ # Fetch party account and currency in one go
party_account = get_party_account(party_type, customer, company)
party_account_currency = get_account_currency(party_account)
if party_account_currency != currency:
frappe.throw(
- _(
- "Currency is not correct, party account currency is {party_account_currency} and transaction currency is {currency}"
- ).format(party_account_currency=party_account_currency, currency=currency)
+ _("Currency is not correct, party account currency is {party_account_currency} and transaction currency is {currency}")
+ .format(party_account_currency=party_account_currency, currency=currency)
)
+
payment_type = "Receive"
+ # Get bank/cash account only once
bank = get_bank_cash_account(company, mode_of_payment)
- company_currency = frappe.get_value("Company", company, "default_currency")
+ if not bank:
+ frappe.throw(_("No Bank or Cash account found for mode of payment {0}").format(mode_of_payment))
+
+ # Fetch company values in a single call
+ company_doc = frappe.get_cached_doc("Company", company)
+ company_currency = company_doc.default_currency
+ letter_head = company_doc.default_letter_head
+
+ # Use cached exchange rate if possible
conversion_rate = get_exchange_rate(currency, company_currency, date, "for_selling")
+
paid_amount, received_amount = set_paid_amount_and_received_amount(
party_account_currency, bank, amount, payment_type, None, conversion_rate
)
@@ -66,14 +147,18 @@ def create_payment_entry(
)
pe.paid_amount = paid_amount
pe.received_amount = received_amount
- pe.letter_head = frappe.get_value("Company", company, "default_letter_head")
+ pe.letter_head = letter_head
pe.reference_date = reference_date
pe.reference_no = reference_no
- if pe.party_type in ["Customer", "Supplier"]:
+
+ # Only fetch bank account if needed
+ if pe.party_type in ("Customer", "Supplier"):
bank_account = get_party_bank_account(pe.party_type, pe.party)
- pe.set("bank_account", bank_account)
- pe.set_bank_account_data()
+ if bank_account:
+ pe.set("bank_account", bank_account)
+ pe.set_bank_account_data()
+ # Minimize method calls
pe.setup_party_account_field()
pe.set_missing_values()
@@ -81,10 +166,11 @@ def create_payment_entry(
pe.set_amounts()
if submit:
pe.docstatus = 1
+
+ # Use insert with minimal overhead
pe.insert(ignore_permissions=True)
return pe
-
def get_bank_cash_account(company, mode_of_payment, bank_account=None):
bank = get_default_bank_cash_account(
company, "Bank", mode_of_payment=mode_of_payment, account=bank_account
@@ -222,6 +308,201 @@ def get_unallocated_payments(customer, company, currency, mode_of_payment=None):
return unallocated_payment
+# @frappe.whitelist()
+# def process_pos_payment(payload):
+# data = json.loads(payload)
+# data = frappe._dict(data)
+# if not data.pos_profile.get("posa_use_pos_awesome_payments"):
+# frappe.throw(_("POS Awesome Payments is not enabled for this POS Profile"))
+
+# # validate data
+# if not data.customer:
+# frappe.throw(_("Customer is required"))
+# if not data.company:
+# frappe.throw(_("Company is required"))
+# if not data.currency:
+# frappe.throw(_("Currency is required"))
+# if not data.pos_profile_name:
+# frappe.throw(_("POS Profile is required"))
+# if not data.pos_opening_shift_name:
+# frappe.throw(_("POS Opening Shift is required"))
+
+# company = data.company
+# currency = data.currency
+# customer = data.customer
+# pos_opening_shift_name = data.pos_opening_shift_name
+# allow_make_new_payments = data.pos_profile.get("posa_allow_make_new_payments")
+# allow_reconcile_payments = data.pos_profile.get("posa_allow_reconcile_payments")
+# allow_mpesa_reconcile_payments = data.pos_profile.get(
+# "posa_allow_mpesa_reconcile_payments"
+# )
+# today = nowdate()
+
+# new_payments_entry = []
+# all_payments_entry = []
+# errors = []
+# reconcile_doc = None
+
+# # first process mpesa payments
+# if (
+# allow_mpesa_reconcile_payments
+# and len(data.selected_mpesa_payments) > 0
+# and data.total_selected_mpesa_payments > 0
+# ):
+# for mpesa_payment in data.selected_mpesa_payments:
+# try:
+# new_mpesa_payment = submit_mpesa_payment(
+# mpesa_payment.get("name"), customer
+# )
+# new_payments_entry.append(new_mpesa_payment)
+# all_payments_entry.append(new_mpesa_payment)
+# except Exception as e:
+# errors.append(e)
+
+# # then process the new payments
+# if (
+# allow_make_new_payments
+# and len(data.payment_methods) > 0
+# and data.total_payment_methods > 0
+# ):
+# for payment_method in data.payment_methods:
+# try:
+# if not payment_method.get("amount"):
+# continue
+# new_payment_entry = create_payment_entry(
+# company=company,
+# customer=customer,
+# currency=currency,
+# amount=flt(payment_method.get("amount")),
+# mode_of_payment=payment_method.get("mode_of_payment"),
+# posting_date=today,
+# reference_no=pos_opening_shift_name,
+# reference_date=today,
+# cost_center=data.pos_profile.get("cost_center"),
+# submit=1,
+# )
+# new_payments_entry.append(new_payment_entry)
+# all_payments_entry.append(new_payment_entry)
+# except Exception as e:
+# errors.append(e)
+
+# # then then reconcile the new payments and the unallocated payments with the outstanding invoices
+# if len(data.selected_invoices) > 0 and data.total_selected_invoices > 0:
+# if (
+# allow_reconcile_payments
+# and len(data.selected_payments) > 0
+# and data.total_selected_payments > 0
+# ):
+# # add the unallocated payments to the all payments entry
+# for selected_payment in data.selected_payments:
+# all_payments_entry.append(selected_payment)
+
+# if len(all_payments_entry) > 0:
+# # sort the all payments entry by posting date
+# all_payments_entry = sorted(
+# all_payments_entry,
+# key=lambda k: getdate(str(k.get("posting_date"))),
+# reverse=True,
+# )
+# all_invoices_list = sorted(
+# data.selected_invoices,
+# key=lambda k: getdate(k.get("posting_date")),
+# reverse=True,
+# )
+# reconcile_doc = frappe.new_doc("Payment Reconciliation")
+# reconcile_doc.party_type = "Customer"
+# reconcile_doc.party = customer
+# reconcile_doc.company = company
+# reconcile_doc.receivable_payable_account = get_party_account(
+# "Customer", customer, company
+# )
+# reconcile_doc.get_unreconciled_entries()
+# args = {
+# "invoices": [],
+# "payments": [],
+# }
+# for invoice in all_invoices_list:
+# args["invoices"].append(
+# {
+# "invoice_type": "Sales Invoice",
+# "invoice_number": invoice.get("name"),
+# "invoice_date": invoice.get("posting_date"),
+# "amount": invoice.get("grand_total"),
+# "outstanding_amount": invoice.get("outstanding_amount"),
+# "currency": invoice.get("currency"),
+# "exchange_rate": 0,
+# }
+# )
+# for payment in all_payments_entry:
+# args["payments"].append(
+# {
+# "reference_type": "Payment Entry",
+# "reference_name": payment.get("name"),
+# "posting_date": payment.get("posting_date"),
+# "amount": payment.get("unallocated_amount"),
+# "unallocated_amount": payment.get("unallocated_amount"),
+# "difference_amount": 0,
+# "currency": payment.get("currency"),
+# "exchange_rate": 0,
+# }
+# )
+# reconcile_doc.allocate_entries(args)
+# reconcile_doc.reconcile()
+
+# # then show the results
+# msg = ""
+# if len(new_payments_entry) > 0:
+# msg += "
New Payments
"
+# msg += ""
+# msg += "| Payment Entry | Amount |
"
+# msg += ""
+# for payment_entry in new_payments_entry:
+# msg += "| {0} | {1} |
".format(
+# payment_entry.get("name"), payment_entry.get("unallocated_amount")
+# )
+# msg += ""
+# msg += "
"
+# if len(all_payments_entry) > 0 and len(data.selected_invoices) > 0:
+# msg += "Reconciled Payments
"
+# msg += ""
+# msg += "| Payment Entry | Amount |
"
+# msg += ""
+# for payment_entry in all_payments_entry:
+# msg += "| {0} | {1} |
".format(
+# payment_entry.get("name"), payment_entry.get("unallocated_amount")
+# )
+# msg += ""
+# msg += "
"
+# if len(data.selected_invoices) > 0 and data.total_selected_invoices > 0:
+# msg += "Reconciled Invoices
"
+# msg += ""
+# msg += "| Invoice | Amount |
"
+# msg += ""
+# for invoice in data.selected_invoices:
+# msg += "| {0} | {1} |
".format(
+# invoice.get("name"), invoice.get("outstanding_amount")
+# )
+# msg += ""
+# msg += "
"
+# if len(errors) > 0:
+# msg += "Errors
"
+# msg += ""
+# msg += "| Error |
"
+# msg += ""
+# for error in errors:
+# msg += "| {0} |
".format(error)
+# msg += ""
+# msg += "
"
+# if len(msg) > 0:
+# frappe.msgprint(msg)
+
+# return {
+# "new_payments_entry": new_payments_entry,
+# "all_payments_entry": all_payments_entry,
+# "errors": errors,
+# "reconcile_doc": reconcile_doc,
+# }
+
@frappe.whitelist()
def process_pos_payment(payload):
data = json.loads(payload)
@@ -229,27 +510,26 @@ def process_pos_payment(payload):
if not data.pos_profile.get("posa_use_pos_awesome_payments"):
frappe.throw(_("POS Awesome Payments is not enabled for this POS Profile"))
- # validate data
- if not data.customer:
- frappe.throw(_("Customer is required"))
- if not data.company:
- frappe.throw(_("Company is required"))
- if not data.currency:
- frappe.throw(_("Currency is required"))
- if not data.pos_profile_name:
- frappe.throw(_("POS Profile is required"))
- if not data.pos_opening_shift_name:
- frappe.throw(_("POS Opening Shift is required"))
+ # Validate required fields early
+ required_fields = [
+ ("customer", _("Customer is required")),
+ ("company", _("Company is required")),
+ ("currency", _("Currency is required")),
+ ("pos_profile_name", _("POS Profile is required")),
+ ("pos_opening_shift_name", _("POS Opening Shift is required")),
+ ]
+ for field, error_msg in required_fields:
+ if not data.get(field):
+ frappe.throw(error_msg)
company = data.company
currency = data.currency
customer = data.customer
pos_opening_shift_name = data.pos_opening_shift_name
- allow_make_new_payments = data.pos_profile.get("posa_allow_make_new_payments")
- allow_reconcile_payments = data.pos_profile.get("posa_allow_reconcile_payments")
- allow_mpesa_reconcile_payments = data.pos_profile.get(
- "posa_allow_mpesa_reconcile_payments"
- )
+ pos_profile = data.pos_profile
+ allow_make_new_payments = pos_profile.get("posa_allow_make_new_payments")
+ allow_reconcile_payments = pos_profile.get("posa_allow_reconcile_payments")
+ allow_mpesa_reconcile_payments = pos_profile.get("posa_allow_mpesa_reconcile_payments")
today = nowdate()
new_payments_entry = []
@@ -257,86 +537,67 @@ def process_pos_payment(payload):
errors = []
reconcile_doc = None
- # first process mpesa payments
- if (
- allow_mpesa_reconcile_payments
- and len(data.selected_mpesa_payments) > 0
- and data.total_selected_mpesa_payments > 0
- ):
- for mpesa_payment in data.selected_mpesa_payments:
+ # --- 1. Batch process MPESA payments ---
+ mpesa_payments = data.get("selected_mpesa_payments") or []
+ if allow_mpesa_reconcile_payments and mpesa_payments and data.get("total_selected_mpesa_payments", 0) > 0:
+ for mpesa_payment in mpesa_payments:
try:
- new_mpesa_payment = submit_mpesa_payment(
- mpesa_payment.get("name"), customer
- )
+ new_mpesa_payment = submit_mpesa_payment(mpesa_payment.get("name"), customer)
new_payments_entry.append(new_mpesa_payment)
all_payments_entry.append(new_mpesa_payment)
except Exception as e:
- errors.append(e)
-
- # then process the new payments
- if (
- allow_make_new_payments
- and len(data.payment_methods) > 0
- and data.total_payment_methods > 0
- ):
- for payment_method in data.payment_methods:
+ errors.append(str(e))
+
+ # --- 2. Batch process new payments ---
+ payment_methods = data.get("payment_methods") or []
+ if allow_make_new_payments and payment_methods and data.get("total_payment_methods", 0) > 0:
+ for payment_method in payment_methods:
try:
- if not payment_method.get("amount"):
+ amount = flt(payment_method.get("amount"))
+ if not amount:
continue
new_payment_entry = create_payment_entry(
company=company,
customer=customer,
currency=currency,
- amount=flt(payment_method.get("amount")),
+ amount=amount,
mode_of_payment=payment_method.get("mode_of_payment"),
posting_date=today,
reference_no=pos_opening_shift_name,
reference_date=today,
- cost_center=data.pos_profile.get("cost_center"),
+ cost_center=pos_profile.get("cost_center"),
submit=1,
)
new_payments_entry.append(new_payment_entry)
all_payments_entry.append(new_payment_entry)
except Exception as e:
- errors.append(e)
-
- # then then reconcile the new payments and the unallocated payments with the outstanding invoices
- if len(data.selected_invoices) > 0 and data.total_selected_invoices > 0:
- if (
- allow_reconcile_payments
- and len(data.selected_payments) > 0
- and data.total_selected_payments > 0
- ):
- # add the unallocated payments to the all payments entry
- for selected_payment in data.selected_payments:
- all_payments_entry.append(selected_payment)
-
- if len(all_payments_entry) > 0:
- # sort the all payments entry by posting date
- all_payments_entry = sorted(
- all_payments_entry,
- key=lambda k: getdate(str(k.get("posting_date"))),
- reverse=True,
- )
- all_invoices_list = sorted(
- data.selected_invoices,
- key=lambda k: getdate(k.get("posting_date")),
- reverse=True,
- )
+ errors.append(str(e))
+
+ # --- 3. Reconcile payments and invoices ---
+ selected_invoices = data.get("selected_invoices") or []
+ if selected_invoices and data.get("total_selected_invoices", 0) > 0:
+ # Add unallocated payments if allowed
+ if allow_reconcile_payments:
+ selected_payments = data.get("selected_payments") or []
+ if selected_payments and data.get("total_selected_payments", 0) > 0:
+ all_payments_entry.extend(selected_payments)
+
+ if all_payments_entry:
+ # Sort only if more than 1 entry (avoid unnecessary sort)
+ if len(all_payments_entry) > 1:
+ all_payments_entry.sort(key=lambda k: getdate(str(k.get("posting_date"))), reverse=True)
+ if len(selected_invoices) > 1:
+ selected_invoices.sort(key=lambda k: getdate(k.get("posting_date")), reverse=True)
+
reconcile_doc = frappe.new_doc("Payment Reconciliation")
reconcile_doc.party_type = "Customer"
reconcile_doc.party = customer
reconcile_doc.company = company
- reconcile_doc.receivable_payable_account = get_party_account(
- "Customer", customer, company
- )
+ reconcile_doc.receivable_payable_account = get_party_account("Customer", customer, company)
reconcile_doc.get_unreconciled_entries()
+
args = {
- "invoices": [],
- "payments": [],
- }
- for invoice in all_invoices_list:
- args["invoices"].append(
+ "invoices": [
{
"invoice_type": "Sales Invoice",
"invoice_number": invoice.get("name"),
@@ -346,9 +607,9 @@ def process_pos_payment(payload):
"currency": invoice.get("currency"),
"exchange_rate": 0,
}
- )
- for payment in all_payments_entry:
- args["payments"].append(
+ for invoice in selected_invoices
+ ],
+ "payments": [
{
"reference_type": "Payment Entry",
"reference_name": payment.get("name"),
@@ -359,56 +620,49 @@ def process_pos_payment(payload):
"currency": payment.get("currency"),
"exchange_rate": 0,
}
- )
+ for payment in all_payments_entry
+ ],
+ }
reconcile_doc.allocate_entries(args)
reconcile_doc.reconcile()
- # then show the results
- msg = ""
- if len(new_payments_entry) > 0:
- msg += "New Payments
"
- msg += ""
- msg += "| Payment Entry | Amount |
"
- msg += ""
- for payment_entry in new_payments_entry:
- msg += "| {0} | {1} |
".format(
- payment_entry.get("name"), payment_entry.get("unallocated_amount")
- )
- msg += ""
- msg += "
"
- if len(all_payments_entry) > 0 and len(data.selected_invoices) > 0:
- msg += "Reconciled Payments
"
- msg += ""
- msg += "| Payment Entry | Amount |
"
- msg += ""
- for payment_entry in all_payments_entry:
- msg += "| {0} | {1} |
".format(
- payment_entry.get("name"), payment_entry.get("unallocated_amount")
- )
- msg += ""
- msg += "
"
- if len(data.selected_invoices) > 0 and data.total_selected_invoices > 0:
- msg += "Reconciled Invoices
"
- msg += ""
- msg += "| Invoice | Amount |
"
- msg += ""
- for invoice in data.selected_invoices:
- msg += "| {0} | {1} |
".format(
- invoice.get("name"), invoice.get("outstanding_amount")
- )
- msg += ""
- msg += "
"
- if len(errors) > 0:
- msg += "Errors
"
- msg += ""
- msg += "| Error |
"
- msg += ""
- for error in errors:
- msg += "| {0} |
".format(error)
- msg += ""
- msg += "
"
- if len(msg) > 0:
- frappe.msgprint(msg)
+ # --- 4. Build HTML message efficiently ---
+ def build_table(title, headers, rows):
+ html = f"{title}
"
+ html += "".join(f"| {h} | " for h in headers)
+ html += "
"
+ for row in rows:
+ html += "" + "".join(f"| {c} | " for c in row) + "
"
+ html += "
"
+ return html
+
+ msg_parts = []
+ if new_payments_entry:
+ msg_parts.append(build_table(
+ "New Payments",
+ ["Payment Entry", "Amount"],
+ [(pe.get("name"), pe.get("unallocated_amount")) for pe in new_payments_entry]
+ ))
+ if all_payments_entry and selected_invoices:
+ msg_parts.append(build_table(
+ "Reconciled Payments",
+ ["Payment Entry", "Amount"],
+ [(pe.get("name"), pe.get("unallocated_amount")) for pe in all_payments_entry]
+ ))
+ if selected_invoices and data.get("total_selected_invoices", 0) > 0:
+ msg_parts.append(build_table(
+ "Reconciled Invoices",
+ ["Invoice", "Amount"],
+ [(inv.get("name"), inv.get("outstanding_amount")) for inv in selected_invoices]
+ ))
+ if errors:
+ msg_parts.append(build_table(
+ "Errors",
+ ["Error"],
+ [(e,) for e in errors]
+ ))
+ if msg_parts:
+ frappe.msgprint("".join(msg_parts))
return {
"new_payments_entry": new_payments_entry,
@@ -417,7 +671,6 @@ def process_pos_payment(payload):
"reconcile_doc": reconcile_doc,
}
-
@frappe.whitelist()
def get_available_pos_profiles(company, currency):
pos_profiles_list = frappe.get_list(
diff --git a/posawesome/posawesome/api/posapp.py b/posawesome/posawesome/api/posapp.py
index d92dacafc..a597f0430 100644
--- a/posawesome/posawesome/api/posapp.py
+++ b/posawesome/posawesome/api/posapp.py
@@ -126,6 +126,213 @@ def update_opening_shift_data(data, pos_profile):
data["stock_settings"].update({"allow_negative_stock": allow_negative_stock})
+# @frappe.whitelist()
+# def get_items(
+# pos_profile, price_list=None, item_group="", search_value="", customer=None
+# ):
+# _pos_profile = json.loads(pos_profile)
+# ttl = _pos_profile.get("posa_server_cache_duration")
+# if ttl:
+# ttl = int(ttl) * 30
+
+# @redis_cache(ttl=ttl or 1800)
+# def __get_items(pos_profile, price_list, item_group, search_value, customer=None):
+# return _get_items(pos_profile, price_list, item_group, search_value, customer)
+
+# def _get_items(pos_profile, price_list, item_group, search_value, customer=None):
+# pos_profile = json.loads(pos_profile)
+# today = nowdate()
+# data = dict()
+# posa_display_items_in_stock = pos_profile.get("posa_display_items_in_stock")
+# search_serial_no = pos_profile.get("posa_search_serial_no")
+# search_batch_no = pos_profile.get("posa_search_batch_no")
+# posa_show_template_items = pos_profile.get("posa_show_template_items")
+# warehouse = pos_profile.get("warehouse")
+# use_limit_search = pos_profile.get("pose_use_limit_search")
+# search_limit = 0
+
+# if not price_list:
+# price_list = pos_profile.get("selling_price_list")
+
+# limit = ""
+
+# condition = ""
+# condition += get_item_group_condition(pos_profile.get("name"))
+
+# if use_limit_search:
+# search_limit = pos_profile.get("posa_search_limit") or 500
+# if search_value:
+# data = search_serial_or_batch_or_barcode_number(
+# search_value, search_serial_no
+# )
+
+# item_code = data.get("item_code") if data.get("item_code") else search_value
+# serial_no = data.get("serial_no") if data.get("serial_no") else ""
+# batch_no = data.get("batch_no") if data.get("batch_no") else ""
+# barcode = data.get("barcode") if data.get("barcode") else ""
+
+# condition += get_seearch_items_conditions(
+# item_code, serial_no, batch_no, barcode
+# )
+# if item_group:
+# condition += " AND item_group like '%{item_group}%'".format(
+# item_group=item_group
+# )
+# limit = " LIMIT {search_limit}".format(search_limit=search_limit)
+
+# if not posa_show_template_items:
+# condition += " AND has_variants = 0"
+
+# result = []
+
+# items_data = frappe.db.sql(
+# """
+# SELECT
+# name AS item_code,
+# item_name,
+# description,
+# stock_uom,
+# image,
+# is_stock_item,
+# has_variants,
+# variant_of,
+# item_group,
+# idx as idx,
+# has_batch_no,
+# has_serial_no,
+# max_discount,
+# brand
+# FROM
+# `tabItem`
+# WHERE
+# disabled = 0
+# AND is_sales_item = 1
+# AND is_fixed_asset = 0
+# {condition}
+# ORDER BY
+# item_name asc
+# {limit}
+# """.format(
+# condition=condition, limit=limit
+# ),
+# as_dict=1,
+# )
+
+# if items_data:
+# items = [d.item_code for d in items_data]
+# item_prices_data = frappe.get_all(
+# "Item Price",
+# fields=["item_code", "price_list_rate", "currency", "uom"],
+# filters={
+# "price_list": price_list,
+# "item_code": ["in", items],
+# "currency": pos_profile.get("currency"),
+# "selling": 1,
+# "valid_from": ["<=", today],
+# "customer": ["in", ["", None, customer]],
+# },
+# or_filters=[
+# ["valid_upto", ">=", today],
+# ["valid_upto", "in", ["", None]],
+# ],
+# order_by="valid_from ASC, valid_upto DESC",
+# )
+
+# item_prices = {}
+# for d in item_prices_data:
+# item_prices.setdefault(d.item_code, {})
+# item_prices[d.item_code][d.get("uom") or "None"] = d
+
+# for item in items_data:
+# item_code = item.item_code
+# item_price = {}
+# if item_prices.get(item_code):
+# item_price = (
+# item_prices.get(item_code).get(item.stock_uom)
+# or item_prices.get(item_code).get("None")
+# or {}
+# )
+# item_barcode = frappe.get_all(
+# "Item Barcode",
+# filters={"parent": item_code},
+# fields=["barcode", "posa_uom"],
+# )
+# batch_no_data = []
+# if search_batch_no:
+# batch_list = get_batch_qty(warehouse=warehouse, item_code=item_code)
+# if batch_list:
+# for batch in batch_list:
+# if batch.qty > 0 and batch.batch_no:
+# batch_doc = frappe.get_cached_doc(
+# "Batch", batch.batch_no
+# )
+# if (
+# str(batch_doc.expiry_date) > str(today)
+# or batch_doc.expiry_date in ["", None]
+# ) and batch_doc.disabled == 0:
+# batch_no_data.append(
+# {
+# "batch_no": batch.batch_no,
+# "batch_qty": batch.qty,
+# "expiry_date": batch_doc.expiry_date,
+# "batch_price": batch_doc.posa_batch_price,
+# "manufacturing_date": batch_doc.manufacturing_date,
+# }
+# )
+# serial_no_data = []
+# if search_serial_no:
+# serial_no_data = frappe.get_all(
+# "Serial No",
+# filters={
+# "item_code": item_code,
+# "status": "Active",
+# "warehouse": warehouse,
+# },
+# fields=["name as serial_no"],
+# )
+# item_stock_qty = 0
+# if pos_profile.get("posa_display_items_in_stock") or use_limit_search:
+# item_stock_qty = get_stock_availability(
+# item_code, pos_profile.get("warehouse")
+# )
+# attributes = ""
+# if pos_profile.get("posa_show_template_items") and item.has_variants:
+# attributes = get_item_attributes(item.item_code)
+# item_attributes = ""
+# if pos_profile.get("posa_show_template_items") and item.variant_of:
+# item_attributes = frappe.get_all(
+# "Item Variant Attribute",
+# fields=["attribute", "attribute_value"],
+# filters={"parent": item.item_code, "parentfield": "attributes"},
+# )
+# if posa_display_items_in_stock and (
+# not item_stock_qty or item_stock_qty < 0
+# ):
+# pass
+# else:
+# row = {}
+# row.update(item)
+# row.update(
+# {
+# "rate": item_price.get("price_list_rate") or 0,
+# "currency": item_price.get("currency")
+# or pos_profile.get("currency"),
+# "item_barcode": item_barcode or [],
+# "actual_qty": item_stock_qty or 0,
+# "serial_no_data": serial_no_data or [],
+# "batch_no_data": batch_no_data or [],
+# "attributes": attributes or "",
+# "item_attributes": item_attributes or "",
+# }
+# )
+# result.append(row)
+# return result
+
+# if _pos_profile.get("posa_use_server_cache"):
+# return __get_items(pos_profile, price_list, item_group, search_value, customer)
+# else:
+# return _get_items(pos_profile, price_list, item_group, search_value, customer)
+
@frappe.whitelist()
def get_items(
pos_profile, price_list=None, item_group="", search_value="", customer=None
@@ -155,21 +362,22 @@ def _get_items(pos_profile, price_list, item_group, search_value, customer=None)
price_list = pos_profile.get("selling_price_list")
limit = ""
+ condition = get_item_group_condition(pos_profile.get("name"))
- condition = ""
- condition += get_item_group_condition(pos_profile.get("name"))
-
+ # Optimize search value handling
+ item_code, serial_no, batch_no, barcode = "", "", "", ""
if use_limit_search:
search_limit = pos_profile.get("posa_search_limit") or 500
if search_value:
data = search_serial_or_batch_or_barcode_number(
search_value, search_serial_no
)
-
- item_code = data.get("item_code") if data.get("item_code") else search_value
- serial_no = data.get("serial_no") if data.get("serial_no") else ""
- batch_no = data.get("batch_no") if data.get("batch_no") else ""
- barcode = data.get("barcode") if data.get("barcode") else ""
+ item_code = data.get("item_code") or search_value
+ serial_no = data.get("serial_no") or ""
+ batch_no = data.get("batch_no") or ""
+ barcode = data.get("barcode") or ""
+ else:
+ item_code = search_value
condition += get_seearch_items_conditions(
item_code, serial_no, batch_no, barcode
@@ -183,8 +391,7 @@ def _get_items(pos_profile, price_list, item_group, search_value, customer=None)
if not posa_show_template_items:
condition += " AND has_variants = 0"
- result = []
-
+ # Use a single SQL query to fetch all required item fields
items_data = frappe.db.sql(
"""
SELECT
@@ -218,122 +425,145 @@ def _get_items(pos_profile, price_list, item_group, search_value, customer=None)
as_dict=1,
)
- if items_data:
- items = [d.item_code for d in items_data]
- item_prices_data = frappe.get_all(
- "Item Price",
- fields=["item_code", "price_list_rate", "currency", "uom"],
+ if not items_data:
+ return []
+
+ items = [d.item_code for d in items_data]
+
+ # Batch fetch item prices
+ item_prices_data = frappe.get_all(
+ "Item Price",
+ fields=["item_code", "price_list_rate", "currency", "uom"],
+ filters={
+ "price_list": price_list,
+ "item_code": ["in", items],
+ "currency": pos_profile.get("currency"),
+ "selling": 1,
+ "valid_from": ["<=", today],
+ "customer": ["in", ["", None, customer]],
+ },
+ or_filters=[
+ ["valid_upto", ">=", today],
+ ["valid_upto", "in", ["", None]],
+ ],
+ order_by="valid_from ASC, valid_upto DESC",
+ )
+
+ # Build price lookup
+ item_prices = {}
+ for d in item_prices_data:
+ item_prices.setdefault(d.item_code, {})
+ item_prices[d.item_code][d.get("uom") or "None"] = d
+
+ # Batch fetch barcodes for all items
+ barcodes_map = {}
+ barcodes_data = frappe.get_all(
+ "Item Barcode",
+ filters={"parent": ["in", items]},
+ fields=["parent", "barcode", "posa_uom"],
+ )
+ for b in barcodes_data:
+ barcodes_map.setdefault(b.parent, []).append({"barcode": b.barcode, "posa_uom": b.posa_uom})
+
+ # Pre-fetch batch and serial data if needed
+ batch_map = {}
+ if search_batch_no:
+ for item_code in items:
+ batch_list = get_batch_qty(warehouse=warehouse, item_code=item_code)
+ batch_map[item_code] = []
+ if batch_list:
+ for batch in batch_list:
+ if batch.qty > 0 and batch.batch_no:
+ batch_doc = frappe.get_cached_doc("Batch", batch.batch_no)
+ if (
+ str(batch_doc.expiry_date) > str(today)
+ or batch_doc.expiry_date in ["", None]
+ ) and batch_doc.disabled == 0:
+ batch_map[item_code].append(
+ {
+ "batch_no": batch.batch_no,
+ "batch_qty": batch.qty,
+ "expiry_date": batch_doc.expiry_date,
+ "batch_price": batch_doc.posa_batch_price,
+ "manufacturing_date": batch_doc.manufacturing_date,
+ }
+ )
+
+ serial_map = {}
+ if search_serial_no:
+ serial_data = frappe.get_all(
+ "Serial No",
filters={
- "price_list": price_list,
"item_code": ["in", items],
- "currency": pos_profile.get("currency"),
- "selling": 1,
- "valid_from": ["<=", today],
- "customer": ["in", ["", None, customer]],
+ "status": "Active",
+ "warehouse": warehouse,
},
- or_filters=[
- ["valid_upto", ">=", today],
- ["valid_upto", "in", ["", None]],
- ],
- order_by="valid_from ASC, valid_upto DESC",
+ fields=["item_code", "name as serial_no"],
)
-
- item_prices = {}
- for d in item_prices_data:
- item_prices.setdefault(d.item_code, {})
- item_prices[d.item_code][d.get("uom") or "None"] = d
-
+ for s in serial_data:
+ serial_map.setdefault(s.item_code, []).append({"serial_no": s.serial_no})
+
+ # Batch fetch stock qty if needed
+ stock_qty_map = {}
+ if posa_display_items_in_stock or use_limit_search:
+ for item_code in items:
+ stock_qty_map[item_code] = get_stock_availability(item_code, warehouse)
+
+ # Batch fetch attributes if needed
+ attributes_map = {}
+ item_attributes_map = {}
+ if posa_show_template_items:
for item in items_data:
- item_code = item.item_code
- item_price = {}
- if item_prices.get(item_code):
- item_price = (
- item_prices.get(item_code).get(item.stock_uom)
- or item_prices.get(item_code).get("None")
- or {}
- )
- item_barcode = frappe.get_all(
- "Item Barcode",
- filters={"parent": item_code},
- fields=["barcode", "posa_uom"],
- )
- batch_no_data = []
- if search_batch_no:
- batch_list = get_batch_qty(warehouse=warehouse, item_code=item_code)
- if batch_list:
- for batch in batch_list:
- if batch.qty > 0 and batch.batch_no:
- batch_doc = frappe.get_cached_doc(
- "Batch", batch.batch_no
- )
- if (
- str(batch_doc.expiry_date) > str(today)
- or batch_doc.expiry_date in ["", None]
- ) and batch_doc.disabled == 0:
- batch_no_data.append(
- {
- "batch_no": batch.batch_no,
- "batch_qty": batch.qty,
- "expiry_date": batch_doc.expiry_date,
- "batch_price": batch_doc.posa_batch_price,
- "manufacturing_date": batch_doc.manufacturing_date,
- }
- )
- serial_no_data = []
- if search_serial_no:
- serial_no_data = frappe.get_all(
- "Serial No",
- filters={
- "item_code": item_code,
- "status": "Active",
- "warehouse": warehouse,
- },
- fields=["name as serial_no"],
- )
- item_stock_qty = 0
- if pos_profile.get("posa_display_items_in_stock") or use_limit_search:
- item_stock_qty = get_stock_availability(
- item_code, pos_profile.get("warehouse")
- )
- attributes = ""
- if pos_profile.get("posa_show_template_items") and item.has_variants:
- attributes = get_item_attributes(item.item_code)
- item_attributes = ""
- if pos_profile.get("posa_show_template_items") and item.variant_of:
- item_attributes = frappe.get_all(
+ if item.has_variants:
+ attributes_map[item.item_code] = get_item_attributes(item.item_code)
+ if item.variant_of:
+ item_attributes_map[item.item_code] = frappe.get_all(
"Item Variant Attribute",
fields=["attribute", "attribute_value"],
filters={"parent": item.item_code, "parentfield": "attributes"},
)
- if posa_display_items_in_stock and (
- not item_stock_qty or item_stock_qty < 0
- ):
- pass
- else:
- row = {}
- row.update(item)
- row.update(
- {
- "rate": item_price.get("price_list_rate") or 0,
- "currency": item_price.get("currency")
- or pos_profile.get("currency"),
- "item_barcode": item_barcode or [],
- "actual_qty": item_stock_qty or 0,
- "serial_no_data": serial_no_data or [],
- "batch_no_data": batch_no_data or [],
- "attributes": attributes or "",
- "item_attributes": item_attributes or "",
- }
- )
- result.append(row)
+
+ result = []
+ for item in items_data:
+ item_code = item.item_code
+ item_price = {}
+ if item_prices.get(item_code):
+ item_price = (
+ item_prices.get(item_code).get(item.stock_uom)
+ or item_prices.get(item_code).get("None")
+ or {}
+ )
+ item_barcode = barcodes_map.get(item_code, [])
+ batch_no_data = batch_map.get(item_code, []) if search_batch_no else []
+ serial_no_data = serial_map.get(item_code, []) if search_serial_no else []
+ item_stock_qty = stock_qty_map.get(item_code, 0) if (posa_display_items_in_stock or use_limit_search) else 0
+ attributes = attributes_map.get(item_code, "") if posa_show_template_items and item.has_variants else ""
+ item_attributes = item_attributes_map.get(item_code, "") if posa_show_template_items and item.variant_of else ""
+
+ if posa_display_items_in_stock and (not item_stock_qty or item_stock_qty < 0):
+ continue
+
+ row = {}
+ row.update(item)
+ row.update(
+ {
+ "rate": item_price.get("price_list_rate") or 0,
+ "currency": item_price.get("currency") or pos_profile.get("currency"),
+ "item_barcode": item_barcode,
+ "actual_qty": item_stock_qty or 0,
+ "serial_no_data": serial_no_data,
+ "batch_no_data": batch_no_data,
+ "attributes": attributes,
+ "item_attributes": item_attributes,
+ }
+ )
+ result.append(row)
return result
if _pos_profile.get("posa_use_server_cache"):
return __get_items(pos_profile, price_list, item_group, search_value, customer)
else:
return _get_items(pos_profile, price_list, item_group, search_value, customer)
-
-
def get_item_group_condition(pos_profile):
cond = " and 1=1"
item_groups = get_item_groups(pos_profile)
@@ -368,43 +598,40 @@ def get_items_groups():
as_dict=1,
)
-
def get_customer_groups(pos_profile):
customer_groups = []
if pos_profile.get("customer_groups"):
- # Get items based on the item groups defined in the POS profile
+ # Use set to avoid duplicates, and collect all child group names efficiently
+ seen = set()
for data in pos_profile.get("customer_groups"):
- customer_groups.extend(
- [
- "%s" % frappe.db.escape(d.get("name"))
- for d in get_child_nodes(
- "Customer Group", data.get("customer_group")
- )
- ]
- )
-
- return list(set(customer_groups))
-
+ # Get all child nodes for the customer group
+ for d in get_child_nodes("Customer Group", data.get("customer_group")):
+ group_name = d.get("name")
+ if group_name and group_name not in seen:
+ seen.add(group_name)
+ customer_groups = list(seen)
+ return customer_groups
def get_child_nodes(group_type, root):
- lft, rgt = frappe.db.get_value(group_type, root, ["lft", "rgt"])
+ # Use tuple unpacking for lft, rgt and check for None
+ lft_rgt = frappe.db.get_value(group_type, root, ["lft", "rgt"])
+ if not lft_rgt:
+ return []
+ lft, rgt = lft_rgt
return frappe.db.sql(
- """ Select name, lft, rgt from `tab{tab}` where
- lft >= {lft} and rgt <= {rgt} order by lft""".format(
- tab=group_type, lft=lft, rgt=rgt
- ),
+ """SELECT name, lft, rgt FROM `tab{tab}` WHERE lft >= %s AND rgt <= %s ORDER BY lft""".format(tab=group_type),
+ (lft, rgt),
as_dict=1,
)
-
def get_customer_group_condition(pos_profile):
cond = "disabled = 0"
customer_groups = get_customer_groups(pos_profile)
if customer_groups:
- cond = " customer_group in (%s)" % (", ".join(["%s"] * len(customer_groups)))
-
- return cond % tuple(customer_groups)
-
+ placeholders = ", ".join(["%s"] * len(customer_groups))
+ cond += " AND customer_group IN ({})".format(placeholders)
+ return cond, tuple(customer_groups)
+ return cond, ()
@frappe.whitelist()
def get_customer_names(pos_profile):
@@ -419,19 +646,14 @@ def __get_customer_names(pos_profile):
def _get_customer_names(pos_profile):
pos_profile = json.loads(pos_profile)
- condition = ""
- condition += get_customer_group_condition(pos_profile)
- customers = frappe.db.sql(
- """
+ condition, params = get_customer_group_condition(pos_profile)
+ query = """
SELECT name, mobile_no, email_id, tax_id, customer_name, primary_address
FROM `tabCustomer`
WHERE {0}
- ORDER by name
- """.format(
- condition
- ),
- as_dict=1,
- )
+ ORDER BY name
+ """.format(condition)
+ customers = frappe.db.sql(query, params, as_dict=1)
return customers
if _pos_profile.get("posa_use_server_cache"):
@@ -439,7 +661,6 @@ def _get_customer_names(pos_profile):
else:
return _get_customer_names(pos_profile)
-
@frappe.whitelist()
def get_sales_person_names():
sales_persons = frappe.get_list(
diff --git a/posawesome/posawesome/custom/pos_settings.json b/posawesome/posawesome/custom/pos_settings.json
new file mode 100644
index 000000000..aadaa7ca8
--- /dev/null
+++ b/posawesome/posawesome/custom/pos_settings.json
@@ -0,0 +1,70 @@
+{
+ "custom_fields": [
+ {
+ "_assign": null,
+ "_comments": null,
+ "_liked_by": null,
+ "_user_tags": null,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "collapsible_depends_on": null,
+ "columns": 0,
+ "creation": "2023-10-16 15:52:07.916335",
+ "default": null,
+ "depends_on": null,
+ "description": null,
+ "docstatus": 0,
+ "dt": "POS Settings",
+ "fetch_from": null,
+ "fetch_if_empty": 0,
+ "fieldname": "custom_auto_close_shift",
+ "fieldtype": "Datetime",
+ "hidden": 0,
+ "hide_border": 0,
+ "hide_days": 0,
+ "hide_seconds": 0,
+ "idx": 3,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_preview": 0,
+ "in_standard_filter": 0,
+ "insert_after": "auto_close_shift",
+ "is_system_generated": 0,
+ "is_virtual": 0,
+ "label": "Auto Close Shift",
+ "length": 0,
+ "mandatory_depends_on": null,
+ "modified": "2023-10-16 15:52:07.916335",
+ "modified_by": "Administrator",
+ "module": "POSAwesome",
+ "name": "POS Settings-custom_auto_close_shift",
+ "no_copy": 0,
+ "non_negative": 0,
+ "options": null,
+ "owner": "Administrator",
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "print_width": null,
+ "read_only": 0,
+ "read_only_depends_on": null,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "sort_options": 0,
+ "translatable": 0,
+ "unique": 0,
+ "width": null
+ }
+ ],
+ "custom_perms": [],
+ "doctype": "POS Settings",
+ "links": [],
+ "property_setters": [],
+ "sync_on_migrate": 1
+}
\ No newline at end of file
diff --git a/posawesome/posawesome/doctype/pezesha_settings/__init__.py b/posawesome/posawesome/doctype/pezesha_settings/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/posawesome/posawesome/doctype/pezesha_settings/pezesha_settings.js b/posawesome/posawesome/doctype/pezesha_settings/pezesha_settings.js
new file mode 100644
index 000000000..6ed47adf7
--- /dev/null
+++ b/posawesome/posawesome/doctype/pezesha_settings/pezesha_settings.js
@@ -0,0 +1,8 @@
+// Copyright (c) 2024, Youssef Restom and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Pezesha Settings', {
+ // refresh: function(frm) {
+
+ // }
+});
diff --git a/posawesome/posawesome/doctype/pezesha_settings/pezesha_settings.json b/posawesome/posawesome/doctype/pezesha_settings/pezesha_settings.json
new file mode 100644
index 000000000..da359f4c8
--- /dev/null
+++ b/posawesome/posawesome/doctype/pezesha_settings/pezesha_settings.json
@@ -0,0 +1,64 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "creation": "2024-03-28 12:08:55.556406",
+ "default_view": "List",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "enable",
+ "client_id",
+ "client_secret_id",
+ "authorization"
+ ],
+ "fields": [
+ {
+ "fieldname": "client_id",
+ "fieldtype": "Data",
+ "label": "Client ID",
+ "mandatory_depends_on": "eval:doc.enable == 1;"
+ },
+ {
+ "fieldname": "client_secret_id",
+ "fieldtype": "Data",
+ "label": "Client Secret ID",
+ "mandatory_depends_on": "eval:doc.enable == 1;"
+ },
+ {
+ "fieldname": "authorization",
+ "fieldtype": "Small Text",
+ "label": "Authorization",
+ "read_only": 1
+ },
+ {
+ "default": "0",
+ "fieldname": "enable",
+ "fieldtype": "Check",
+ "label": "Enable"
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "issingle": 1,
+ "links": [],
+ "modified": "2024-03-28 14:27:25.725083",
+ "modified_by": "Administrator",
+ "module": "POSAwesome",
+ "name": "Pezesha Settings",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "print": 1,
+ "read": 1,
+ "role": "System Manager",
+ "share": 1,
+ "write": 1
+ }
+ ],
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "states": []
+}
\ No newline at end of file
diff --git a/posawesome/posawesome/doctype/pezesha_settings/pezesha_settings.py b/posawesome/posawesome/doctype/pezesha_settings/pezesha_settings.py
new file mode 100644
index 000000000..dd24e8a1a
--- /dev/null
+++ b/posawesome/posawesome/doctype/pezesha_settings/pezesha_settings.py
@@ -0,0 +1,141 @@
+# Copyright (c) 2024, Youssef Restom and contributors
+# For license information, please see license.txt
+
+import frappe
+import requests
+import json
+from frappe.model.document import Document
+from frappe import _
+from frappe.integrations.utils import (make_get_request, make_post_request, create_request_log)
+
+class PezeshaSettings(Document):
+ def before_validate(self):
+ if self.enable:
+ try:
+ response = make_post_request(
+ # url = 'https://gateway.pezesha.com',
+ url="https://gateway.pezesha.com/oauth/token",
+ headers = {
+ 'pezesha-apikey': '9ea7l6xraTJjDAXU6KYogxcArmlDGE1u',
+ 'Accept-Encoding': 'gzip, deflate'
+ },
+ data={
+ "grant_type": "client_credentials",
+ "client_id": self.client_id,
+ "client_secret": self.client_secret_id,
+ "provider": "users"
+ },
+ auth=(
+ self.client_id,
+ self.get_password(fieldname="client_secret_id", raise_exception=False),
+ ),
+ )
+ self.authorization = response['access_token']
+ except Exception as e:
+ frappe.throw(_("Seems API Key or API Secret is wrong !!!"))
+
+
+
+@frappe.whitelist()
+def pezesha_loan_offer(customer, pos_profile):
+ pos = frappe.get_doc("POS Profile", pos_profile)
+ pz_st = frappe.db.get_single_value('Pezesha Settings', 'authorization')
+ url = 'https://gateway.pezesha.com/mfi/v1/borrowers/options'
+ headers = {
+ 'Authorization': f'Bearer {pz_st}',
+ 'pezesha-apikey': '9ea7l6xraTJjDAXU6KYogxcArmlDGE1u',
+ 'Accept-Encoding': 'gzip, deflate'
+ }
+ data = {
+ 'channel': pos.custom_pezesha_channel_id,
+ 'identifier': customer
+ }
+ response = requests.post(url, headers=headers, data=data)
+ if response.status_code == 200:
+ try:
+ dt = response.json()
+ ddt = dt['data']
+ return dt
+ except KeyError:
+ frappe.msgprint("You already have a pending loan. Cannot apply for new loan until current one is cleared")
+ return "You already have a pending loan. Cannot apply for new loan until current one is cleared"
+ else:
+ frappe.msgprint(f"Unable To Find Borrower {customer}")
+ return response.status_code
+
+@frappe.whitelist()
+def pezesha_loan_application(data, pos_profile):
+ res = json.loads(data)
+ pos = frappe.get_doc("POS Profile", pos_profile)
+ pz_st = frappe.db.get_single_value('Pezesha Settings', 'authorization')
+ url = 'https://gateway.pezesha.com/mfi/v1/borrowers/loans'
+ headers = {
+ 'Authorization': f'Bearer {pz_st}',
+ 'pezesha-apikey': '9ea7l6xraTJjDAXU6KYogxcArmlDGE1u',
+ 'Accept-Encoding': 'gzip, deflate'
+ }
+ data = {
+ 'channel': pos.custom_pezesha_channel_id,
+ 'pezesha_id': res.get('pezesha_customer_id'),
+ 'amount': res.get('amount'),
+ 'duration': res.get('duration'),
+ 'interest': res.get('interest'),
+ 'rate': res.get('rate'),
+ 'fee': res.get('fee')
+ }
+
+ response = requests.post(url, headers=headers, data=data)
+ return response.json()
+
+@frappe.whitelist()
+def pezesha_loan_status(customer, pos_profile):
+ pos = frappe.get_doc("POS Profile", pos_profile)
+ pz_st = frappe.db.get_single_value('Pezesha Settings', 'authorization')
+ url = 'https://gateway.pezesha.com/mfi/v1/borrowers/latest'
+ headers = {
+ 'Authorization': f'Bearer {pz_st}',
+ 'pezesha-apikey': '9ea7l6xraTJjDAXU6KYogxcArmlDGE1u',
+ 'Accept-Encoding': 'gzip, deflate'
+ }
+ data = {
+ 'channel': pos.custom_pezesha_channel_id,
+ 'identifier': customer
+ }
+ response = requests.post(url, headers=headers, data=data)
+ if response.status_code == 200:
+ try:
+ dt = response.json()
+ ddt = dt['data']
+ amt = ddt['loan_amount']
+ return ddt
+ except KeyError:
+ frappe.msgprint("Please Apply Loan Application")
+ return "Please Apply Loan Application"
+ else:
+ frappe.msgprint("Please Apply Loan Application")
+ return response.status_code
+
+def corn():
+ doc = frappe.get_doc('Pezesha Settings')
+ if doc.enable:
+ try:
+ response = make_post_request(
+ url="https://gateway.pezesha.com/oauth/token",
+ headers = {
+ 'pezesha-apikey': '9ea7l6xraTJjDAXU6KYogxcArmlDGE1u',
+ 'Accept-Encoding': 'gzip, deflate'
+ },
+ data={
+ "grant_type": "client_credentials",
+ "client_id": doc.client_id,
+ "client_secret": doc.client_secret_id,
+ "provider": "users"
+ },
+ auth=(
+ doc.client_id,
+ doc.get_password(fieldname="client_secret_id", raise_exception=False),
+ ),
+ )
+ doc.db_set('authorization', response['access_token'])
+ except Exception as e:
+ frappe.throw(_("Seems API Key or API Secret is wrong !!!"))
diff --git a/posawesome/posawesome/doctype/pezesha_settings/test_pezesha_settings.py b/posawesome/posawesome/doctype/pezesha_settings/test_pezesha_settings.py
new file mode 100644
index 000000000..39f34ace0
--- /dev/null
+++ b/posawesome/posawesome/doctype/pezesha_settings/test_pezesha_settings.py
@@ -0,0 +1,9 @@
+# Copyright (c) 2024, Youssef Restom and Contributors
+# See license.txt
+
+# import frappe
+from frappe.tests.utils import FrappeTestCase
+
+
+class TestPezeshaSettings(FrappeTestCase):
+ pass
diff --git a/posawesome/public/js/posapp/Home.vue b/posawesome/public/js/posapp/Home.vue
index 67dd9b7a7..5d4f70c62 100644
--- a/posawesome/public/js/posapp/Home.vue
+++ b/posawesome/public/js/posapp/Home.vue
@@ -1,8 +1,10 @@
-
-
+
+
+
+
@@ -13,35 +15,43 @@ import POS from './components/pos/Pos.vue';
import Payments from './components/payments/Pay.vue';
export default {
- data: function () {
- return {
- page: 'POS',
- };
- },
+ name: "Home",
components: {
Navbar,
POS,
Payments,
},
+ data() {
+ return {
+ page: 'POS',
+ frappeNavRemoved: false,
+ };
+ },
methods: {
setPage(page) {
- this.page = page;
+ if (this.page !== page) {
+ this.page = page;
+ }
},
- remove_frappe_nav() {
- this.$nextTick(function () {
- $('.page-head').remove();
- $('.navbar.navbar-default.navbar-fixed-top').remove();
+ removeFrappeNav() {
+ // Only remove once for performance
+ if (this.frappeNavRemoved) return;
+ this.frappeNavRemoved = true;
+ this.$nextTick(() => {
+ const head = document.querySelector('.page-head');
+ if (head) head.remove();
+ const nav = document.querySelector('.navbar.navbar-default.navbar-fixed-top');
+ if (nav) nav.remove();
});
},
},
mounted() {
- this.remove_frappe_nav();
+ this.removeFrappeNav();
},
- updated() {},
- created: function () {
- setTimeout(() => {
- this.remove_frappe_nav();
- }, 1000);
+ created() {
+ setTimeout(() => {
+ this.removeFrappeNav();
+ }, 500);
},
};
@@ -50,4 +60,4 @@ export default {
.container1 {
margin-top: 0px;
}
-
+
\ No newline at end of file
diff --git a/posawesome/public/js/posapp/components/pos/Customer.vue b/posawesome/public/js/posapp/components/pos/Customer.vue
index 86a5f036e..1f99b919b 100644
--- a/posawesome/public/js/posapp/components/pos/Customer.vue
+++ b/posawesome/public/js/posapp/components/pos/Customer.vue
@@ -61,6 +61,7 @@
+
\ No newline at end of file
diff --git a/posawesome/public/js/posapp/components/pos/Invoice.vue b/posawesome/public/js/posapp/components/pos/Invoice.vue
index f77948da6..cea600808 100644
--- a/posawesome/public/js/posapp/components/pos/Invoice.vue
+++ b/posawesome/public/js/posapp/components/pos/Invoice.vue
@@ -629,7 +629,7 @@
-
+
@@ -742,7 +742,7 @@
-
+
+
+
+ {{ dialogtitle }}
+ {{ dialogMessage }}
+
+ Close
+
+
+
+
+
+
+ Loan Confirmation Request Pending Approval
+
+ Close
+
+
+
+
+
+
+ Loan Application
+
+
+
+
+
+
+
+
+
+
+
+
+ Submit
+ Close
+
+
+
-
-
+
+
+
+
+
+
+
+ {{ payment.mode_of_payment }}
+
+
+
+
+
+
+
+ {{ __("Request") }}
+
+
+
+
+
+
+
+ {{ __("Credit Pezesha") }}
+
+
+
+
+
+
+
+
- {{ payment.mode_of_payment }}
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- {{ __("Request") }}
+ {{ __("Pezesha Loan Status") }}
-
({
+ dialogtitle: "",
+ dialogMessage: "",
+ dialognotSuccessful: false,
+ dialogSuccessful: false,
+ dialogVisible: false,
+ success: true,
+ message: "Thank you for your Loan Approval.",
+ formLoan: {
+ loan_amount: null,
+ loan_id: null,
+ loan_status: null,
+ },
+ formData: {
+ amount: 0,
+ rate: 0,
+ interest: 0,
+ },
loading: false,
pos_profile: "",
invoice_doc: "",
@@ -731,6 +887,210 @@ export default {
}),
methods: {
+ openDialog() {
+ if (!this.invoice_doc.customer) {
+ evntBus.$emit("show_mesage", {
+ text: __(`There is no Customer!`),
+ color: "error",
+ });
+ return;
+ } else {
+ // Emit a freeze event to indicate that a process is in progress
+ evntBus.$emit("freeze", {
+ title: __("Please wait..."),
+ });
+
+ // Make the server call
+ frappe.call({
+ method:
+ "posawesome.posawesome.doctype.pezesha_settings.pezesha_settings.pezesha_loan_offer",
+ args: {
+ customer: this.invoice_doc.customer,
+ pos_profile: this.pos_profile.name,
+ },
+ callback: (r) => {
+ st = r.message;
+ dt = st.data;
+ if (st.status == 200) {
+ // Populate formData with fetched values
+ this.formData.pezesha_customer_id = this.invoice_doc.customer;
+ this.formData.pezesha_channel_id = this.pos_profile.name;
+ this.formData.amount = dt.amount;
+ this.formData.fee = dt.fee;
+ this.formData.interest = (dt.amount * dt.rate) / 100;
+ this.formData.duration = dt.duration;
+ this.formData.rate = dt.rate;
+ this.changeHandler(); // Call changeHandler after setting initial values
+ // Once the server call is completed, emit an unfreeze event
+ evntBus.$emit("unfreeze");
+ // Optionally, update dialog visibility or perform other actions
+ this.dialogVisible = true;
+ } else {
+ this.dialognotSuccessful = true;
+ evntBus.$emit("unfreeze");
+ if (st.status == 400 || st == 400) {
+ this.dialogtitle = "Invalid Merchant ID";
+ this.dialogMessage =
+ "Loan offer request failed: The provided merchant ID is invalid. Please verify your merchant ID and try again.";
+ } else if (st.status == 404 || st == 404) {
+ this.dialogtitle = "Merchant not found";
+ this.dialogMessage = "Merchant not found.";
+ } else if (st.status == 503 || st == 503) {
+ this.dialogtitle = "Loan Offer Unavailable";
+ this.dialogMessage =
+ "Loan offer request failed: Unable to retrieve loan offers at this time. Please try again later.";
+ } else if (st.status == 401 || st == 401) {
+ this.dialogtitle = "Missing Authorization Token";
+ this.dialogMessage =
+ "The request does not include the required authorization token.";
+ }
+ }
+ },
+ });
+ }
+ },
+ changeHandler() {
+ // if(dt.amount >= this.formData.amount){
+ this.formData.interest =
+ (this.formData.amount * this.formData.rate) / 100;
+ // }else{
+ // frappe.throw("Please ensure that the input value does not exceed the loan amount limit.")
+ // }
+ // change of user input, do something
+ },
+ closeDialog() {
+ this.dialogVisible = false;
+ },
+ closeSuccessfulDialog() {
+ this.dialogSuccessful = false;
+ },
+ // pezeshaLoanStatus(){
+
+ // },
+ pezeshaLoanStatus() {
+ evntBus.$emit("freeze", {
+ title: __("Please wait..."),
+ });
+ frappe.call({
+ method:
+ "posawesome.posawesome.doctype.pezesha_settings.pezesha_settings.pezesha_loan_status",
+ args: {
+ customer: this.invoice_doc.customer,
+ pos_profile: this.pos_profile.name,
+ },
+ callback: (r) => {
+ if (r.message) {
+ pez = r.message;
+ this.formLoan.loan_amount = pez.loan_amount;
+ this.formLoan.loan_id = pez.loan_id;
+ this.formLoan.loan_status = pez.status;
+ evntBus.$emit("unfreeze");
+ } else {
+ this.dialognotSuccessful = true;
+ evntBus.$emit("unfreeze");
+ if (st.status == 404 || st == 404) {
+ this.dialogtitle = "Loan Not Found";
+ this.dialogMessage =
+ "Loan status request failed: No loan found for the given identifier. Please verify your details and try again.";
+ } else if (st.status == 400 || st == 400) {
+ this.dialogtitle = "Invalid Loan Status Request";
+ this.dialogMessage =
+ "Loan status request failed: Invalid request parameters. Please ensure you provide a valid channel and identifier.";
+ } else if (st.status == 401 || st == 401) {
+ this.dialogtitle = "Authorization Token Missing";
+ this.dialogMessage =
+ "Loan status request failed: Missing authorization token. Please provide a valid token to retrieve loan status.";
+ }
+ }
+ },
+ });
+ },
+ closeNotSuccessfulDialog() {
+ this.dialognotSuccessful = false;
+ },
+ // submitForm() {
+ // if(this.invoice_doc.grand_total >= this.formData.amount){
+ // frappe.call({
+ // method: "posawesome.posawesome.doctype.pezesha_settings.pezesha_settings.pezesha_loan_application",
+ // args: {
+ // data: this.formData,
+ // pos_profile: this.pos_profile.name,
+ // },
+ // callback: (r) => {
+ // // Emit an unfreeze event after receiving the response
+ // evntBus.$emit("unfreeze");
+ // let s = r.message;
+ // if (s.status == 200) {
+ // this.dialogMessage = JSON.stringify(s);
+ // this.dialogSuccessful = true;
+ // } else {
+ // this.dialognotSuccessful = true;
+ // }
+ // }
+ // });
+
+ // }else{
+ // frappe.throw("Please ensure that the input value does not exceed the loan amount limit.")
+ // }
+ // // Here you can handle form submission
+ // // Emit a freeze event to indicate that a process is in progress
+ // evntBus.$emit("freeze", {
+ // title: __("Please wait..."),
+ // });
+
+ // // Make the server call
+
+ // },
+ submitForm() {
+ if (this.invoice_doc.grand_total >= this.formData.amount) {
+ // Here you can handle form submission
+ // Emit a freeze event to indicate that a process is in progress
+ evntBus.$emit("freeze", {
+ title: __("Please wait..."),
+ });
+ // Make the server call
+ frappe.call({
+ method:
+ "posawesome.posawesome.doctype.pezesha_settings.pezesha_settings.pezesha_loan_application",
+ args: {
+ data: this.formData,
+ pos_profile: this.pos_profile.name,
+ },
+ callback: (r) => {
+ // Emit an unfreeze event after receiving the response
+ evntBus.$emit("unfreeze");
+ let s = r.message;
+ if (s.status == 200) {
+ // this.dialogMessage = JSON.stringify(s);
+ this.dialogSuccessful = true;
+ } else {
+ this.dialognotSuccessful = true;
+ if (s.status == 403 || s == 403) {
+ this.dialogtitle = "Loan Application Denied";
+ this.dialogMessage =
+ "Loan application failed: Your previous loan is yet to be fully paid or is overdue. Please settle outstanding dues to apply for a new loan.";
+ } else if (s.status == 400 || s == 400) {
+ this.dialogtitle = "Invalid Loan Amount";
+ this.dialogMessage =
+ "Loan application failed: The requested loan amount exceeds your available credit limit. Please request a lower amount.";
+ }
+ // else if(st.status == 503 ){
+ // dialogtitle = "Duplicate loan request";
+ // dialogMessage = 'Kindly clear your previous loan before applying for a new Loan';
+ // }
+ // else if(st.status == 401){
+ // dialogtitle = "Missing Authorization Token";
+ // dialogMessage = 'The request does not include the required authorization token.';
+ // }
+ }
+ // Close the dialog after form submission
+ this.dialogVisible = false;
+ },
+ });
+ } else {
+ frappe.throw("Please ensure the input value matches the order amount.");
+ }
+ },
back_to_invoice() {
evntBus.$emit("show_payment", "false");
evntBus.$emit("set_customer_readonly", false);
@@ -1248,6 +1608,10 @@ export default {
},
computed: {
+ formattedPezeshaAmount() {
+ // Assuming pezesha_amount is a computed property or data property
+ return this.formtCurrency(this.pezesha_amount);
+ },
total_payments() {
let total = parseFloat(this.invoice_doc.loyalty_amount);
if (this.invoice_doc && this.invoice_doc.payments) {