Merge branch 'develop' of https://github.com/frappe/erpnext into stock_ageing_fix

This commit is contained in:
deepeshgarg007
2019-07-16 09:02:48 +05:30
46 changed files with 1015 additions and 1587 deletions

View File

@@ -121,7 +121,7 @@ frappe.treeview_settings["Account"] = {
}, },
onrender: function(node) { onrender: function(node) {
if(frappe.boot.user.can_read.indexOf("GL Entry") !== -1){ if(frappe.boot.user.can_read.indexOf("GL Entry") !== -1){
var dr_or_cr = node.data.balance < 0 ? "Cr" : "Dr"; var dr_or_cr = in_list(["Liability", "Income", "Equity"], node.data.root_type) ? "Cr" : "Dr";
if (node.data && node.data.balance!==undefined) { if (node.data && node.data.balance!==undefined) {
$('<span class="balance-area pull-right text-muted small">' $('<span class="balance-area pull-right text-muted small">'
+ (node.data.balance_in_account_currency ? + (node.data.balance_in_account_currency ?

View File

@@ -10,6 +10,7 @@
"acc_frozen_upto", "acc_frozen_upto",
"frozen_accounts_modifier", "frozen_accounts_modifier",
"determine_address_tax_category_from", "determine_address_tax_category_from",
"over_billing_allowance",
"column_break_4", "column_break_4",
"credit_controller", "credit_controller",
"check_supplier_invoice_uniqueness", "check_supplier_invoice_uniqueness",
@@ -168,12 +169,18 @@
"fieldname": "automatically_fetch_payment_terms", "fieldname": "automatically_fetch_payment_terms",
"fieldtype": "Check", "fieldtype": "Check",
"label": "Automatically Fetch Payment Terms" "label": "Automatically Fetch Payment Terms"
},
{
"description": "Percentage you are allowed to bill more against the amount ordered. For example: If the order value is $100 for an item and tolerance is set as 10% then you are allowed to bill for $110.",
"fieldname": "over_billing_allowance",
"fieldtype": "Currency",
"label": "Over Billing Allowance (%)"
} }
], ],
"icon": "icon-cog", "icon": "icon-cog",
"idx": 1, "idx": 1,
"issingle": 1, "issingle": 1,
"modified": "2019-04-28 18:20:55.789946", "modified": "2019-07-04 18:20:55.789946",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Accounts Settings", "name": "Accounts Settings",

View File

@@ -1,177 +1,64 @@
{ {
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2019-03-07 12:07:09.416101", "creation": "2019-03-07 12:07:09.416101",
"custom": 0,
"docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB", "engine": "InnoDB",
"field_order": [
"sales_invoice",
"customer",
"column_break_3",
"posting_date",
"outstanding_amount"
],
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "sales_invoice", "fieldname": "sales_invoice",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Invoice", "label": "Invoice",
"length": 0,
"no_copy": 0,
"options": "Sales Invoice", "options": "Sales Invoice",
"permlevel": 0, "reqd": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_from": "sales_invoice.customer", "fetch_from": "sales_invoice.customer",
"fieldname": "customer", "fieldname": "customer",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Customer", "label": "Customer",
"length": 0,
"no_copy": 0,
"options": "Customer", "options": "Customer",
"permlevel": 0, "read_only": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_from": "sales_invoice.posting_date", "fetch_from": "sales_invoice.posting_date",
"fieldname": "posting_date", "fieldname": "posting_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Date", "label": "Date",
"length": 0, "read_only": 1
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_from": "sales_invoice.grand_total", "fetch_from": "sales_invoice.grand_total",
"fieldname": "outstanding_amount", "fieldname": "outstanding_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Outstanding Amount", "label": "Outstanding Amount",
"length": 0,
"no_copy": 0,
"options": "Company:company:default_currency", "options": "Company:company:default_currency",
"permlevel": 0, "read_only": 1
"precision": "", },
"print_hide": 0, {
"print_hide_if_no_value": 0, "fieldname": "column_break_3",
"read_only": 1, "fieldtype": "Column Break"
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
} }
], ],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "modified": "2019-05-30 19:27:29.436153",
"modified": "2019-03-07 16:38:03.622666",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Discounted Invoice", "name": "Discounted Invoice",
"name_case": "",
"owner": "Administrator", "owner": "Administrator",
"permissions": [], "permissions": [],
"quick_entry": 1, "quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"track_changes": 1, "track_changes": 1
"track_seen": 0,
"track_views": 0
} }

View File

@@ -1,744 +1,177 @@
{ {
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 1, "allow_import": 1,
"allow_rename": 0,
"autoname": "ACC-INV-DISC-.YYYY.-.#####", "autoname": "ACC-INV-DISC-.YYYY.-.#####",
"beta": 0,
"creation": "2019-03-07 12:01:56.296952", "creation": "2019-03-07 12:01:56.296952",
"custom": 0,
"docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"document_type": "",
"editable_grid": 1, "editable_grid": 1,
"engine": "InnoDB", "engine": "InnoDB",
"field_order": [
"posting_date",
"loan_start_date",
"loan_period",
"loan_end_date",
"column_break_3",
"status",
"company",
"section_break_5",
"invoices",
"section_break_7",
"total_amount",
"column_break_9",
"bank_charges",
"section_break_6",
"short_term_loan",
"bank_account",
"bank_charges_account",
"column_break_15",
"accounts_receivable_credit",
"accounts_receivable_discounted",
"accounts_receivable_unpaid",
"amended_from"
],
"fields": [ "fields": [
{ {
"allow_bulk_edit": 0, "default": "Today",
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "posting_date", "fieldname": "posting_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Posting Date", "label": "Posting Date",
"length": 0, "reqd": 1
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "loan_start_date", "fieldname": "loan_start_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0, "label": "Loan Start Date"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Loan Start Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "loan_period", "fieldname": "loan_period",
"fieldtype": "Int", "fieldtype": "Int",
"hidden": 0, "label": "Loan Period (Days)"
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Loan Period",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "loan_end_date", "fieldname": "loan_end_date",
"fieldtype": "Date", "fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Loan End Date", "label": "Loan End Date",
"length": 0,
"no_copy": 1, "no_copy": 1,
"permlevel": 0, "read_only": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_3", "fieldname": "column_break_3",
"fieldtype": "Column Break", "fieldtype": "Column Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "status", "fieldname": "status",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Status", "label": "Status",
"length": 0,
"no_copy": 1, "no_copy": 1,
"options": "Draft\nSanctioned\nDisbursed\nSettled\nCancelled", "options": "Draft\nSanctioned\nDisbursed\nSettled\nCancelled",
"permlevel": 0, "read_only": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "company", "fieldname": "company",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1, "in_list_view": 1,
"in_standard_filter": 0,
"label": "Company", "label": "Company",
"length": 0,
"no_copy": 0,
"options": "Company", "options": "Company",
"permlevel": 0, "reqd": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_5", "fieldname": "section_break_5",
"fieldtype": "Section Break", "fieldtype": "Section Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "invoices", "fieldname": "invoices",
"fieldtype": "Table", "fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Invoices", "label": "Invoices",
"length": 0,
"no_copy": 0,
"options": "Discounted Invoice", "options": "Discounted Invoice",
"permlevel": 0, "reqd": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_7", "fieldname": "section_break_7",
"fieldtype": "Section Break", "fieldtype": "Section Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "total_amount", "fieldname": "total_amount",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Total Amount", "label": "Total Amount",
"length": 0,
"no_copy": 0,
"options": "Company:company:default_currency", "options": "Company:company:default_currency",
"permlevel": 0, "read_only": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_9", "fieldname": "column_break_9",
"fieldtype": "Column Break", "fieldtype": "Column Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "bank_charges", "fieldname": "bank_charges",
"fieldtype": "Currency", "fieldtype": "Currency",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Bank Charges", "label": "Bank Charges",
"length": 0, "options": "Company:company:default_currency"
"no_copy": 0,
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_6", "fieldname": "section_break_6",
"fieldtype": "Section Break", "fieldtype": "Section Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "short_term_loan", "fieldname": "short_term_loan",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Short Term Loan Account", "label": "Short Term Loan Account",
"length": 0,
"no_copy": 0,
"options": "Account", "options": "Account",
"permlevel": 0, "reqd": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "bank_account", "fieldname": "bank_account",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Bank Account", "label": "Bank Account",
"length": 0,
"no_copy": 0,
"options": "Account", "options": "Account",
"permlevel": 0, "reqd": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "bank_charges_account", "fieldname": "bank_charges_account",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Bank Charges Account", "label": "Bank Charges Account",
"length": 0,
"no_copy": 0,
"options": "Account", "options": "Account",
"permlevel": 0, "reqd": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_15", "fieldname": "column_break_15",
"fieldtype": "Column Break", "fieldtype": "Column Break"
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "accounts_receivable_credit", "fieldname": "accounts_receivable_credit",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Accounts Receivable Credit Account", "label": "Accounts Receivable Credit Account",
"length": 0,
"no_copy": 0,
"options": "Account", "options": "Account",
"permlevel": 0, "reqd": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "accounts_receivable_discounted", "fieldname": "accounts_receivable_discounted",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Accounts Receivable Discounted Account", "label": "Accounts Receivable Discounted Account",
"length": 0,
"no_copy": 0,
"options": "Account", "options": "Account",
"permlevel": 0, "reqd": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "accounts_receivable_unpaid", "fieldname": "accounts_receivable_unpaid",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Accounts Receivable Unpaid Account", "label": "Accounts Receivable Unpaid Account",
"length": 0,
"no_copy": 0,
"options": "Account", "options": "Account",
"permlevel": 0, "reqd": 1
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}, },
{ {
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from", "fieldname": "amended_from",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Amended From", "label": "Amended From",
"length": 0,
"no_copy": 1, "no_copy": 1,
"options": "Invoice Discounting", "options": "Invoice Discounting",
"permlevel": 0,
"print_hide": 1, "print_hide": 1,
"print_hide_if_no_value": 0, "read_only": 1
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
} }
], ],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 1, "is_submittable": 1,
"issingle": 0, "modified": "2019-05-30 19:08:21.199759",
"istable": 0,
"max_attachments": 0,
"modified": "2019-03-08 14:24:31.222027",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Invoice Discounting", "name": "Invoice Discounting",
"name_case": "",
"owner": "Administrator", "owner": "Administrator",
"permissions": [ "permissions": [
{ {
@@ -748,26 +181,17 @@
"delete": 1, "delete": 1,
"email": 1, "email": 1,
"export": 1, "export": 1,
"if_owner": 0,
"import": 1, "import": 1,
"permlevel": 0,
"print": 1, "print": 1,
"read": 1, "read": 1,
"report": 1, "report": 1,
"role": "System Manager", "role": "System Manager",
"set_user_permissions": 0,
"share": 1, "share": 1,
"submit": 1, "submit": 1,
"write": 1 "write": 1
} }
], ],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified", "sort_field": "modified",
"sort_order": "DESC", "sort_order": "DESC",
"track_changes": 1, "track_changes": 1
"track_seen": 0,
"track_views": 0
} }

View File

@@ -28,19 +28,40 @@ class InvoiceDiscounting(AccountsController):
self.total_amount = sum([flt(d.outstanding_amount) for d in self.invoices]) self.total_amount = sum([flt(d.outstanding_amount) for d in self.invoices])
def on_submit(self): def on_submit(self):
self.update_sales_invoice()
self.make_gl_entries() self.make_gl_entries()
def on_cancel(self): def on_cancel(self):
self.set_status() self.set_status()
self.update_sales_invoice()
self.make_gl_entries() self.make_gl_entries()
def set_status(self): def set_status(self, status=None):
if status:
self.status = status
self.db_set("status", status)
for d in self.invoices:
frappe.get_doc("Sales Invoice", d.sales_invoice).set_status(update=True, update_modified=False)
else:
self.status = "Draft" self.status = "Draft"
if self.docstatus == 1: if self.docstatus == 1:
self.status = "Sanctioned" self.status = "Sanctioned"
elif self.docstatus == 2: elif self.docstatus == 2:
self.status = "Cancelled" self.status = "Cancelled"
def update_sales_invoice(self):
for d in self.invoices:
if self.docstatus == 1:
is_discounted = 1
else:
discounted_invoice = frappe.db.exists({
"doctype": "Discounted Invoice",
"sales_invoice": d.sales_invoice,
"docstatus": 1
})
is_discounted = 1 if discounted_invoice else 0
frappe.db.set_value("Sales Invoice", d.sales_invoice, "is_discounted", is_discounted)
def make_gl_entries(self): def make_gl_entries(self):
company_currency = frappe.get_cached_value('Company', self.company, "default_currency") company_currency = frappe.get_cached_value('Company', self.company, "default_currency")

View File

@@ -105,24 +105,28 @@ class JournalEntry(AccountsController):
invoice_discounting_list = list(set([d.reference_name for d in self.accounts if d.reference_type=="Invoice Discounting"])) invoice_discounting_list = list(set([d.reference_name for d in self.accounts if d.reference_type=="Invoice Discounting"]))
for inv_disc in invoice_discounting_list: for inv_disc in invoice_discounting_list:
short_term_loan_account, id_status = frappe.db.get_value("Invoice Discounting", inv_disc, ["short_term_loan", "status"]) inv_disc_doc = frappe.get_doc("Invoice Discounting", inv_disc)
status = None
for d in self.accounts: for d in self.accounts:
if d.account == short_term_loan_account and d.reference_name == inv_disc: if d.account == inv_disc_doc.short_term_loan and d.reference_name == inv_disc:
if self.docstatus == 1: if self.docstatus == 1:
if d.credit > 0: if d.credit > 0:
_validate_invoice_discounting_status(inv_disc, id_status, "Sanctioned", d.idx) _validate_invoice_discounting_status(inv_disc, inv_disc_doc.status, "Sanctioned", d.idx)
status = "Disbursed" status = "Disbursed"
elif d.debit > 0: elif d.debit > 0:
_validate_invoice_discounting_status(inv_disc, id_status, "Disbursed", d.idx) _validate_invoice_discounting_status(inv_disc, inv_disc_doc.status, "Disbursed", d.idx)
status = "Settled" status = "Settled"
else: else:
if d.credit > 0: if d.credit > 0:
_validate_invoice_discounting_status(inv_disc, id_status, "Disbursed", d.idx) _validate_invoice_discounting_status(inv_disc, inv_disc_doc.status, "Disbursed", d.idx)
status = "Sanctioned" status = "Sanctioned"
elif d.debit > 0: elif d.debit > 0:
_validate_invoice_discounting_status(inv_disc, id_status, "Settled", d.idx) _validate_invoice_discounting_status(inv_disc, inv_disc_doc.status, "Settled", d.idx)
status = "Disbursed" status = "Disbursed"
frappe.db.set_value("Invoice Discounting", inv_disc, "status", status) break
if status:
inv_disc_doc.set_status(status=status)
def unlink_advance_entry_reference(self): def unlink_advance_entry_reference(self):
for d in self.get("accounts"): for d in self.get("accounts"):

View File

@@ -83,10 +83,14 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
} }
} }
if (doc.outstanding_amount>0 && !cint(doc.is_return)) { if (doc.outstanding_amount>0) {
cur_frm.add_custom_button(__('Payment Request'), function() { cur_frm.add_custom_button(__('Payment Request'), function() {
me.make_payment_request(); me.make_payment_request();
}, __('Create')); }, __('Create'));
cur_frm.add_custom_button(__('Invoice Discounting'), function() {
cur_frm.events.create_invoice_discounting(cur_frm);
}, __('Create'));
} }
if (doc.docstatus === 1) { if (doc.docstatus === 1) {
@@ -808,6 +812,13 @@ frappe.ui.form.on('Sales Invoice', {
frm.set_df_property("patient_name", "hidden", 1); frm.set_df_property("patient_name", "hidden", 1);
frm.set_df_property("ref_practitioner", "hidden", 1); frm.set_df_property("ref_practitioner", "hidden", 1);
} }
},
create_invoice_discounting: function(frm) {
frappe.model.open_mapped_doc({
method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.create_invoice_discounting",
frm: frm
});
} }
}) })

View File

@@ -155,6 +155,7 @@
"inter_company_invoice_reference", "inter_company_invoice_reference",
"customer_group", "customer_group",
"campaign", "campaign",
"is_discounted",
"col_break23", "col_break23",
"status", "status",
"source", "source",
@@ -1324,6 +1325,13 @@
"options": "Campaign", "options": "Campaign",
"print_hide": 1 "print_hide": 1
}, },
{
"fieldname": "is_discounted",
"fieldtype": "Check",
"label": "Is Discounted",
"no_copy": 1,
"read_only": 1
},
{ {
"fieldname": "col_break23", "fieldname": "col_break23",
"fieldtype": "Column Break", "fieldtype": "Column Break",
@@ -1336,7 +1344,7 @@
"in_standard_filter": 1, "in_standard_filter": 1,
"label": "Status", "label": "Status",
"no_copy": 1, "no_copy": 1,
"options": "\nDraft\nReturn\nCredit Note Issued\nSubmitted\nPaid\nUnpaid\nOverdue\nCancelled", "options": "\nDraft\nReturn\nCredit Note Issued\nSubmitted\nPaid\nUnpaid\nUnpaid and Discounted\nOverdue and Discounted\nOverdue\nOverdue\nCancelled",
"print_hide": 1, "print_hide": 1,
"read_only": 1 "read_only": 1
}, },
@@ -1558,7 +1566,7 @@
"icon": "fa fa-file-text", "icon": "fa fa-file-text",
"idx": 181, "idx": 181,
"is_submittable": 1, "is_submittable": 1,
"modified": "2019-05-25 22:05:03.474745", "modified": "2019-07-04 22:05:03.474745",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Sales Invoice", "name": "Sales Invoice",

View File

@@ -1177,6 +1177,56 @@ class SalesInvoice(SellingController):
self.set_missing_values(for_validate = True) self.set_missing_values(for_validate = True)
def get_discounting_status(self):
status = None
if self.is_discounted:
invoice_discounting_list = frappe.db.sql("""
select status
from `tabInvoice Discounting` id, `tabDiscounted Invoice` d
where
id.name = d.parent
and d.sales_invoice=%s
and id.docstatus=1
and status in ('Disbursed', 'Settled')
""", self.name)
for d in invoice_discounting_list:
status = d[0]
if status == "Disbursed":
break
return status
def set_status(self, update=False, status=None, update_modified=True):
if self.is_new():
if self.get('amended_from'):
self.status = 'Draft'
return
if not status:
if self.docstatus == 2:
status = "Cancelled"
elif self.docstatus == 1:
if flt(self.outstanding_amount) > 0 and getdate(self.due_date) < getdate(nowdate()) and self.is_discounted and self.get_discounting_status()=='Disbursed':
self.status = "Overdue and Discounted"
elif flt(self.outstanding_amount) > 0 and getdate(self.due_date) < getdate(nowdate()):
self.status = "Overdue"
elif flt(self.outstanding_amount) > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.is_discounted and self.get_discounting_status()=='Disbursed':
self.status = "Unpaid and Discounted"
elif flt(self.outstanding_amount) > 0 and getdate(self.due_date) >= getdate(nowdate()):
self.status = "Unpaid"
elif flt(self.outstanding_amount) < 0 and self.is_return==0 and frappe.db.get_value('Sales Invoice', {'is_return': 1, 'return_against': self.name, 'docstatus': 1}):
self.status = "Credit Note Issued"
elif self.is_return == 1:
self.status = "Return"
elif flt(self.outstanding_amount)<=0:
self.status = "Paid"
else:
self.status = "Submitted"
else:
self.status = "Draft"
if update:
self.db_set('status', self.status, update_modified = update_modified)
def validate_inter_company_party(doctype, party, company, inter_company_reference): def validate_inter_company_party(doctype, party, company, inter_company_reference):
if not party: if not party:
return return
@@ -1432,3 +1482,17 @@ def get_loyalty_programs(customer):
return [] return []
else: else:
return lp_details return lp_details
@frappe.whitelist()
def create_invoice_discounting(source_name, target_doc=None):
invoice = frappe.get_doc("Sales Invoice", source_name)
invoice_discounting = frappe.new_doc("Invoice Discounting")
invoice_discounting.company = invoice.company
invoice_discounting.append("invoices", {
"sales_invoice": source_name,
"customer": invoice.customer,
"posting_date": invoice.posting_date,
"outstanding_amount": invoice.outstanding_amount
})
return invoice_discounting

View File

@@ -6,17 +6,18 @@ frappe.listview_settings['Sales Invoice'] = {
add_fields: ["customer", "customer_name", "base_grand_total", "outstanding_amount", "due_date", "company", add_fields: ["customer", "customer_name", "base_grand_total", "outstanding_amount", "due_date", "company",
"currency", "is_return"], "currency", "is_return"],
get_indicator: function(doc) { get_indicator: function(doc) {
if(flt(doc.outstanding_amount) < 0) { var status_color = {
return [__("Credit Note Issued"), "darkgrey", "outstanding_amount,<,0"] "Draft": "grey",
} else if (flt(doc.outstanding_amount) > 0 && doc.due_date >= frappe.datetime.get_today()) { "Unpaid": "orange",
return [__("Unpaid"), "orange", "outstanding_amount,>,0|due_date,>,Today"] "Paid": "green",
} else if (flt(doc.outstanding_amount) > 0 && doc.due_date < frappe.datetime.get_today()) { "Return": "darkgrey",
return [__("Overdue"), "red", "outstanding_amount,>,0|due_date,<=,Today"] "Credit Note Issued": "darkgrey",
} else if(cint(doc.is_return)) { "Unpaid and Discounted": "orange",
return [__("Return"), "darkgrey", "is_return,=,Yes"]; "Overdue and Discounted": "red",
} else if(flt(doc.outstanding_amount)==0) { "Overdue": "red"
return [__("Paid"), "green", "outstanding_amount,=,0"]
} };
return [__(doc.status), status_color[doc.status], "status,=,"+doc.status];
}, },
right_column: "grand_total" right_column: "grand_total"
}; };

View File

@@ -88,6 +88,12 @@ frappe.query_reports["Accounts Payable"] = {
} }
} }
}, },
{
"fieldname":"payment_terms_template",
"label": __("Payment Terms Template"),
"fieldtype": "Link",
"options": "Payment Terms Template"
},
{ {
"fieldname":"supplier_group", "fieldname":"supplier_group",
"label": __("Supplier Group"), "label": __("Supplier Group"),

View File

@@ -77,6 +77,12 @@ frappe.query_reports["Accounts Payable Summary"] = {
"fieldtype": "Link", "fieldtype": "Link",
"options": "Supplier" "options": "Supplier"
}, },
{
"fieldname":"payment_terms_template",
"label": __("Payment Terms Template"),
"fieldtype": "Link",
"options": "Payment Terms Template"
},
{ {
"fieldname":"supplier_group", "fieldname":"supplier_group",
"label": __("Supplier Group"), "label": __("Supplier Group"),

View File

@@ -541,6 +541,10 @@ class ReceivablePayableReport(object):
where supplier_group=%s)""") where supplier_group=%s)""")
values.append(self.filters.get("supplier_group")) values.append(self.filters.get("supplier_group"))
if self.filters.get("payment_terms_template"):
conditions.append("party in (select name from tabSupplier where payment_terms=%s)")
values.append(self.filters.get("payment_terms_template"))
if self.filters.get("cost_center"): if self.filters.get("cost_center"):
lft, rgt = frappe.get_cached_value("Cost Center", lft, rgt = frappe.get_cached_value("Cost Center",
self.filters.get("cost_center"), ['lft', 'rgt']) self.filters.get("cost_center"), ['lft', 'rgt'])

View File

@@ -11,6 +11,7 @@ from erpnext.accounts.utils import get_account_currency
from erpnext.accounts.report.financial_statements import get_cost_centers_with_children from erpnext.accounts.report.financial_statements import get_cost_centers_with_children
from six import iteritems from six import iteritems
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_accounting_dimensions
from collections import OrderedDict
def execute(filters=None): def execute(filters=None):
if not filters: if not filters:
@@ -274,7 +275,7 @@ def group_by_field(group_by):
return 'voucher_no' return 'voucher_no'
def initialize_gle_map(gl_entries, filters): def initialize_gle_map(gl_entries, filters):
gle_map = frappe._dict() gle_map = OrderedDict()
group_by = group_by_field(filters.get('group_by')) group_by = group_by_field(filters.get('group_by'))
for gle in gl_entries: for gle in gl_entries:

View File

@@ -734,6 +734,7 @@ def get_children(doctype, parent, company, is_root=False):
parent_fieldname = 'parent_' + doctype.lower().replace(' ', '_') parent_fieldname = 'parent_' + doctype.lower().replace(' ', '_')
fields = [ fields = [
'name as value', 'name as value',
'root_type',
'is_group as expandable' 'is_group as expandable'
] ]
filters = [['docstatus', '<', 2]] filters = [['docstatus', '<', 2]]
@@ -741,7 +742,7 @@ def get_children(doctype, parent, company, is_root=False):
filters.append(['ifnull(`{0}`,"")'.format(parent_fieldname), '=', '' if is_root else parent]) filters.append(['ifnull(`{0}`,"")'.format(parent_fieldname), '=', '' if is_root else parent])
if is_root: if is_root:
fields += ['root_type', 'report_type', 'account_currency'] if doctype == 'Account' else [] fields += ['report_type', 'account_currency'] if doctype == 'Account' else []
filters.append(['company', '=', company]) filters.append(['company', '=', company])
else: else:

View File

@@ -4,6 +4,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import unittest import unittest
import frappe import frappe
import json
import frappe.defaults import frappe.defaults
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
from frappe.utils import flt, add_days, nowdate, getdate from frappe.utils import flt, add_days, nowdate, getdate
@@ -15,7 +16,7 @@ from erpnext.stock.doctype.material_request.test_material_request import make_ma
from erpnext.stock.doctype.material_request.material_request import make_purchase_order from erpnext.stock.doctype.material_request.material_request import make_purchase_order
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
from erpnext.controllers.accounts_controller import update_child_qty_rate from erpnext.controllers.accounts_controller import update_child_qty_rate
import json from erpnext.controllers.status_updater import OverAllowanceError
class TestPurchaseOrder(unittest.TestCase): class TestPurchaseOrder(unittest.TestCase):
def test_make_purchase_receipt(self): def test_make_purchase_receipt(self):
@@ -41,7 +42,7 @@ class TestPurchaseOrder(unittest.TestCase):
po.load_from_db() po.load_from_db()
self.assertEqual(po.get("items")[0].received_qty, 4) self.assertEqual(po.get("items")[0].received_qty, 4)
frappe.db.set_value('Item', '_Test Item', 'tolerance', 50) frappe.db.set_value('Item', '_Test Item', 'over_delivery_receipt_allowance', 50)
pr = create_pr_against_po(po.name, received_qty=8) pr = create_pr_against_po(po.name, received_qty=8)
self.assertEqual(get_ordered_qty(), existing_ordered_qty) self.assertEqual(get_ordered_qty(), existing_ordered_qty)
@@ -57,12 +58,12 @@ class TestPurchaseOrder(unittest.TestCase):
def test_ordered_qty_against_pi_with_update_stock(self): def test_ordered_qty_against_pi_with_update_stock(self):
existing_ordered_qty = get_ordered_qty() existing_ordered_qty = get_ordered_qty()
po = create_purchase_order() po = create_purchase_order()
self.assertEqual(get_ordered_qty(), existing_ordered_qty + 10) self.assertEqual(get_ordered_qty(), existing_ordered_qty + 10)
frappe.db.set_value('Item', '_Test Item', 'tolerance', 50) frappe.db.set_value('Item', '_Test Item', 'over_delivery_receipt_allowance', 50)
frappe.db.set_value('Item', '_Test Item', 'over_billing_allowance', 20)
pi = make_pi_from_po(po.name) pi = make_pi_from_po(po.name)
pi.update_stock = 1 pi.update_stock = 1
@@ -81,6 +82,11 @@ class TestPurchaseOrder(unittest.TestCase):
po.load_from_db() po.load_from_db()
self.assertEqual(po.get("items")[0].received_qty, 0) self.assertEqual(po.get("items")[0].received_qty, 0)
frappe.db.set_value('Item', '_Test Item', 'over_delivery_receipt_allowance', 0)
frappe.db.set_value('Item', '_Test Item', 'over_billing_allowance', 0)
frappe.db.set_value("Accounts Settings", None, "over_billing_allowance", 0)
def test_update_child_qty_rate(self): def test_update_child_qty_rate(self):
mr = make_material_request(qty=10) mr = make_material_request(qty=10)
po = make_purchase_order(mr.name) po = make_purchase_order(mr.name)

View File

@@ -6,11 +6,12 @@ import frappe
def get_data(): def get_data():
config = [ config = [
{ {
"label": _("Masters and Accounts"), "label": _("Accounts Receivable"),
"items": [ "items": [
{ {
"type": "doctype", "type": "doctype",
"name": "Item", "name": "Sales Invoice",
"description": _("Bills raised to Customers."),
"onboard": 1, "onboard": 1,
}, },
{ {
@@ -19,12 +20,115 @@ def get_data():
"description": _("Customer database."), "description": _("Customer database."),
"onboard": 1, "onboard": 1,
}, },
{
"type": "doctype",
"name": "Payment Entry",
"description": _("Bank/Cash transactions against party or for internal transfer")
},
{
"type": "doctype",
"name": "Payment Request",
"description": _("Payment Request"),
},
{
"type": "report",
"name": "Accounts Receivable",
"doctype": "Sales Invoice",
"is_query_report": True
},
{
"type": "report",
"name": "Accounts Receivable Summary",
"doctype": "Sales Invoice",
"is_query_report": True
},
{
"type": "report",
"name": "Sales Register",
"doctype": "Sales Invoice",
"is_query_report": True
},
{
"type": "report",
"name": "Item-wise Sales Register",
"is_query_report": True,
"doctype": "Sales Invoice"
},
{
"type": "report",
"name": "Ordered Items To Be Billed",
"is_query_report": True,
"doctype": "Sales Invoice"
},
{
"type": "report",
"name": "Delivered Items To Be Billed",
"is_query_report": True,
"doctype": "Sales Invoice"
},
]
},
{
"label": _("Accounts Payable"),
"items": [
{
"type": "doctype",
"name": "Purchase Invoice",
"description": _("Bills raised by Suppliers."),
"onboard": 1
},
{ {
"type": "doctype", "type": "doctype",
"name": "Supplier", "name": "Supplier",
"description": _("Supplier database."), "description": _("Supplier database."),
"onboard": 1, "onboard": 1,
}, },
{
"type": "doctype",
"name": "Payment Entry",
"description": _("Bank/Cash transactions against party or for internal transfer")
},
{
"type": "report",
"name": "Accounts Payable",
"doctype": "Purchase Invoice",
"is_query_report": True
},
{
"type": "report",
"name": "Accounts Payable Summary",
"doctype": "Purchase Invoice",
"is_query_report": True
},
{
"type": "report",
"name": "Purchase Register",
"doctype": "Purchase Invoice",
"is_query_report": True
},
{
"type": "report",
"name": "Item-wise Purchase Register",
"is_query_report": True,
"doctype": "Purchase Invoice"
},
{
"type": "report",
"name": "Purchase Order Items To Be Billed",
"is_query_report": True,
"doctype": "Purchase Invoice"
},
{
"type": "report",
"name": "Received Items To Be Billed",
"is_query_report": True,
"doctype": "Purchase Invoice"
},
]
},
{
"label": _("Accounting Masters"),
"items": [
{ {
"type": "doctype", "type": "doctype",
"name": "Company", "name": "Company",
@@ -40,201 +144,31 @@ def get_data():
"description": _("Tree of financial accounts."), "description": _("Tree of financial accounts."),
"onboard": 1, "onboard": 1,
}, },
]
},
{
"label": _("Billing"),
"items": [
{
"type": "doctype",
"name": "Sales Invoice",
"description": _("Bills raised to Customers."),
"onboard": 1,
},
{
"type": "doctype",
"name": "Purchase Invoice",
"description": _("Bills raised by Suppliers."),
"onboard": 1
},
{
"type": "doctype",
"name": "Payment Request",
"description": _("Payment Request"),
},
{
"type": "doctype",
"name": "Payment Term",
"description": _("Payment Terms based on conditions")
},
# Reports
{
"type": "report",
"name": "Ordered Items To Be Billed",
"is_query_report": True,
"reference_doctype": "Sales Invoice"
},
{
"type": "report",
"name": "Delivered Items To Be Billed",
"is_query_report": True,
"reference_doctype": "Sales Invoice"
},
{
"type": "report",
"name": "Purchase Order Items To Be Billed",
"is_query_report": True,
"reference_doctype": "Purchase Invoice"
},
{
"type": "report",
"name": "Received Items To Be Billed",
"is_query_report": True,
"reference_doctype": "Purchase Invoice"
},
]
},
{
"label": _("Settings"),
"icon": "fa fa-cog",
"items": [
{ {
"type": "doctype", "type": "doctype",
"name": "Accounts Settings", "name": "Accounts Settings",
"description": _("Default settings for accounting transactions.")
}, },
{ {
"type": "doctype", "type": "doctype",
"name": "Fiscal Year", "name": "Fiscal Year",
"description": _("Financial / accounting year.") "description": _("Financial / accounting year.")
}, },
{
"type": "doctype",
"name": "Currency",
"description": _("Enable / disable currencies.")
},
{
"type": "doctype",
"name": "Currency Exchange",
"description": _("Currency exchange rate master.")
},
{
"type": "doctype",
"name": "Exchange Rate Revaluation",
"description": _("Exchange Rate Revaluation master.")
},
{
"type": "doctype",
"name": "Payment Gateway Account",
"description": _("Setup Gateway accounts.")
},
{
"type": "doctype",
"name": "Terms and Conditions",
"label": _("Terms and Conditions Template"),
"description": _("Template of terms or contract.")
},
{
"type": "doctype",
"name": "Mode of Payment",
"description": _("e.g. Bank, Cash, Credit Card")
},
{
"type": "doctype",
"name": "Auto Repeat",
"label": _("Auto Repeat"),
"description": _("To make recurring documents")
},
{
"type": "doctype",
"name": "C-Form",
"description": _("C-Form records"),
"country": "India"
},
{
"type": "doctype",
"name": "Cheque Print Template",
"description": _("Setup cheque dimensions for printing")
},
{ {
"type": "doctype", "type": "doctype",
"name": "Accounting Dimension", "name": "Accounting Dimension",
"description": _("Setup custom dimensions for accounting")
}, },
{ {
"type": "doctype", "type": "doctype",
"name": "Opening Invoice Creation Tool", "name": "Finance Book",
"description": _("Create Opening Sales and Purchase Invoices")
}
]
},
{
"label": _("Accounting Entries"),
"items": [
{
"type": "doctype",
"name": "Payment Entry",
"description": _("Bank/Cash transactions against party or for internal transfer")
}, },
{ {
"type": "doctype", "type": "doctype",
"name": "Journal Entry", "name": "Accounting Period",
"description": _("Accounting journal entries.")
}
]
}, },
{ {
"label": _("Financial Statements"), "type": "doctype",
"items": [ "name": "Payment Term",
{ "description": _("Payment Terms based on conditions")
"type": "report",
"name": "General Ledger",
"doctype": "GL Entry",
"is_query_report": True,
},
{
"type": "report",
"name": "Accounts Receivable",
"doctype": "Sales Invoice",
"is_query_report": True
},
{
"type": "report",
"name": "Accounts Payable",
"doctype": "Purchase Invoice",
"is_query_report": True
},
{
"type": "report",
"name": "Trial Balance",
"doctype": "GL Entry",
"is_query_report": True,
},
{
"type": "report",
"name": "Balance Sheet",
"doctype": "GL Entry",
"is_query_report": True
},
{
"type": "report",
"name": "Cash Flow",
"doctype": "GL Entry",
"is_query_report": True
},
{
"type": "report",
"name": "Profit and Loss Statement",
"doctype": "GL Entry",
"is_query_report": True
},
{
"type": "report",
"name": "Consolidated Financial Statement",
"doctype": "GL Entry",
"is_query_report": True
}, },
] ]
}, },
@@ -243,43 +177,10 @@ def get_data():
"items": [ "items": [
{ {
"type": "doctype", "type": "doctype",
"label": _("Bank"), "label": _("Match Payments with Invoices"),
"name": "Bank", "name": "Payment Reconciliation",
"description": _("Match non-linked Invoices and Payments.")
}, },
{
"type": "page",
"label": _("Reconcile payments and bank transactions"),
"name": "bank-reconciliation",
"description": _("Link bank transactions with payments.")
},
{
"type": "doctype",
"label": _("Bank Account"),
"name": "Bank Account",
},
{
"type": "doctype",
"label": _("Invoice Discounting"),
"name": "Invoice Discounting",
},
{
"type": "doctype",
"label": _("Bank Statement Transaction Entry List"),
"name": "Bank Statement Transaction Entry",
"route": "#List/Bank Statement Transaction Entry",
},
{
"type": "doctype",
"label": _("Bank Statement Transaction Entry Report"),
"name": "Bank Statement Transaction Entry",
"route": "#Report/Bank Statement Transaction Entry",
},
{
"type": "doctype",
"label": _("Bank Statement Settings"),
"name": "Bank Statement Settings",
},
{ {
"type": "doctype", "type": "doctype",
"label": _("Update Bank Transaction Dates"), "label": _("Update Bank Transaction Dates"),
@@ -288,9 +189,8 @@ def get_data():
}, },
{ {
"type": "doctype", "type": "doctype",
"label": _("Match Payments with Invoices"), "label": _("Invoice Discounting"),
"name": "Payment Reconciliation", "name": "Invoice Discounting",
"description": _("Match non-linked Invoices and Payments.")
}, },
{ {
"type": "report", "type": "report",
@@ -306,8 +206,75 @@ def get_data():
}, },
{ {
"type": "doctype", "type": "doctype",
"name": "Bank Guarantee", "name": "Bank Guarantee"
"doctype": "Bank Guarantee" },
{
"type": "doctype",
"name": "Cheque Print Template",
"description": _("Setup cheque dimensions for printing")
},
]
},
{
"label": _("General Ledger"),
"items": [
{
"type": "doctype",
"name": "Journal Entry",
"description": _("Accounting journal entries.")
},
{
"type": "report",
"name": "General Ledger",
"doctype": "GL Entry",
"is_query_report": True,
},
{
"type": "report",
"name": "Customer Ledger Summary",
"doctype": "Sales Invoice",
"is_query_report": True,
},
{
"type": "report",
"name": "Supplier Ledger Summary",
"doctype": "Sales Invoice",
"is_query_report": True,
}
]
},
{
"label": _("Taxes"),
"items": [
{
"type": "doctype",
"name": "Sales Taxes and Charges Template",
"description": _("Tax template for selling transactions.")
},
{
"type": "doctype",
"name": "Purchase Taxes and Charges Template",
"description": _("Tax template for buying transactions.")
},
{
"type": "doctype",
"name": "Item Tax Template",
"description": _("Tax template for item tax rates.")
},
{
"type": "doctype",
"name": "Tax Category",
"description": _("Tax Category for overriding tax rates.")
},
{
"type": "doctype",
"name": "Tax Rule",
"description": _("Tax Rule for transactions.")
},
{
"type": "doctype",
"name": "Tax Withholding Category",
"description": _("Tax Withholding rates to be applied on transactions.")
}, },
] ]
}, },
@@ -327,6 +294,10 @@ def get_data():
"name": "Budget", "name": "Budget",
"description": _("Define budget for a financial year.") "description": _("Define budget for a financial year.")
}, },
{
"type": "doctype",
"name": "Accounting Dimension",
},
{ {
"type": "report", "type": "report",
"name": "Budget Variance Report", "name": "Budget Variance Report",
@@ -338,51 +309,106 @@ def get_data():
"name": "Monthly Distribution", "name": "Monthly Distribution",
"description": _("Seasonality for setting budgets, targets etc.") "description": _("Seasonality for setting budgets, targets etc.")
}, },
]
},
{
"label": _("Financial Statements"),
"items": [
{
"type": "report",
"name": "Trial Balance",
"doctype": "GL Entry",
"is_query_report": True,
},
{
"type": "report",
"name": "Profit and Loss Statement",
"doctype": "GL Entry",
"is_query_report": True
},
{
"type": "report",
"name": "Balance Sheet",
"doctype": "GL Entry",
"is_query_report": True
},
{
"type": "report",
"name": "Cash Flow",
"doctype": "GL Entry",
"is_query_report": True
},
{
"type": "report",
"name": "Consolidated Financial Statement",
"doctype": "GL Entry",
"is_query_report": True
},
]
},
{
"label": _("Opening and Closing"),
"items": [
{
"type": "doctype",
"name": "Opening Invoice Creation Tool",
},
{
"type": "doctype",
"name": "Chart of Accounts Importer",
},
{ {
"type": "doctype", "type": "doctype",
"name": "Period Closing Voucher", "name": "Period Closing Voucher",
"description": _("Close Balance Sheet and book Profit or Loss.") "description": _("Close Balance Sheet and book Profit or Loss.")
}, },
] ]
}, },
{ {
"label": _("Taxes"), "label": _("Multi Currency"),
"items": [ "items": [
{ {
"type": "doctype", "type": "doctype",
"name": "Tax Category", "name": "Currency",
"description": _("Tax Category for overriding tax rates.") "description": _("Enable / disable currencies.")
}, },
{ {
"type": "doctype", "type": "doctype",
"name": "Sales Taxes and Charges Template", "name": "Currency Exchange",
"description": _("Tax template for selling transactions.") "description": _("Currency exchange rate master.")
}, },
{ {
"type": "doctype", "type": "doctype",
"name": "Purchase Taxes and Charges Template", "name": "Exchange Rate Revaluation",
"description": _("Tax template for buying transactions.") "description": _("Exchange Rate Revaluation master.")
},
]
},
{
"label": _("Settings"),
"icon": "fa fa-cog",
"items": [
{
"type": "doctype",
"name": "Payment Gateway Account",
"description": _("Setup Gateway accounts.")
}, },
{ {
"type": "doctype", "type": "doctype",
"name": "Item Tax Template", "name": "Terms and Conditions",
"description": _("Tax template for item tax rates.") "label": _("Terms and Conditions Template"),
"description": _("Template of terms or contract.")
}, },
{ {
"type": "doctype", "type": "doctype",
"name": "Tax Rule", "name": "Mode of Payment",
"description": _("Tax Rule for transactions.") "description": _("e.g. Bank, Cash, Credit Card")
},
{
"type": "doctype",
"name": "Tax Withholding Category",
"description": _("Tax Withholding rates to be applied on transactions.")
}, },
] ]
}, },
{ {
"label": _("Subscription Management"), "label": _("Subscription Management"),
"icon": "fa fa-microchip ",
"items": [ "items": [
{ {
"type": "doctype", "type": "doctype",
@@ -403,7 +429,31 @@ def get_data():
] ]
}, },
{ {
"label": _("Key Reports"), "label": _("Bank Statement"),
"items": [
{
"type": "doctype",
"label": _("Bank"),
"name": "Bank",
},
{
"type": "doctype",
"label": _("Bank Account"),
"name": "Bank Account",
},
{
"type": "doctype",
"name": "Bank Statement Transaction Entry",
},
{
"type": "doctype",
"label": _("Bank Statement Settings"),
"name": "Bank Statement Settings",
},
]
},
{
"label": _("Profitability"),
"items": [ "items": [
{ {
"type": "report", "type": "report",
@@ -413,21 +463,9 @@ def get_data():
}, },
{ {
"type": "report", "type": "report",
"name": "Sales Register", "name": "Profitability Analysis",
"doctype": "Sales Invoice", "doctype": "GL Entry",
"is_query_report": True
},
{
"type": "report",
"name": "Purchase Register",
"doctype": "Purchase Invoice",
"is_query_report": True
},
{
"type": "report",
"name": "Purchase Invoice Trends",
"is_query_report": True, "is_query_report": True,
"doctype": "Purchase Invoice"
}, },
{ {
"type": "report", "type": "report",
@@ -437,38 +475,14 @@ def get_data():
}, },
{ {
"type": "report", "type": "report",
"name": "Item-wise Sales Register", "name": "Purchase Invoice Trends",
"is_query_report": True,
"doctype": "Sales Invoice"
},
{
"type": "report",
"name": "Item-wise Purchase Register",
"is_query_report": True, "is_query_report": True,
"doctype": "Purchase Invoice" "doctype": "Purchase Invoice"
}, },
{
"type": "report",
"name": "Profitability Analysis",
"doctype": "GL Entry",
"is_query_report": True,
},
{
"type": "report",
"name": "Customer Ledger Summary",
"doctype": "Sales Invoice",
"is_query_report": True,
},
{
"type": "report",
"name": "Supplier Ledger Summary",
"doctype": "Sales Invoice",
"is_query_report": True,
}
] ]
}, },
{ {
"label": _("Other Reports"), "label": _("Reports"),
"icon": "fa fa-table", "icon": "fa fa-table",
"items": [ "items": [
{ {
@@ -489,18 +503,6 @@ def get_data():
"is_query_report": True, "is_query_report": True,
"doctype": "Sales Invoice" "doctype": "Sales Invoice"
}, },
{
"type": "report",
"name": "Accounts Receivable Summary",
"doctype": "Sales Invoice",
"is_query_report": True
},
{
"type": "report",
"name": "Accounts Payable Summary",
"doctype": "Purchase Invoice",
"is_query_report": True
},
{ {
"type": "report", "type": "report",
"is_query_report": True, "is_query_report": True,
@@ -549,27 +551,7 @@ def get_data():
} }
] ]
}, },
{
"label": _("Help"),
"icon": "fa fa-facetime-video",
"items": [
{
"type": "help",
"label": _("Chart of Accounts"),
"youtube_id": "DyR-DST-PyA"
},
{
"type": "help",
"label": _("Opening Accounting Balance"),
"youtube_id": "kdgM20Q-q68"
},
{
"type": "help",
"label": _("Setting up Taxes"),
"youtube_id": "nQ1zZdPgdaQ"
}
]
}
] ]
gst = { gst = {
@@ -617,6 +599,12 @@ def get_data():
"name": "GST Itemised Purchase Register", "name": "GST Itemised Purchase Register",
"is_query_report": True "is_query_report": True
}, },
{
"type": "doctype",
"name": "C-Form",
"description": _("C-Form records"),
"country": "India"
},
] ]
} }
@@ -624,6 +612,6 @@ def get_data():
countries = frappe.get_all("Company", fields="country") countries = frappe.get_all("Company", fields="country")
countries = [country["country"] for country in countries] countries = [country["country"] for country in countries]
if "India" in countries: if "India" in countries:
config.insert(7, gst) config.insert(9, gst)
domains = frappe.get_active_domains() domains = frappe.get_active_domains()
return config return config

View File

@@ -228,29 +228,5 @@ def get_data():
} }
] ]
}, },
{
"label": _("Help"),
"items": [
{
"type": "help",
"label": _("Customer and Supplier"),
"youtube_id": "anoGi_RpQ20"
},
{
"type": "help",
"label": _("Material Request to Purchase Order"),
"youtube_id": "4TN9kPyfIqM"
},
{
"type": "help",
"label": _("Purchase Order to Payment"),
"youtube_id": "EK65tLdVUDk"
},
{
"type": "help",
"label": _("Managing Subcontracting"),
"youtube_id": "ThiMCC2DtKo"
},
]
},
] ]

View File

@@ -4,127 +4,13 @@ from frappe import _
def get_data(): def get_data():
return [ return [
{ {
"label": _("Employee and Attendance"), "label": _("Employee"),
"items": [ "items": [
{ {
"type": "doctype", "type": "doctype",
"name": "Employee", "name": "Employee",
"onboard": 1, "onboard": 1,
}, },
{
"type": "doctype",
"name": "Employee Attendance Tool",
"hide_count": True,
"onboard": 1,
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Employee Group",
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Attendance",
"onboard": 1,
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Attendance Request",
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Upload Attendance",
"hide_count": True,
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Employee Checkin",
"hide_count": True,
"onboard": 1,
"dependencies": ["Employee"]
},
]
},
{
"label": _("Payroll"),
"items": [
{
"type": "doctype",
"name": "Salary Structure",
"onboard": 1,
},
{
"type": "doctype",
"name": "Salary Structure Assignment",
"onboard": 1,
"dependencies": ["Salary Structure", "Employee"],
},
{
"type": "doctype",
"name": "Salary Slip",
"onboard": 1,
},
{
"type": "doctype",
"name": "Payroll Entry",
"onboard": 1,
},
{
"type": "doctype",
"name": "Employee Benefit Application",
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Employee Benefit Claim",
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Additional Salary",
},
{
"type": "doctype",
"name": "Employee Tax Exemption Declaration",
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Employee Tax Exemption Proof Submission",
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Employee Incentive",
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Retention Bonus",
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Payroll Period",
},
{
"type": "doctype",
"name": "Salary Component",
},
]
},
{
"label": _("Settings"),
"icon": "fa fa-cog",
"items": [
{
"type": "doctype",
"name": "HR Settings",
},
{ {
"type": "doctype", "type": "doctype",
"name": "Employment Type", "name": "Employment Type",
@@ -147,19 +33,56 @@ def get_data():
}, },
{ {
"type": "doctype", "type": "doctype",
"name": "Daily Work Summary Group" "name": "Employee Group",
"dependencies": ["Employee"]
}, },
{ {
"type": "doctype", "type": "doctype",
"name": "Employee Health Insurance" "name": "Employee Health Insurance"
}, },
{
"type": "doctype",
"name": "Staffing Plan",
}
] ]
}, },
{
"label": _("Attendance"),
"items": [
{
"type": "doctype",
"name": "Employee Attendance Tool",
"hide_count": True,
"onboard": 1,
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Attendance",
"onboard": 1,
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Attendance Request",
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Upload Attendance",
"hide_count": True,
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Employee Checkin",
"hide_count": True,
"dependencies": ["Employee"]
},
{
"type": "report",
"is_query_report": True,
"name": "Monthly Attendance Sheet",
"doctype": "Attendance"
},
]
},
{ {
"label": _("Leaves"), "label": _("Leaves"),
"items": [ "items": [
@@ -175,13 +98,8 @@ def get_data():
}, },
{ {
"type": "doctype", "type": "doctype",
"name": "Compensatory Leave Request", "name": "Leave Policy",
"dependencies": ["Employee"] "dependencies": ["Leave Type"]
},
{
"type": "doctype",
"name": "Leave Encashment",
"dependencies": ["Employee"]
}, },
{ {
"type": "doctype", "type": "doctype",
@@ -194,37 +112,167 @@ def get_data():
}, },
{ {
"type": "doctype", "type": "doctype",
"name": "Leave Policy", "name": "Holiday List",
"dependencies": ["Leave Type"]
}, },
{ {
"type": "doctype", "type": "doctype",
"name": "Holiday List", "name": "Compensatory Leave Request",
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Leave Encashment",
"dependencies": ["Employee"]
}, },
{ {
"type": "doctype", "type": "doctype",
"name": "Leave Block List", "name": "Leave Block List",
}, },
{
"type": "report",
"is_query_report": True,
"name": "Employee Leave Balance",
"doctype": "Leave Application"
},
] ]
}, },
{ {
"label": _("Recruitment and Training"), "label": _("Payroll"),
"items": [ "items": [
{ {
"type": "doctype", "type": "doctype",
"name": "Job Applicant", "name": "Salary Structure",
"onboard": 1, "onboard": 1,
}, },
{
"type": "doctype",
"name": "Salary Structure Assignment",
"onboard": 1,
"dependencies": ["Salary Structure", "Employee"],
},
{
"type": "doctype",
"name": "Payroll Entry",
"onboard": 1,
},
{
"type": "doctype",
"name": "Salary Slip",
"onboard": 1,
},
{
"type": "doctype",
"name": "Salary Component",
},
{
"type": "doctype",
"name": "Additional Salary",
},
{
"type": "doctype",
"name": "Retention Bonus",
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Employee Incentive",
"dependencies": ["Employee"]
},
{
"type": "report",
"is_query_report": True,
"name": "Salary Register",
"doctype": "Salary Slip"
},
]
},
{
"label": _("Employee Tax and Benefits"),
"items": [
{
"type": "doctype",
"name": "Employee Tax Exemption Declaration",
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Employee Tax Exemption Proof Submission",
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Employee Benefit Application",
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Employee Benefit Claim",
"dependencies": ["Employee"]
},
]
},
{
"label": _("Employee Lifecycle"),
"items": [
{
"type": "doctype",
"name": "Employee Onboarding",
"dependencies": ["Job Applicant"],
},
{
"type": "doctype",
"name": "Employee Promotion",
"dependencies": ["Employee"],
},
{
"type": "doctype",
"name": "Employee Transfer",
"dependencies": ["Employee"],
},
{
"type": "doctype",
"name": "Employee Separation",
"dependencies": ["Employee"],
},
{
"type": "doctype",
"name": "Employee Onboarding Template",
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Employee Separation Template",
"dependencies": ["Employee"]
},
]
},
{
"label": _("Recruitment"),
"items": [
{ {
"type": "doctype", "type": "doctype",
"name": "Job Opening", "name": "Job Opening",
"onboard": 1, "onboard": 1,
}, },
{
"type": "doctype",
"name": "Job Applicant",
"onboard": 1,
},
{ {
"type": "doctype", "type": "doctype",
"name": "Job Offer", "name": "Job Offer",
"onboard": 1, "onboard": 1,
}, },
{
"type": "doctype",
"name": "Staffing Plan",
},
]
},
{
"label": _("Training"),
"items": [
{ {
"type": "doctype", "type": "doctype",
"name": "Training Program" "name": "Training Program"
@@ -244,42 +292,7 @@ def get_data():
] ]
}, },
{ {
"label": _("Employee Lifecycle"), "label": _("Performance"),
"items": [
{
"type": "doctype",
"name": "Employee Transfer",
"dependencies": ["Employee"],
},
{
"type": "doctype",
"name": "Employee Promotion",
"dependencies": ["Employee"],
},
{
"type": "doctype",
"name": "Employee Separation",
"dependencies": ["Employee"],
},
{
"type": "doctype",
"name": "Employee Onboarding",
"dependencies": ["Job Applicant"],
},
{
"type": "doctype",
"name": "Employee Separation Template",
"dependencies": ["Employee"]
},
{
"type": "doctype",
"name": "Employee Onboarding Template",
"dependencies": ["Employee"]
}
]
},
{
"label": _("Appraisals, Expense Claims and Loans"),
"items": [ "items": [
{ {
"type": "doctype", "type": "doctype",
@@ -290,15 +303,24 @@ def get_data():
"name": "Appraisal Template", "name": "Appraisal Template",
}, },
{ {
"type": "page", "type": "doctype",
"name": "team-updates", "name": "Energy Point Rule",
"label": _("Team Updates")
}, },
{ {
"type": "doctype", "type": "doctype",
"name": "Employee Advance", "name": "Energy Point Log",
"dependencies": ["Employee"]
}, },
{
"type": "link",
"doctype": "Energy Point Log",
"label": _("Energy Point Leaderboard"),
"route": "#social/users"
},
]
},
{
"label": _("Expense Claims"),
"items": [
{ {
"type": "doctype", "type": "doctype",
"name": "Expense Claim", "name": "Expense Claim",
@@ -306,8 +328,14 @@ def get_data():
}, },
{ {
"type": "doctype", "type": "doctype",
"name": "Loan Type", "name": "Employee Advance",
"dependencies": ["Employee"]
}, },
]
},
{
"label": _("Loans"),
"items": [
{ {
"type": "doctype", "type": "doctype",
"name": "Loan Application", "name": "Loan Application",
@@ -316,19 +344,72 @@ def get_data():
{ {
"type": "doctype", "type": "doctype",
"name": "Loan" "name": "Loan"
} },
{
"type": "doctype",
"name": "Loan Type",
},
]
},
{
"label": _("Shift Management"),
"items": [
{
"type": "doctype",
"name": "Shift Type",
},
{
"type": "doctype",
"name": "Shift Request",
},
{
"type": "doctype",
"name": "Shift Assignment",
},
]
},
{
"label": _("Fleet Management"),
"items": [
{
"type": "doctype",
"name": "Vehicle"
},
{
"type": "doctype",
"name": "Vehicle Log"
},
{
"type": "report",
"is_query_report": True,
"name": "Vehicle Expenses",
"doctype": "Vehicle"
},
]
},
{
"label": _("Settings"),
"icon": "fa fa-cog",
"items": [
{
"type": "doctype",
"name": "HR Settings",
},
{
"type": "doctype",
"name": "Daily Work Summary Group"
},
{
"type": "page",
"name": "team-updates",
"label": _("Team Updates")
},
] ]
}, },
{ {
"label": _("Reports"), "label": _("Reports"),
"icon": "fa fa-list", "icon": "fa fa-list",
"items": [ "items": [
{
"type": "report",
"is_query_report": True,
"name": "Employee Leave Balance",
"doctype": "Leave Application"
},
{ {
"type": "report", "type": "report",
"is_query_report": True, "is_query_report": True,
@@ -341,29 +422,6 @@ def get_data():
"name": "Employees working on a holiday", "name": "Employees working on a holiday",
"doctype": "Employee" "doctype": "Employee"
}, },
{
"type": "report",
"name": "Employee Information",
"doctype": "Employee"
},
{
"type": "report",
"is_query_report": True,
"name": "Salary Register",
"doctype": "Salary Slip"
},
{
"type": "report",
"is_query_report": True,
"name": "Monthly Attendance Sheet",
"doctype": "Attendance"
},
{
"type": "report",
"is_query_report": True,
"name": "Vehicle Expenses",
"doctype": "Vehicle"
},
{ {
"type": "report", "type": "report",
"is_query_report": True, "is_query_report": True,
@@ -372,50 +430,4 @@ def get_data():
}, },
] ]
}, },
{
"label": _("Shifts and Fleet Management"),
"items": [
{
"type": "doctype",
"name": "Shift Type",
},
{
"type": "doctype",
"name": "Shift Request",
},
{
"type": "doctype",
"name": "Shift Assignment",
},
{
"type": "doctype",
"name": "Vehicle"
},
{
"type": "doctype",
"name": "Vehicle Log"
},
]
},
# {
# "label": _("Help"),
# "icon": "fa fa-facetime-video",
# "items": [
# {
# "type": "help",
# "label": _("Setting up Employees"),
# "youtube_id": "USfIUdZlUhw"
# },
# {
# "type": "help",
# "label": _("Leave Management"),
# "youtube_id": "fc0p_AXebc8"
# },
# {
# "type": "help",
# "label": _("Expense Claims"),
# "youtube_id": "5SZHJF--ZFY"
# }
# ]
# },
] ]

View File

@@ -88,17 +88,14 @@ def get_data():
"doctype": "Project", "doctype": "Project",
"dependencies": ["Project"], "dependencies": ["Project"],
}, },
]
},
{ {
"label": _("Help"), "type": "report",
"icon": "fa fa-facetime-video", "is_query_report": True,
"items": [ "name": "Project Billing Summary",
{ "doctype": "Project",
"type": "help", "dependencies": ["Project"],
"label": _("Managing Projects"),
"youtube_id": "egxIGwtoKI4"
}, },
] ]
}, },
] ]

View File

@@ -318,41 +318,5 @@ def get_data():
} }
] ]
}, },
{
"label": _("SMS"),
"icon": "fa fa-wrench",
"items": [
{
"type": "doctype",
"name": "SMS Center",
"description":_("Send mass SMS to your contacts"),
},
{
"type": "doctype",
"name": "SMS Log",
"description":_("Logs for maintaining sms delivery status"),
},
] ]
},
{
"label": _("Help"),
"items": [
{
"type": "help",
"label": _("Customer and Supplier"),
"youtube_id": "anoGi_RpQ20"
},
{
"type": "help",
"label": _("Sales Order to Payment"),
"youtube_id": "1eP90MWoDQM"
},
{
"type": "help",
"label": _("Point-of-Sale"),
"youtube_id": "4WkelWkbP_c"
},
]
},
]

View File

@@ -329,45 +329,5 @@ def get_data():
} }
] ]
}, },
{
"label": _("Help"),
"icon": "fa fa-facetime-video",
"items": [
{
"type": "help",
"label": _("Items and Pricing"),
"youtube_id": "qXaEwld4_Ps"
},
{
"type": "help",
"label": _("Item Variants"),
"youtube_id": "OGBETlCzU5o"
},
{
"type": "help",
"label": _("Opening Stock Balance"),
"youtube_id": "0yPgrtfeCTs"
},
{
"type": "help",
"label": _("Making Stock Entries"),
"youtube_id": "Njt107hlY3I"
},
{
"type": "help",
"label": _("Serialized Inventory"),
"youtube_id": "gvOVlEwFDAk"
},
{
"type": "help",
"label": _("Batch Inventory"),
"youtube_id": "J0QKl7ABPKM"
},
{
"type": "help",
"label": _("Managing Subcontracting"),
"youtube_id": "ThiMCC2DtKo"
},
]
}
] ]

View File

@@ -488,8 +488,7 @@ class AccountsController(TransactionBase):
return res return res
def is_inclusive_tax(self): def is_inclusive_tax(self):
is_inclusive = cint(frappe.db.get_single_value("Accounts Settings", is_inclusive = cint(frappe.db.get_single_value("Accounts Settings", "show_inclusive_tax_in_print"))
"show_inclusive_tax_in_print"))
if is_inclusive: if is_inclusive:
is_inclusive = 0 is_inclusive = 0
@@ -576,9 +575,9 @@ class AccountsController(TransactionBase):
unlink_ref_doc_from_payment_entries(self) unlink_ref_doc_from_payment_entries(self)
def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield): def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield):
from erpnext.controllers.status_updater import get_tolerance_for from erpnext.controllers.status_updater import get_allowance_for
item_tolerance = {} item_allowance = {}
global_tolerance = None global_qty_allowance, global_amount_allowance = None, None
for item in self.get("items"): for item in self.get("items"):
if item.get(item_ref_dn): if item.get(item_ref_dn):
@@ -586,26 +585,27 @@ class AccountsController(TransactionBase):
item.get(item_ref_dn), based_on), self.precision(based_on, item)) item.get(item_ref_dn), based_on), self.precision(based_on, item))
if not ref_amt: if not ref_amt:
frappe.msgprint( frappe.msgprint(
_("Warning: System will not check overbilling since amount for Item {0} in {1} is zero").format( _("Warning: System will not check overbilling since amount for Item {0} in {1} is zero")
item.item_code, ref_dt)) .format(item.item_code, ref_dt))
else: else:
already_billed = frappe.db.sql("""select sum(%s) from `tab%s` already_billed = frappe.db.sql("""
where %s=%s and docstatus=1 and parent != %s""" % select sum(%s)
(based_on, self.doctype + " Item", item_ref_dn, '%s', '%s'), from `tab%s`
where %s=%s and docstatus=1 and parent != %s
""" % (based_on, self.doctype + " Item", item_ref_dn, '%s', '%s'),
(item.get(item_ref_dn), self.name))[0][0] (item.get(item_ref_dn), self.name))[0][0]
total_billed_amt = flt(flt(already_billed) + flt(item.get(based_on)), total_billed_amt = flt(flt(already_billed) + flt(item.get(based_on)),
self.precision(based_on, item)) self.precision(based_on, item))
tolerance, item_tolerance, global_tolerance = get_tolerance_for(item.item_code, allowance, item_allowance, global_qty_allowance, global_amount_allowance = \
item_tolerance, global_tolerance) get_allowance_for(item.item_code, item_allowance, global_qty_allowance, global_amount_allowance, "amount")
max_allowed_amt = flt(ref_amt * (100 + tolerance) / 100) max_allowed_amt = flt(ref_amt * (100 + allowance) / 100)
if total_billed_amt - max_allowed_amt > 0.01: if total_billed_amt - max_allowed_amt > 0.01:
frappe.throw(_( frappe.throw(_("Cannot overbill for Item {0} in row {1} more than {2}. To allow over-billing, please set in Stock Settings")
"Cannot overbill for Item {0} in row {1} more than {2}. To allow over-billing, please set in Stock Settings").format( .format(item.item_code, item.idx, max_allowed_amt))
item.item_code, item.idx, max_allowed_amt))
def get_company_default(self, fieldname): def get_company_default(self, fieldname):
from erpnext.accounts.utils import get_company_default from erpnext.accounts.utils import get_company_default
@@ -615,9 +615,10 @@ class AccountsController(TransactionBase):
stock_items = [] stock_items = []
item_codes = list(set(item.item_code for item in self.get("items"))) item_codes = list(set(item.item_code for item in self.get("items")))
if item_codes: if item_codes:
stock_items = [r[0] for r in frappe.db.sql("""select name stock_items = [r[0] for r in frappe.db.sql("""
from `tabItem` where name in (%s) and is_stock_item=1""" % \ select name from `tabItem`
(", ".join((["%s"] * len(item_codes))),), item_codes)] where name in (%s) and is_stock_item=1
""" % (", ".join((["%s"] * len(item_codes))),), item_codes)]
return stock_items return stock_items

View File

@@ -7,6 +7,8 @@ from frappe.utils import flt, comma_or, nowdate, getdate
from frappe import _ from frappe import _
from frappe.model.document import Document from frappe.model.document import Document
class OverAllowanceError(frappe.ValidationError): pass
def validate_status(status, options): def validate_status(status, options):
if status not in options: if status not in options:
frappe.throw(_("Status must be one of {0}").format(comma_or(options))) frappe.throw(_("Status must be one of {0}").format(comma_or(options)))
@@ -43,16 +45,6 @@ status_map = {
["Closed", "eval:self.status=='Closed'"], ["Closed", "eval:self.status=='Closed'"],
["On Hold", "eval:self.status=='On Hold'"], ["On Hold", "eval:self.status=='On Hold'"],
], ],
"Sales Invoice": [
["Draft", None],
["Submitted", "eval:self.docstatus==1"],
["Paid", "eval:self.outstanding_amount==0 and self.docstatus==1"],
["Return", "eval:self.is_return==1 and self.docstatus==1"],
["Credit Note Issued", "eval:self.outstanding_amount < 0 and self.docstatus==1"],
["Unpaid", "eval:self.outstanding_amount > 0 and getdate(self.due_date) >= getdate(nowdate()) and self.docstatus==1"],
["Overdue", "eval:self.outstanding_amount > 0 and getdate(self.due_date) < getdate(nowdate()) and self.docstatus==1"],
["Cancelled", "eval:self.docstatus==2"],
],
"Purchase Invoice": [ "Purchase Invoice": [
["Draft", None], ["Draft", None],
["Submitted", "eval:self.docstatus==1"], ["Submitted", "eval:self.docstatus==1"],
@@ -154,8 +146,9 @@ class StatusUpdater(Document):
def validate_qty(self): def validate_qty(self):
"""Validates qty at row level""" """Validates qty at row level"""
self.tolerance = {} self.item_allowance = {}
self.global_tolerance = None self.global_qty_allowance = None
self.global_amount_allowance = None
for args in self.status_updater: for args in self.status_updater:
if "target_ref_field" not in args: if "target_ref_field" not in args:
@@ -186,32 +179,41 @@ class StatusUpdater(Document):
# if not item[args['target_ref_field']]: # if not item[args['target_ref_field']]:
# msgprint(_("Note: System will not check over-delivery and over-booking for Item {0} as quantity or amount is 0").format(item.item_code)) # msgprint(_("Note: System will not check over-delivery and over-booking for Item {0} as quantity or amount is 0").format(item.item_code))
if args.get('no_tolerance'): if args.get('no_allowance'):
item['reduce_by'] = item[args['target_field']] - item[args['target_ref_field']] item['reduce_by'] = item[args['target_field']] - item[args['target_ref_field']]
if item['reduce_by'] > .01: if item['reduce_by'] > .01:
self.limits_crossed_error(args, item) self.limits_crossed_error(args, item)
elif item[args['target_ref_field']]: elif item[args['target_ref_field']]:
self.check_overflow_with_tolerance(item, args) self.check_overflow_with_allowance(item, args)
def check_overflow_with_tolerance(self, item, args): def check_overflow_with_allowance(self, item, args):
""" """
Checks if there is overflow condering a relaxation tolerance Checks if there is overflow condering a relaxation allowance
""" """
# check if overflow is within tolerance qty_or_amount = "qty" if "qty" in args['target_ref_field'] else "amount"
tolerance, self.tolerance, self.global_tolerance = get_tolerance_for(item['item_code'],
self.tolerance, self.global_tolerance) # check if overflow is within allowance
allowance, self.item_allowance, self.global_qty_allowance, self.global_amount_allowance = \
get_allowance_for(item['item_code'], self.item_allowance,
self.global_qty_allowance, self.global_amount_allowance, qty_or_amount)
overflow_percent = ((item[args['target_field']] - item[args['target_ref_field']]) / overflow_percent = ((item[args['target_field']] - item[args['target_ref_field']]) /
item[args['target_ref_field']]) * 100 item[args['target_ref_field']]) * 100
if overflow_percent - tolerance > 0.01: if overflow_percent - allowance > 0.01:
item['max_allowed'] = flt(item[args['target_ref_field']] * (100+tolerance)/100) item['max_allowed'] = flt(item[args['target_ref_field']] * (100+allowance)/100)
item['reduce_by'] = item[args['target_field']] - item['max_allowed'] item['reduce_by'] = item[args['target_field']] - item['max_allowed']
self.limits_crossed_error(args, item) self.limits_crossed_error(args, item, qty_or_amount)
def limits_crossed_error(self, args, item): def limits_crossed_error(self, args, item, qty_or_amount):
'''Raise exception for limits crossed''' '''Raise exception for limits crossed'''
if qty_or_amount == "qty":
action_msg = _('To allow over receipt / delivery, update "Over Receipt/Delivery Allowance" in Stock Settings or the Item.')
else:
action_msg = _('To allow over billing, update "Over Billing Allowance" in Accounts Settings or the Item.')
frappe.throw(_('This document is over limit by {0} {1} for item {4}. Are you making another {3} against the same {2}?') frappe.throw(_('This document is over limit by {0} {1} for item {4}. Are you making another {3} against the same {2}?')
.format( .format(
frappe.bold(_(item["target_ref_field"].title())), frappe.bold(_(item["target_ref_field"].title())),
@@ -219,9 +221,7 @@ class StatusUpdater(Document):
frappe.bold(_(args.get('target_dt'))), frappe.bold(_(args.get('target_dt'))),
frappe.bold(_(self.doctype)), frappe.bold(_(self.doctype)),
frappe.bold(item.get('item_code')) frappe.bold(item.get('item_code'))
) + '<br><br>' + ) + '<br><br>' + action_msg, OverAllowanceError, title = _('Limit Crossed'))
_('To allow over-billing or over-ordering, update "Allowance" in Stock Settings or the Item.'),
title = _('Limit Crossed'))
def update_qty(self, update_modified=True): def update_qty(self, update_modified=True):
"""Updates qty or amount at row level """Updates qty or amount at row level
@@ -358,19 +358,34 @@ class StatusUpdater(Document):
ref_doc.db_set("per_billed", per_billed) ref_doc.db_set("per_billed", per_billed)
ref_doc.set_status(update=True) ref_doc.set_status(update=True)
def get_tolerance_for(item_code, item_tolerance={}, global_tolerance=None): def get_allowance_for(item_code, item_allowance={}, global_qty_allowance=None, global_amount_allowance=None, qty_or_amount="qty"):
""" """
Returns the tolerance for the item, if not set, returns global tolerance Returns the allowance for the item, if not set, returns global allowance
""" """
if item_tolerance.get(item_code): if qty_or_amount == "qty":
return item_tolerance[item_code], item_tolerance, global_tolerance if item_allowance.get(item_code, frappe._dict()).get("qty"):
return item_allowance[item_code].qty, item_allowance, global_qty_allowance, global_amount_allowance
else:
if item_allowance.get(item_code, frappe._dict()).get("amount"):
return item_allowance[item_code].amount, item_allowance, global_qty_allowance, global_amount_allowance
tolerance = flt(frappe.db.get_value('Item',item_code,'tolerance') or 0) qty_allowance, over_billing_allowance = \
frappe.db.get_value('Item', item_code, ['over_delivery_receipt_allowance', 'over_billing_allowance'])
if not tolerance: if qty_or_amount == "qty" and not qty_allowance:
if global_tolerance == None: if global_qty_allowance == None:
global_tolerance = flt(frappe.db.get_value('Stock Settings', None, 'tolerance')) global_qty_allowance = flt(frappe.db.get_single_value('Stock Settings', 'over_delivery_receipt_allowance'))
tolerance = global_tolerance qty_allowance = global_qty_allowance
elif qty_or_amount == "amount" and not over_billing_allowance:
if global_amount_allowance == None:
global_amount_allowance = flt(frappe.db.get_single_value('Accounts Settings', 'over_billing_allowance'))
over_billing_allowance = global_amount_allowance
item_tolerance[item_code] = tolerance if qty_or_amount == "qty":
return tolerance, item_tolerance, global_tolerance allowance = qty_allowance
item_allowance.setdefault(item_code, frappe._dict()).setdefault("qty", qty_allowance)
else:
allowance = over_billing_allowance
item_allowance.setdefault(item_code, frappe._dict()).setdefault("amount", over_billing_allowance)
return allowance, item_allowance, global_qty_allowance, global_amount_allowance

View File

@@ -19,6 +19,10 @@ frappe.ui.form.on("Opportunity", {
} }
} }
}); });
if (frm.doc.opportunity_from && frm.doc.party_name){
frm.trigger('set_contact_link');
}
}, },
onload_post_render: function(frm) { onload_post_render: function(frm) {

View File

@@ -15,7 +15,7 @@ frappe.ui.form.on('HR Settings', {
let policy = frm.doc.password_policy; let policy = frm.doc.password_policy;
if (policy) { if (policy) {
if (policy.includes(' ') || policy.includes('--')) { if (policy.includes(' ') || policy.includes('--')) {
frappe.msgprint(_("Password policy cannot contain spaces or simultaneous hyphens. The format will be restructured automatically")); frappe.msgprint(__("Password policy cannot contain spaces or simultaneous hyphens. The format will be restructured automatically"));
} }
frm.set_value('password_policy', policy.split(new RegExp(" |-", 'g')).filter((token) => token).join('-')); frm.set_value('password_policy', policy.split(new RegExp(" |-", 'g')).filter((token) => token).join('-'));
} }

View File

@@ -29,9 +29,12 @@ class LoanApplication(Document):
if self.repayment_method == "Repay Fixed Amount per Period": if self.repayment_method == "Repay Fixed Amount per Period":
monthly_interest_rate = flt(self.rate_of_interest) / (12 *100) monthly_interest_rate = flt(self.rate_of_interest) / (12 *100)
if monthly_interest_rate: if monthly_interest_rate:
self.repayment_periods = math.ceil((math.log(self.repayment_amount) - min_repayment_amount = self.loan_amount*monthly_interest_rate
math.log(self.repayment_amount - (self.loan_amount*monthly_interest_rate))) / if self.repayment_amount - min_repayment_amount < 0:
(math.log(1 + monthly_interest_rate))) frappe.throw(_("Repayment Amount must be greater than " \
+ str(flt(min_repayment_amount, 2))))
self.repayment_periods = math.ceil(math.log(self.repayment_amount) -
math.log(self.repayment_amount - min_repayment_amount) /(math.log(1 + monthly_interest_rate)))
else: else:
self.repayment_periods = self.loan_amount / self.repayment_amount self.repayment_periods = self.loan_amount / self.repayment_amount

View File

@@ -31,21 +31,22 @@ class TestLoanApplication(unittest.TestCase):
"rate_of_interest": 9.2, "rate_of_interest": 9.2,
"loan_amount": 250000, "loan_amount": 250000,
"repayment_method": "Repay Over Number of Periods", "repayment_method": "Repay Over Number of Periods",
"repayment_periods": 24 "repayment_periods": 18
}) })
loan_application.insert() loan_application.insert()
def test_loan_totals(self): def test_loan_totals(self):
loan_application = frappe.get_doc("Loan Application", {"applicant":self.applicant}) loan_application = frappe.get_doc("Loan Application", {"applicant":self.applicant})
self.assertEquals(loan_application.repayment_amount, 11445)
self.assertEquals(loan_application.total_payable_interest, 24657)
self.assertEquals(loan_application.total_payable_amount, 274657)
loan_application.repayment_method = "Repay Fixed Amount per Period" self.assertEqual(loan_application.total_payable_interest, 18599)
loan_application.repayment_amount = 15000 self.assertEqual(loan_application.total_payable_amount, 268599)
self.assertEqual(loan_application.repayment_amount, 14923)
loan_application.repayment_periods = 24
loan_application.save() loan_application.save()
loan_application.reload()
self.assertEqual(loan_application.repayment_periods, 18) self.assertEqual(loan_application.total_payable_interest, 24657)
self.assertEqual(loan_application.total_payable_interest, 18506) self.assertEqual(loan_application.total_payable_amount, 274657)
self.assertEqual(loan_application.total_payable_amount, 268506) self.assertEqual(loan_application.repayment_amount, 11445)

View File

@@ -505,6 +505,7 @@ erpnext.patches.v10_0.update_hub_connector_domain
erpnext.patches.v10_0.set_student_party_type erpnext.patches.v10_0.set_student_party_type
erpnext.patches.v10_0.update_project_in_sle erpnext.patches.v10_0.update_project_in_sle
erpnext.patches.v10_0.fix_reserved_qty_for_sub_contract erpnext.patches.v10_0.fix_reserved_qty_for_sub_contract
erpnext.patches.v10_0.repost_requested_qty_for_non_stock_uom_items
erpnext.patches.v11_0.merge_land_unit_with_location erpnext.patches.v11_0.merge_land_unit_with_location
erpnext.patches.v11_0.add_index_on_nestedset_doctypes erpnext.patches.v11_0.add_index_on_nestedset_doctypes
erpnext.patches.v11_0.remove_modules_setup_page erpnext.patches.v11_0.remove_modules_setup_page
@@ -602,6 +603,7 @@ erpnext.patches.v11_1.set_salary_details_submittable
erpnext.patches.v11_1.rename_depends_on_lwp erpnext.patches.v11_1.rename_depends_on_lwp
execute:frappe.delete_doc("Report", "Inactive Items") execute:frappe.delete_doc("Report", "Inactive Items")
erpnext.patches.v11_1.delete_scheduling_tool erpnext.patches.v11_1.delete_scheduling_tool
erpnext.patches.v12_0.rename_tolerance_fields
erpnext.patches.v12_0.make_custom_fields_for_bank_remittance #14-06-2019 erpnext.patches.v12_0.make_custom_fields_for_bank_remittance #14-06-2019
execute:frappe.delete_doc_if_exists("Page", "support-analytics") execute:frappe.delete_doc_if_exists("Page", "support-analytics")
erpnext.patches.v12_0.make_item_manufacturer erpnext.patches.v12_0.make_item_manufacturer

View File

@@ -0,0 +1,21 @@
# Copyright (c) 2019, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
def execute():
from erpnext.stock.stock_balance import update_bin_qty, get_indented_qty
count=0
for item_code, warehouse in frappe.db.sql("""select distinct item_code, warehouse
from `tabMaterial Request Item` where docstatus = 1 and stock_uom<>uom"""):
try:
count += 1
update_bin_qty(item_code, warehouse, {
"indented_qty": get_indented_qty(item_code, warehouse),
})
if count % 200 == 0:
frappe.db.commit()
except:
frappe.db.rollback()

View File

@@ -0,0 +1,15 @@
import frappe
from frappe.model.utils.rename_field import rename_field
def execute():
frappe.reload_doc("stock", "doctype", "item")
frappe.reload_doc("stock", "doctype", "stock_settings")
frappe.reload_doc("accounts", "doctype", "accounts_settings")
rename_field('Stock Settings', "tolerance", "over_delivery_receipt_allowance")
rename_field('Item', "tolerance", "over_delivery_receipt_allowance")
qty_allowance = frappe.db.get_single_value("Stock Settings", "over_delivery_receipt_allowance")
frappe.db.set_value("Accounts Settings", None, "over_delivery_receipt_allowance", qty_allowance)
frappe.db.sql("update tabItem set over_billing_allowance=over_delivery_receipt_allowance")

View File

@@ -1424,11 +1424,14 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
}, },
callback: function(r) { callback: function(r) {
if(!r.exc) { if(!r.exc) {
me.frm.set_value("taxes", r.message); if(me.frm.doc.shipping_rule && me.frm.doc.taxes) {
for (let tax of r.message) {
me.frm.add_child("taxes", tax);
}
if(me.frm.doc.shipping_rule) { refresh_field("taxes");
me.frm.script_manager.trigger("shipping_rule");
} else { } else {
me.frm.set_value("taxes", r.message);
me.calculate_taxes_and_totals(); me.calculate_taxes_and_totals();
} }
} }

View File

@@ -65,7 +65,7 @@ $.extend(erpnext.queries, {
frappe.throw(__("Please set {0}", frappe.throw(__("Please set {0}",
[__(frappe.meta.get_label(doc.doctype, frappe.dynamic_link.fieldname, doc.name))])); [__(frappe.meta.get_label(doc.doctype, frappe.dynamic_link.fieldname, doc.name))]));
} }
console.log(frappe.dynamic_link)
return { return {
query: 'frappe.contacts.doctype.address.address.address_query', query: 'frappe.contacts.doctype.address.address.address_query',
filters: { filters: {

View File

@@ -145,7 +145,7 @@ erpnext.utils.set_taxes_from_address = function(frm, triggered_from_field, billi
erpnext.utils.set_taxes = function(frm, triggered_from_field) { erpnext.utils.set_taxes = function(frm, triggered_from_field) {
if(frappe.meta.get_docfield(frm.doc.doctype, "taxes")) { if(frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
if(!erpnext.utils.validate_mandatory(frm, "Lead/Customer/Supplier", if(!erpnext.utils.validate_mandatory(frm, "Lead/Customer/Supplier",
frm.doc.customer || frm.doc.supplier || frm.doc.lead, triggered_from_field)) { frm.doc.customer || frm.doc.supplier || frm.doc.lead || frm.doc.party_name, triggered_from_field)) {
return; return;
} }

View File

@@ -28,7 +28,7 @@
"fieldtype": "Select", "fieldtype": "Select",
"in_list_view": 1, "in_list_view": 1,
"label": "Rating", "label": "Rating",
"options": "1\n2\n3\n4\n5", "options": "\n1\n2\n3\n4\n5",
"reqd": 1 "reqd": 1
}, },
{ {
@@ -44,7 +44,7 @@
} }
], ],
"istable": 1, "istable": 1,
"modified": "2019-05-26 21:50:48.951264", "modified": "2019-07-13 19:58:08.966141",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Quality Management", "module": "Quality Management",
"name": "Quality Feedback Parameter", "name": "Quality Feedback Parameter",

View File

@@ -26,7 +26,7 @@
"fieldname": "status", "fieldname": "status",
"fieldtype": "Select", "fieldtype": "Select",
"label": "Status", "label": "Status",
"options": "Open\nClose" "options": "Open\nClosed"
}, },
{ {
"fieldname": "minutes", "fieldname": "minutes",
@@ -55,7 +55,7 @@
"label": "Minutes" "label": "Minutes"
} }
], ],
"modified": "2019-05-26 23:12:23.364357", "modified": "2019-07-13 19:57:40.500541",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Quality Management", "module": "Quality Management",
"name": "Quality Meeting", "name": "Quality Meeting",

View File

@@ -34,7 +34,7 @@ frappe.listview_settings['Sales Order'] = {
"per_delivered,<,100|per_billed,=,100|status,!=,Closed"]; "per_delivered,<,100|per_billed,=,100|status,!=,Closed"];
} }
} else if ((flt(doc.per_delivered, 6) == 100) } else if ((flt(doc.per_delivered, 6) === 100)
&& flt(doc.grand_total) !== 0 && flt(doc.per_billed, 6) < 100 && doc.status !== "Closed") { && flt(doc.grand_total) !== 0 && flt(doc.per_billed, 6) < 100 && doc.status !== "Closed") {
// to bill // to bill
@@ -48,7 +48,7 @@ frappe.listview_settings['Sales Order'] = {
if(flt(doc.per_billed, 6) < 100 ){ if(flt(doc.per_billed, 6) < 100 ){
return [__("To Deliver and Bill"), "orange", "per_delivered,=,100|per_billed,<,100|status,!=,Closed"]; return [__("To Deliver and Bill"), "orange", "per_delivered,=,100|per_billed,<,100|status,!=,Closed"];
}else if(flt(doc.per_billed, 6) == 100){ }else if(flt(doc.per_billed, 6) === 100){
return [__("To Deliver"), "orange", "per_delivered,=,100|per_billed,=,100|status,!=,Closed"]; return [__("To Deliver"), "orange", "per_delivered,=,100|per_billed,=,100|status,!=,Closed"];
} }
} }

View File

@@ -192,8 +192,8 @@ class TestSalesOrder(unittest.TestCase):
def test_reserved_qty_for_over_delivery(self): def test_reserved_qty_for_over_delivery(self):
make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100) make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100)
# set over-delivery tolerance # set over-delivery allowance
frappe.db.set_value('Item', "_Test Item", 'tolerance', 50) frappe.db.set_value('Item', "_Test Item", 'over_delivery_receipt_allowance', 50)
existing_reserved_qty = get_reserved_qty() existing_reserved_qty = get_reserved_qty()
@@ -209,8 +209,9 @@ class TestSalesOrder(unittest.TestCase):
def test_reserved_qty_for_over_delivery_via_sales_invoice(self): def test_reserved_qty_for_over_delivery_via_sales_invoice(self):
make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100) make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100)
# set over-delivery tolerance # set over-delivery allowance
frappe.db.set_value('Item', "_Test Item", 'tolerance', 50) frappe.db.set_value('Item', "_Test Item", 'over_delivery_receipt_allowance', 50)
frappe.db.set_value('Item', "_Test Item", 'over_billing_allowance', 20)
existing_reserved_qty = get_reserved_qty() existing_reserved_qty = get_reserved_qty()
@@ -291,8 +292,8 @@ class TestSalesOrder(unittest.TestCase):
make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100) make_stock_entry(target="_Test Warehouse - _TC", qty=10, rate=100)
make_stock_entry(item="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=10, rate=100) make_stock_entry(item="_Test Item Home Desktop 100", target="_Test Warehouse - _TC", qty=10, rate=100)
# set over-delivery tolerance # set over-delivery allowance
frappe.db.set_value('Item', "_Test Product Bundle Item", 'tolerance', 50) frappe.db.set_value('Item', "_Test Product Bundle Item", 'over_delivery_receipt_allowance', 50)
existing_reserved_qty_item1 = get_reserved_qty("_Test Item") existing_reserved_qty_item1 = get_reserved_qty("_Test Item")
existing_reserved_qty_item2 = get_reserved_qty("_Test Item Home Desktop 100") existing_reserved_qty_item2 = get_reserved_qty("_Test Item Home Desktop 100")

View File

@@ -51,7 +51,7 @@ class DeliveryNote(SellingController):
'source_field': 'qty', 'source_field': 'qty',
'percent_join_field': 'against_sales_invoice', 'percent_join_field': 'against_sales_invoice',
'overflow_type': 'delivery', 'overflow_type': 'delivery',
'no_tolerance': 1 'no_allowance': 1
}] }]
if cint(self.is_return): if cint(self.is_return):
self.status_updater.append({ self.status_updater.append({

View File

@@ -29,7 +29,8 @@
"is_fixed_asset", "is_fixed_asset",
"asset_category", "asset_category",
"asset_naming_series", "asset_naming_series",
"tolerance", "over_delivery_receipt_allowance",
"over_billing_allowance",
"image", "image",
"section_break_11", "section_break_11",
"brand", "brand",
@@ -284,14 +285,6 @@
"fieldtype": "Select", "fieldtype": "Select",
"label": "Asset Naming Series" "label": "Asset Naming Series"
}, },
{
"depends_on": "eval:!doc.__islocal",
"fieldname": "tolerance",
"fieldtype": "Float",
"label": "Allow over delivery or receipt upto this percent",
"oldfieldname": "tolerance",
"oldfieldtype": "Currency"
},
{ {
"fieldname": "image", "fieldname": "image",
"fieldtype": "Attach Image", "fieldtype": "Attach Image",
@@ -1021,6 +1014,26 @@
"fieldtype": "Check", "fieldtype": "Check",
"label": "Synced With Hub", "label": "Synced With Hub",
"read_only": 1 "read_only": 1
},
{
"fieldname": "manufacturers",
"fieldtype": "Table",
"label": "Manufacturers",
"options": "Item Manufacturer"
},
{
"depends_on": "eval:!doc.__islocal",
"fieldname": "over_delivery_receipt_allowance",
"fieldtype": "Float",
"label": "Over Delivery/Receipt Allowance (%)",
"oldfieldname": "tolerance",
"oldfieldtype": "Currency"
},
{
"fieldname": "over_billing_allowance",
"fieldtype": "Float",
"label": "Over Billing Allowance (%)",
"depends_on": "eval:!doc.__islocal"
} }
], ],
"has_web_view": 1, "has_web_view": 1,
@@ -1028,7 +1041,7 @@
"idx": 2, "idx": 2,
"image_field": "image", "image_field": "image",
"max_attachments": 1, "max_attachments": 1,
"modified": "2019-07-05 12:18:13.977931", "modified": "2019-07-12 12:18:13.977931",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Item", "name": "Item",

View File

@@ -1007,7 +1007,7 @@ def invalidate_item_variants_cache_for_website(doc):
if item_code: if item_code:
item_cache = ItemVariantsCacheManager(item_code) item_cache = ItemVariantsCacheManager(item_code)
item_cache.rebuild_cache() item_cache.clear_cache()
def check_stock_uom_with_bin(item, stock_uom): def check_stock_uom_with_bin(item, stock_uom):

View File

@@ -255,7 +255,7 @@
"columns": 0, "columns": 0,
"description": "Percentage you are allowed to receive or deliver more against the quantity ordered. For example: If you have ordered 100 units. and your Allowance is 10% then you are allowed to receive 110 units.", "description": "Percentage you are allowed to receive or deliver more against the quantity ordered. For example: If you have ordered 100 units. and your Allowance is 10% then you are allowed to receive 110 units.",
"fetch_if_empty": 0, "fetch_if_empty": 0,
"fieldname": "tolerance", "fieldname": "over_delivery_receipt_allowance",
"fieldtype": "Float", "fieldtype": "Float",
"hidden": 0, "hidden": 0,
"ignore_user_permissions": 0, "ignore_user_permissions": 0,
@@ -264,7 +264,7 @@
"in_global_search": 0, "in_global_search": 0,
"in_list_view": 0, "in_list_view": 0,
"in_standard_filter": 0, "in_standard_filter": 0,
"label": "Limit Percent", "label": "Over Delivery/Receipt Allowance (%)",
"length": 0, "length": 0,
"no_copy": 0, "no_copy": 0,
"permlevel": 0, "permlevel": 0,
@@ -918,7 +918,7 @@
"issingle": 1, "issingle": 1,
"istable": 0, "istable": 0,
"max_attachments": 0, "max_attachments": 0,
"modified": "2019-06-18 01:19:07.738045", "modified": "2019-07-04 01:19:07.738045",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Stock", "module": "Stock",
"name": "Stock Settings", "name": "Stock Settings",

View File

@@ -110,7 +110,7 @@ def get_reserved_qty(item_code, warehouse):
return flt(reserved_qty[0][0]) if reserved_qty else 0 return flt(reserved_qty[0][0]) if reserved_qty else 0
def get_indented_qty(item_code, warehouse): def get_indented_qty(item_code, warehouse):
indented_qty = frappe.db.sql("""select sum(mr_item.qty - mr_item.ordered_qty) indented_qty = frappe.db.sql("""select sum((mr_item.qty - mr_item.ordered_qty) * mr_item.conversion_factor)
from `tabMaterial Request Item` mr_item, `tabMaterial Request` mr from `tabMaterial Request Item` mr_item, `tabMaterial Request` mr
where mr_item.item_code=%s and mr_item.warehouse=%s where mr_item.item_code=%s and mr_item.warehouse=%s
and mr_item.qty > mr_item.ordered_qty and mr_item.parent=mr.name and mr_item.qty > mr_item.ordered_qty and mr_item.parent=mr.name

View File

@@ -270,6 +270,7 @@ def get_expected_time_for(parameter, service_level, start_date_time):
allotted_days -= 1 allotted_days -= 1
expected_time_is_set = allotted_days <= 0 expected_time_is_set = allotted_days <= 0
if not expected_time_is_set:
current_date_time = add_to_date(current_date_time, days=1) current_date_time = add_to_date(current_date_time, days=1)
if end_time and time_period != 'Hour': if end_time and time_period != 'Hour':

View File

@@ -29,10 +29,10 @@ frappe.ready(function() {
.html(r.message.product_info.price.formatted_price_sales_uom + "<div style='font-size: small'>\ .html(r.message.product_info.price.formatted_price_sales_uom + "<div style='font-size: small'>\
(" + r.message.product_info.price.formatted_price + " / " + r.message.product_info.uom + ")</div>"); (" + r.message.product_info.price.formatted_price + " / " + r.message.product_info.uom + ")</div>");
if(r.message.product_info.in_stock==0) { if(r.message.product_info.in_stock===0) {
$(".item-stock").html("<div style='color: red'> <i class='fa fa-close'></i> {{ _("Not in stock") }}</div>"); $(".item-stock").html("<div style='color: red'> <i class='fa fa-close'></i> {{ _("Not in stock") }}</div>");
} }
else if(r.message.product_info.in_stock==1) { else if(r.message.product_info.in_stock===1) {
var qty_display = "{{ _("In stock") }}"; var qty_display = "{{ _("In stock") }}";
if (r.message.product_info.show_stock_qty) { if (r.message.product_info.show_stock_qty) {
qty_display += " ("+r.message.product_info.stock_qty+")"; qty_display += " ("+r.message.product_info.stock_qty+")";
@@ -75,13 +75,13 @@ frappe.ready(function() {
newVal = 0; newVal = 0;
if (btn.attr('data-dir') == 'up') { if (btn.attr('data-dir') == 'up') {
newVal = parseInt(oldValue) + 1; newVal = Number.parseInt(oldValue) + 1;
} else if (btn.attr('data-dir') == 'dwn') { } else if (btn.attr('data-dir') == 'dwn') {
if (parseInt(oldValue) > 1) { if (Number.parseInt(oldValue) > 1) {
newVal = parseInt(oldValue) - 1; newVal = Number.parseInt(oldValue) - 1;
} }
else { else {
newVal = parseInt(oldValue); newVal = Number.parseInt(oldValue);
} }
} }
input.val(newVal); input.val(newVal);

View File