Merge branch 'develop' of github.com:frappe/erpnext into feature-pick-list
This commit is contained in:
commit
ed4f8cf65d
@ -48,7 +48,10 @@ class BankAccount(Document):
|
|||||||
# Encode characters as numbers
|
# Encode characters as numbers
|
||||||
encoded = [encode_char(c) if ord(c) >= 65 and ord(c) <= 90 else c for c in flipped]
|
encoded = [encode_char(c) if ord(c) >= 65 and ord(c) <= 90 else c for c in flipped]
|
||||||
|
|
||||||
to_check = int(''.join(encoded))
|
try:
|
||||||
|
to_check = int(''.join(encoded))
|
||||||
|
except ValueError:
|
||||||
|
frappe.throw(_('IBAN is not valid'))
|
||||||
|
|
||||||
if to_check % 97 != 1:
|
if to_check % 97 != 1:
|
||||||
frappe.throw(_('IBAN is not valid'))
|
frappe.throw(_('IBAN is not valid'))
|
||||||
|
@ -223,7 +223,10 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
|
|||||||
|
|
||||||
if(in_list(["Sales Invoice", "Purchase Invoice"], jvd.reference_type)) {
|
if(in_list(["Sales Invoice", "Purchase Invoice"], jvd.reference_type)) {
|
||||||
out.filters.push([jvd.reference_type, "outstanding_amount", "!=", 0]);
|
out.filters.push([jvd.reference_type, "outstanding_amount", "!=", 0]);
|
||||||
|
// Filter by cost center
|
||||||
|
if(jvd.cost_center) {
|
||||||
|
out.filters.push([jvd.reference_type, "cost_center", "in", ["", jvd.cost_center]]);
|
||||||
|
}
|
||||||
// account filter
|
// account filter
|
||||||
frappe.model.validate_missing(jvd, "account");
|
frappe.model.validate_missing(jvd, "account");
|
||||||
var party_account_field = jvd.reference_type==="Sales Invoice" ? "debit_to": "credit_to";
|
var party_account_field = jvd.reference_type==="Sales Invoice" ? "debit_to": "credit_to";
|
||||||
|
@ -1,751 +1,166 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
|
||||||
"allow_events_in_timeline": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2019-03-24 14:48:59.649168",
|
"creation": "2019-03-24 14:48:59.649168",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"disable",
|
||||||
|
"column_break_2",
|
||||||
|
"rule_description",
|
||||||
|
"section_break_1",
|
||||||
|
"min_qty",
|
||||||
|
"max_qty",
|
||||||
|
"column_break_3",
|
||||||
|
"min_amount",
|
||||||
|
"max_amount",
|
||||||
|
"section_break_6",
|
||||||
|
"same_item",
|
||||||
|
"free_item",
|
||||||
|
"free_qty",
|
||||||
|
"column_break_9",
|
||||||
|
"free_item_uom",
|
||||||
|
"free_item_rate",
|
||||||
|
"section_break_12",
|
||||||
|
"warehouse",
|
||||||
|
"threshold_percentage",
|
||||||
|
"column_break_15",
|
||||||
|
"priority",
|
||||||
|
"apply_multiple_pricing_rules"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"default": "0",
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "disable",
|
"fieldname": "disable",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Check",
|
||||||
"hidden": 0,
|
"label": "Disable"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Disable",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_2",
|
"fieldname": "column_break_2",
|
||||||
"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": "rule_description",
|
"fieldname": "rule_description",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Rule Description",
|
"label": "Rule Description",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"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_1",
|
"fieldname": "section_break_1",
|
||||||
"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,
|
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "min_qty",
|
"fieldname": "min_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"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": "Min Qty"
|
||||||
"label": "Min Qty",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "max_qty",
|
"fieldname": "max_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"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": "Max Qty"
|
||||||
"label": "Max Qty",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_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,
|
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "min_amount",
|
"fieldname": "min_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": "Min Amount"
|
||||||
"label": "Min Amount",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "max_amount",
|
"fieldname": "max_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": "Max Amount"
|
||||||
"label": "Max Amount",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_6",
|
"fieldname": "section_break_6",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"label": "Free Item"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Free Item",
|
|
||||||
"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,
|
"default": "0",
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"depends_on": "eval:!parent.mixed_conditions",
|
"depends_on": "eval:!parent.mixed_conditions",
|
||||||
"fieldname": "same_item",
|
"fieldname": "same_item",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"hidden": 0,
|
"label": "Same Item"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Same Item",
|
|
||||||
"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,
|
|
||||||
"depends_on": "eval:!doc.same_item || parent.mixed_conditions",
|
"depends_on": "eval:!doc.same_item || parent.mixed_conditions",
|
||||||
"fieldname": "free_item",
|
"fieldname": "free_item",
|
||||||
"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": "Item Code",
|
"label": "Item Code",
|
||||||
"length": 0,
|
"options": "Item"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Item",
|
|
||||||
"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": "free_qty",
|
"fieldname": "free_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"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": "Qty"
|
||||||
"label": "Qty",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_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": "free_item_uom",
|
"fieldname": "free_item_uom",
|
||||||
"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": "UOM",
|
"label": "UOM",
|
||||||
"length": 0,
|
"options": "UOM"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "UOM",
|
|
||||||
"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": "free_item_rate",
|
"fieldname": "free_item_rate",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
"label": "Rate"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Rate",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_12",
|
"fieldname": "section_break_12",
|
||||||
"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": "warehouse",
|
"fieldname": "warehouse",
|
||||||
"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": "Warehouse",
|
"label": "Warehouse",
|
||||||
"length": 0,
|
"options": "Warehouse"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Warehouse",
|
|
||||||
"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": "threshold_percentage",
|
"fieldname": "threshold_percentage",
|
||||||
"fieldtype": "Percent",
|
"fieldtype": "Percent",
|
||||||
"hidden": 0,
|
"label": "Threshold for Suggestion"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Threshold for Suggestion",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_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": "priority",
|
"fieldname": "priority",
|
||||||
"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": "Priority",
|
"label": "Priority",
|
||||||
"length": 0,
|
"options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20",
|
|
||||||
"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,
|
"default": "0",
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "apply_multiple_pricing_rules",
|
"fieldname": "apply_multiple_pricing_rules",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"hidden": 0,
|
"label": "Apply Multiple Pricing Rules"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Apply Multiple Pricing Rules",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"idx": 0,
|
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"modified": "2019-07-21 00:00:56.674284",
|
||||||
"modified": "2019-03-24 14:48:59.649168",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Promotional Scheme Product Discount",
|
"name": "Promotional Scheme Product Discount",
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
"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": 0,
|
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
@ -336,6 +336,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
|
|
||||||
if not self.is_return:
|
if not self.is_return:
|
||||||
self.update_against_document_in_jv()
|
self.update_against_document_in_jv()
|
||||||
|
self.update_billing_status_for_zero_amount_refdoc("Purchase Receipt")
|
||||||
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
|
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
|
||||||
|
|
||||||
self.update_billing_status_in_pr()
|
self.update_billing_status_in_pr()
|
||||||
@ -774,6 +775,7 @@ class PurchaseInvoice(BuyingController):
|
|||||||
self.update_prevdoc_status()
|
self.update_prevdoc_status()
|
||||||
|
|
||||||
if not self.is_return:
|
if not self.is_return:
|
||||||
|
self.update_billing_status_for_zero_amount_refdoc("Purchase Receipt")
|
||||||
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
|
self.update_billing_status_for_zero_amount_refdoc("Purchase Order")
|
||||||
|
|
||||||
self.update_billing_status_in_pr()
|
self.update_billing_status_in_pr()
|
||||||
|
@ -451,6 +451,10 @@ def make_customer_and_address(customers):
|
|||||||
|
|
||||||
|
|
||||||
def add_customer(data):
|
def add_customer(data):
|
||||||
|
customer = data.get('full_name') or data.get('customer')
|
||||||
|
if frappe.db.exists("Customer", customer.strip()):
|
||||||
|
return customer.strip()
|
||||||
|
|
||||||
customer_doc = frappe.new_doc('Customer')
|
customer_doc = frappe.new_doc('Customer')
|
||||||
customer_doc.customer_name = data.get('full_name') or data.get('customer')
|
customer_doc.customer_name = data.get('full_name') or data.get('customer')
|
||||||
customer_doc.customer_pos_id = data.get('customer_pos_id')
|
customer_doc.customer_pos_id = data.get('customer_pos_id')
|
||||||
|
@ -166,6 +166,7 @@ class SalesInvoice(SellingController):
|
|||||||
self.make_gl_entries()
|
self.make_gl_entries()
|
||||||
|
|
||||||
if not self.is_return:
|
if not self.is_return:
|
||||||
|
self.update_billing_status_for_zero_amount_refdoc("Delivery Note")
|
||||||
self.update_billing_status_for_zero_amount_refdoc("Sales Order")
|
self.update_billing_status_for_zero_amount_refdoc("Sales Order")
|
||||||
self.check_credit_limit()
|
self.check_credit_limit()
|
||||||
|
|
||||||
@ -220,6 +221,7 @@ class SalesInvoice(SellingController):
|
|||||||
self.update_billing_status_in_dn()
|
self.update_billing_status_in_dn()
|
||||||
|
|
||||||
if not self.is_return:
|
if not self.is_return:
|
||||||
|
self.update_billing_status_for_zero_amount_refdoc("Delivery Note")
|
||||||
self.update_billing_status_for_zero_amount_refdoc("Sales Order")
|
self.update_billing_status_for_zero_amount_refdoc("Sales Order")
|
||||||
self.update_serial_no(in_cancel=True)
|
self.update_serial_no(in_cancel=True)
|
||||||
|
|
||||||
@ -395,14 +397,17 @@ class SalesInvoice(SellingController):
|
|||||||
if pos.get('account_for_change_amount'):
|
if pos.get('account_for_change_amount'):
|
||||||
self.account_for_change_amount = pos.get('account_for_change_amount')
|
self.account_for_change_amount = pos.get('account_for_change_amount')
|
||||||
|
|
||||||
for fieldname in ('territory', 'naming_series', 'currency', 'taxes_and_charges', 'letter_head', 'tc_name',
|
for fieldname in ('territory', 'naming_series', 'currency', 'letter_head', 'tc_name',
|
||||||
'company', 'select_print_heading', 'cash_bank_account', 'company_address',
|
'company', 'select_print_heading', 'cash_bank_account', 'write_off_account', 'taxes_and_charges',
|
||||||
'write_off_account', 'write_off_cost_center', 'apply_discount_on', 'cost_center'):
|
'write_off_cost_center', 'apply_discount_on', 'cost_center'):
|
||||||
if (not for_validate) or (for_validate and not self.get(fieldname)):
|
if (not for_validate) or (for_validate and not self.get(fieldname)):
|
||||||
self.set(fieldname, pos.get(fieldname))
|
self.set(fieldname, pos.get(fieldname))
|
||||||
|
|
||||||
customer_price_list = frappe.get_value("Customer", self.customer, 'default_price_list')
|
customer_price_list = frappe.get_value("Customer", self.customer, 'default_price_list')
|
||||||
|
|
||||||
|
if pos.get("company_address"):
|
||||||
|
self.company_address = pos.get("company_address")
|
||||||
|
|
||||||
if not customer_price_list:
|
if not customer_price_list:
|
||||||
self.set('selling_price_list', pos.get('selling_price_list'))
|
self.set('selling_price_list', pos.get('selling_price_list'))
|
||||||
|
|
||||||
@ -1255,9 +1260,8 @@ def validate_inter_company_party(doctype, party, company, inter_company_referenc
|
|||||||
frappe.throw(_("Invalid Company for Inter Company Transaction."))
|
frappe.throw(_("Invalid Company for Inter Company Transaction."))
|
||||||
|
|
||||||
elif frappe.db.get_value(partytype, {"name": party, internal: 1}, "name") == party:
|
elif frappe.db.get_value(partytype, {"name": party, internal: 1}, "name") == party:
|
||||||
companies = frappe.db.sql("""select company from `tabAllowed To Transact With`
|
companies = frappe.get_all("Allowed To Transact With", fields=["company"], filters={"parenttype": partytype, "parent": party})
|
||||||
where parenttype = '{0}' and parent = '{1}'""".format(partytype, party), as_list = 1)
|
companies = [d.company for d in companies]
|
||||||
companies = [d[0] for d in companies]
|
|
||||||
if not company in companies:
|
if not company in companies:
|
||||||
frappe.throw(_("{0} not allowed to transact with {1}. Please change the Company.").format(partytype, company))
|
frappe.throw(_("{0} not allowed to transact with {1}. Please change the Company.").format(partytype, company))
|
||||||
|
|
||||||
|
@ -12,11 +12,11 @@ def execute(filters=None):
|
|||||||
columns = get_columns()
|
columns = get_columns()
|
||||||
|
|
||||||
if not filters.get("account"): return columns, []
|
if not filters.get("account"): return columns, []
|
||||||
|
|
||||||
account_currency = frappe.db.get_value("Account", filters.account, "account_currency")
|
account_currency = frappe.db.get_value("Account", filters.account, "account_currency")
|
||||||
|
|
||||||
data = get_entries(filters)
|
data = get_entries(filters)
|
||||||
|
|
||||||
from erpnext.accounts.utils import get_balance_on
|
from erpnext.accounts.utils import get_balance_on
|
||||||
balance_as_per_system = get_balance_on(filters["account"], filters["report_date"])
|
balance_as_per_system = get_balance_on(filters["account"], filters["report_date"])
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ def execute(filters=None):
|
|||||||
for d in data:
|
for d in data:
|
||||||
total_debit += flt(d.debit)
|
total_debit += flt(d.debit)
|
||||||
total_credit += flt(d.credit)
|
total_credit += flt(d.credit)
|
||||||
|
|
||||||
amounts_not_reflected_in_system = get_amounts_not_reflected_in_system(filters)
|
amounts_not_reflected_in_system = get_amounts_not_reflected_in_system(filters)
|
||||||
|
|
||||||
bank_bal = flt(balance_as_per_system) - flt(total_debit) + flt(total_credit) \
|
bank_bal = flt(balance_as_per_system) - flt(total_debit) + flt(total_credit) \
|
||||||
@ -39,7 +39,7 @@ def execute(filters=None):
|
|||||||
"credit": total_credit,
|
"credit": total_credit,
|
||||||
"account_currency": account_currency
|
"account_currency": account_currency
|
||||||
},
|
},
|
||||||
get_balance_row(_("Cheques and Deposits incorrectly cleared"), amounts_not_reflected_in_system,
|
get_balance_row(_("Cheques and Deposits incorrectly cleared"), amounts_not_reflected_in_system,
|
||||||
account_currency),
|
account_currency),
|
||||||
{},
|
{},
|
||||||
get_balance_row(_("Calculated Bank Statement balance"), bank_bal, account_currency)
|
get_balance_row(_("Calculated Bank Statement balance"), bank_bal, account_currency)
|
||||||
@ -55,9 +55,16 @@ def get_columns():
|
|||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"width": 90
|
"width": 90
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "payment_document",
|
||||||
|
"label": _("Payment Document Type"),
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"options": "DocType",
|
||||||
|
"width": 220
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "payment_entry",
|
"fieldname": "payment_entry",
|
||||||
"label": _("Payment Entry"),
|
"label": _("Payment Document"),
|
||||||
"fieldtype": "Dynamic Link",
|
"fieldtype": "Dynamic Link",
|
||||||
"options": "payment_document",
|
"options": "payment_document",
|
||||||
"width": 220
|
"width": 220
|
||||||
@ -100,7 +107,7 @@ def get_columns():
|
|||||||
"label": _("Clearance Date"),
|
"label": _("Clearance Date"),
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"width": 110
|
"width": 110
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "account_currency",
|
"fieldname": "account_currency",
|
||||||
"label": _("Currency"),
|
"label": _("Currency"),
|
||||||
@ -112,9 +119,9 @@ def get_columns():
|
|||||||
|
|
||||||
def get_entries(filters):
|
def get_entries(filters):
|
||||||
journal_entries = frappe.db.sql("""
|
journal_entries = frappe.db.sql("""
|
||||||
select "Journal Entry" as payment_document, jv.posting_date,
|
select "Journal Entry" as payment_document, jv.posting_date,
|
||||||
jv.name as payment_entry, jvd.debit_in_account_currency as debit,
|
jv.name as payment_entry, jvd.debit_in_account_currency as debit,
|
||||||
jvd.credit_in_account_currency as credit, jvd.against_account,
|
jvd.credit_in_account_currency as credit, jvd.against_account,
|
||||||
jv.cheque_no as reference_no, jv.cheque_date as ref_date, jv.clearance_date, jvd.account_currency
|
jv.cheque_no as reference_no, jv.cheque_date as ref_date, jv.clearance_date, jvd.account_currency
|
||||||
from
|
from
|
||||||
`tabJournal Entry Account` jvd, `tabJournal Entry` jv
|
`tabJournal Entry Account` jvd, `tabJournal Entry` jv
|
||||||
@ -122,13 +129,13 @@ def get_entries(filters):
|
|||||||
and jvd.account = %(account)s and jv.posting_date <= %(report_date)s
|
and jvd.account = %(account)s and jv.posting_date <= %(report_date)s
|
||||||
and ifnull(jv.clearance_date, '4000-01-01') > %(report_date)s
|
and ifnull(jv.clearance_date, '4000-01-01') > %(report_date)s
|
||||||
and ifnull(jv.is_opening, 'No') = 'No'""", filters, as_dict=1)
|
and ifnull(jv.is_opening, 'No') = 'No'""", filters, as_dict=1)
|
||||||
|
|
||||||
payment_entries = frappe.db.sql("""
|
payment_entries = frappe.db.sql("""
|
||||||
select
|
select
|
||||||
"Payment Entry" as payment_document, name as payment_entry,
|
"Payment Entry" as payment_document, name as payment_entry,
|
||||||
reference_no, reference_date as ref_date,
|
reference_no, reference_date as ref_date,
|
||||||
if(paid_to=%(account)s, received_amount, 0) as debit,
|
if(paid_to=%(account)s, received_amount, 0) as debit,
|
||||||
if(paid_from=%(account)s, paid_amount, 0) as credit,
|
if(paid_from=%(account)s, paid_amount, 0) as credit,
|
||||||
posting_date, ifnull(party,if(paid_from=%(account)s,paid_to,paid_from)) as against_account, clearance_date,
|
posting_date, ifnull(party,if(paid_from=%(account)s,paid_to,paid_from)) as against_account, clearance_date,
|
||||||
if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency
|
if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency
|
||||||
from `tabPayment Entry`
|
from `tabPayment Entry`
|
||||||
@ -156,25 +163,25 @@ def get_entries(filters):
|
|||||||
|
|
||||||
return sorted(list(payment_entries)+list(journal_entries+list(pos_entries)),
|
return sorted(list(payment_entries)+list(journal_entries+list(pos_entries)),
|
||||||
key=lambda k: k['posting_date'] or getdate(nowdate()))
|
key=lambda k: k['posting_date'] or getdate(nowdate()))
|
||||||
|
|
||||||
def get_amounts_not_reflected_in_system(filters):
|
def get_amounts_not_reflected_in_system(filters):
|
||||||
je_amount = frappe.db.sql("""
|
je_amount = frappe.db.sql("""
|
||||||
select sum(jvd.debit_in_account_currency - jvd.credit_in_account_currency)
|
select sum(jvd.debit_in_account_currency - jvd.credit_in_account_currency)
|
||||||
from `tabJournal Entry Account` jvd, `tabJournal Entry` jv
|
from `tabJournal Entry Account` jvd, `tabJournal Entry` jv
|
||||||
where jvd.parent = jv.name and jv.docstatus=1 and jvd.account=%(account)s
|
where jvd.parent = jv.name and jv.docstatus=1 and jvd.account=%(account)s
|
||||||
and jv.posting_date > %(report_date)s and jv.clearance_date <= %(report_date)s
|
and jv.posting_date > %(report_date)s and jv.clearance_date <= %(report_date)s
|
||||||
and ifnull(jv.is_opening, 'No') = 'No' """, filters)
|
and ifnull(jv.is_opening, 'No') = 'No' """, filters)
|
||||||
|
|
||||||
je_amount = flt(je_amount[0][0]) if je_amount else 0.0
|
je_amount = flt(je_amount[0][0]) if je_amount else 0.0
|
||||||
|
|
||||||
pe_amount = frappe.db.sql("""
|
pe_amount = frappe.db.sql("""
|
||||||
select sum(if(paid_from=%(account)s, paid_amount, received_amount))
|
select sum(if(paid_from=%(account)s, paid_amount, received_amount))
|
||||||
from `tabPayment Entry`
|
from `tabPayment Entry`
|
||||||
where (paid_from=%(account)s or paid_to=%(account)s) and docstatus=1
|
where (paid_from=%(account)s or paid_to=%(account)s) and docstatus=1
|
||||||
and posting_date > %(report_date)s and clearance_date <= %(report_date)s""", filters)
|
and posting_date > %(report_date)s and clearance_date <= %(report_date)s""", filters)
|
||||||
|
|
||||||
pe_amount = flt(pe_amount[0][0]) if pe_amount else 0.0
|
pe_amount = flt(pe_amount[0][0]) if pe_amount else 0.0
|
||||||
|
|
||||||
return je_amount + pe_amount
|
return je_amount + pe_amount
|
||||||
|
|
||||||
def get_balance_row(label, amount, account_currency):
|
def get_balance_row(label, amount, account_currency):
|
||||||
|
@ -125,8 +125,9 @@ def get_account_type_based_data(company, account_type, period_list, accumulated_
|
|||||||
data["total"] = total
|
data["total"] = total
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def get_account_type_based_gl_data(company, start_date, end_date, account_type, filters):
|
def get_account_type_based_gl_data(company, start_date, end_date, account_type, filters={}):
|
||||||
cond = ""
|
cond = ""
|
||||||
|
filters = frappe._dict(filters)
|
||||||
|
|
||||||
if filters.finance_book:
|
if filters.finance_book:
|
||||||
cond = " and finance_book = %s" %(frappe.db.escape(filters.finance_book))
|
cond = " and finance_book = %s" %(frappe.db.escape(filters.finance_book))
|
||||||
@ -187,7 +188,7 @@ def get_chart_data(columns, data):
|
|||||||
},
|
},
|
||||||
"type": "bar"
|
"type": "bar"
|
||||||
}
|
}
|
||||||
|
|
||||||
chart["fieldtype"] = "Currency"
|
chart["fieldtype"] = "Currency"
|
||||||
|
|
||||||
return chart
|
return chart
|
||||||
|
@ -130,7 +130,7 @@ def get_cash_flow_data(fiscal_year, companies, filters):
|
|||||||
section_data.append(net_profit_loss)
|
section_data.append(net_profit_loss)
|
||||||
|
|
||||||
for account in cash_flow_account['account_types']:
|
for account in cash_flow_account['account_types']:
|
||||||
account_data = get_account_type_based_data(account['account_type'], companies, fiscal_year)
|
account_data = get_account_type_based_data(account['account_type'], companies, fiscal_year, filters)
|
||||||
account_data.update({
|
account_data.update({
|
||||||
"account_name": account['label'],
|
"account_name": account['label'],
|
||||||
"account": account['label'],
|
"account": account['label'],
|
||||||
@ -148,12 +148,12 @@ def get_cash_flow_data(fiscal_year, companies, filters):
|
|||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def get_account_type_based_data(account_type, companies, fiscal_year):
|
def get_account_type_based_data(account_type, companies, fiscal_year, filters):
|
||||||
data = {}
|
data = {}
|
||||||
total = 0
|
total = 0
|
||||||
for company in companies:
|
for company in companies:
|
||||||
amount = get_account_type_based_gl_data(company,
|
amount = get_account_type_based_gl_data(company,
|
||||||
fiscal_year.year_start_date, fiscal_year.year_end_date, account_type)
|
fiscal_year.year_start_date, fiscal_year.year_end_date, account_type, filters)
|
||||||
|
|
||||||
if amount and account_type == "Depreciation":
|
if amount and account_type == "Depreciation":
|
||||||
amount *= -1
|
amount *= -1
|
||||||
|
@ -121,7 +121,12 @@ def get_balance_on(account=None, date=None, party_type=None, party=None, company
|
|||||||
|
|
||||||
allow_cost_center_in_entry_of_bs_account = get_allow_cost_center_in_entry_of_bs_account()
|
allow_cost_center_in_entry_of_bs_account = get_allow_cost_center_in_entry_of_bs_account()
|
||||||
|
|
||||||
if cost_center and (allow_cost_center_in_entry_of_bs_account or acc.report_type =='Profit and Loss'):
|
if account:
|
||||||
|
report_type = acc.report_type
|
||||||
|
else:
|
||||||
|
report_type = ""
|
||||||
|
|
||||||
|
if cost_center and (allow_cost_center_in_entry_of_bs_account or report_type =='Profit and Loss'):
|
||||||
cc = frappe.get_doc("Cost Center", cost_center)
|
cc = frappe.get_doc("Cost Center", cost_center)
|
||||||
if cc.is_group:
|
if cc.is_group:
|
||||||
cond.append(""" exists (
|
cond.append(""" exists (
|
||||||
@ -138,7 +143,7 @@ def get_balance_on(account=None, date=None, party_type=None, party=None, company
|
|||||||
if not frappe.flags.ignore_account_permission:
|
if not frappe.flags.ignore_account_permission:
|
||||||
acc.check_permission("read")
|
acc.check_permission("read")
|
||||||
|
|
||||||
if acc.report_type == 'Profit and Loss':
|
if report_type == 'Profit and Loss':
|
||||||
# for pl accounts, get balance within a fiscal year
|
# for pl accounts, get balance within a fiscal year
|
||||||
cond.append("posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" \
|
cond.append("posting_date >= '%s' and voucher_type != 'Period Closing Voucher'" \
|
||||||
% year_start_date)
|
% year_start_date)
|
||||||
@ -685,7 +690,7 @@ def get_outstanding_invoices(party_type, party, account, condition=None, filters
|
|||||||
payment_amount = pe_map.get((d.voucher_type, d.voucher_no), 0)
|
payment_amount = pe_map.get((d.voucher_type, d.voucher_no), 0)
|
||||||
outstanding_amount = flt(d.invoice_amount - payment_amount, precision)
|
outstanding_amount = flt(d.invoice_amount - payment_amount, precision)
|
||||||
if outstanding_amount > 0.5 / (10**precision):
|
if outstanding_amount > 0.5 / (10**precision):
|
||||||
if (filters.get("outstanding_amt_greater_than") and
|
if (filters and filters.get("outstanding_amt_greater_than") and
|
||||||
not (outstanding_amount >= filters.get("outstanding_amt_greater_than") and
|
not (outstanding_amount >= filters.get("outstanding_amt_greater_than") and
|
||||||
outstanding_amount <= filters.get("outstanding_amt_less_than"))):
|
outstanding_amount <= filters.get("outstanding_amt_less_than"))):
|
||||||
continue
|
continue
|
||||||
@ -730,7 +735,6 @@ 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]]
|
||||||
@ -738,11 +742,11 @@ 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 += ['report_type', 'account_currency'] if doctype == 'Account' else []
|
fields += ['root_type', 'report_type', 'account_currency'] if doctype == 'Account' else []
|
||||||
filters.append(['company', '=', company])
|
filters.append(['company', '=', company])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
fields += ['account_currency'] if doctype == 'Account' else []
|
fields += ['root_type', 'account_currency'] if doctype == 'Account' else []
|
||||||
fields += [parent_fieldname + ' as parent']
|
fields += [parent_fieldname + ' as parent']
|
||||||
|
|
||||||
acc = frappe.get_list(doctype, fields=fields, filters=filters)
|
acc = frappe.get_list(doctype, fields=fields, filters=filters)
|
||||||
|
@ -388,7 +388,8 @@ class Asset(AccountsController):
|
|||||||
"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
|
"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
|
||||||
"posting_date": self.available_for_use_date,
|
"posting_date": self.available_for_use_date,
|
||||||
"credit": self.purchase_receipt_amount,
|
"credit": self.purchase_receipt_amount,
|
||||||
"credit_in_account_currency": self.purchase_receipt_amount
|
"credit_in_account_currency": self.purchase_receipt_amount,
|
||||||
|
"cost_center": self.cost_center
|
||||||
}))
|
}))
|
||||||
|
|
||||||
gl_entries.append(self.get_gl_dict({
|
gl_entries.append(self.get_gl_dict({
|
||||||
@ -397,7 +398,8 @@ class Asset(AccountsController):
|
|||||||
"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
|
"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
|
||||||
"posting_date": self.available_for_use_date,
|
"posting_date": self.available_for_use_date,
|
||||||
"debit": self.purchase_receipt_amount,
|
"debit": self.purchase_receipt_amount,
|
||||||
"debit_in_account_currency": self.purchase_receipt_amount
|
"debit_in_account_currency": self.purchase_receipt_amount,
|
||||||
|
"cost_center": self.cost_center
|
||||||
}))
|
}))
|
||||||
|
|
||||||
if gl_entries:
|
if gl_entries:
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"doctype": "Report",
|
"doctype": "Report",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": "Yes",
|
"is_standard": "Yes",
|
||||||
"modified": "2019-03-29 17:18:06.678728",
|
"modified": "2019-07-21 23:24:21.094269",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Procurement Tracker",
|
"name": "Procurement Tracker",
|
||||||
@ -16,5 +16,12 @@
|
|||||||
"ref_doctype": "Purchase Order",
|
"ref_doctype": "Purchase Order",
|
||||||
"report_name": "Procurement Tracker",
|
"report_name": "Procurement Tracker",
|
||||||
"report_type": "Script Report",
|
"report_type": "Script Report",
|
||||||
"roles": []
|
"roles": [
|
||||||
|
{
|
||||||
|
"role": "Purchase Manager"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "Purchase User"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
@ -150,10 +150,10 @@ def get_conditions(filters):
|
|||||||
"""% (filters.get('cost_center'), filters.get('project'))
|
"""% (filters.get('cost_center'), filters.get('project'))
|
||||||
|
|
||||||
if filters.get("from_date"):
|
if filters.get("from_date"):
|
||||||
conditions += "AND transaction_date>=%s"% filters.get('from_date')
|
conditions += " AND transaction_date>=%s"% filters.get('from_date')
|
||||||
|
|
||||||
if filters.get("to_date"):
|
if filters.get("to_date"):
|
||||||
conditions += "AND transaction_date<=%s"% filters.get('to_date')
|
conditions += " AND transaction_date<=%s"% filters.get('to_date')
|
||||||
return conditions
|
return conditions
|
||||||
|
|
||||||
def get_data(filters):
|
def get_data(filters):
|
||||||
|
@ -157,6 +157,13 @@ def get_data():
|
|||||||
"reference_doctype": "Purchase Order",
|
"reference_doctype": "Purchase Order",
|
||||||
"onboard": 1,
|
"onboard": 1,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "report",
|
||||||
|
"is_query_report": True,
|
||||||
|
"name": "Procurement Tracker",
|
||||||
|
"reference_doctype": "Purchase Order",
|
||||||
|
"onboard": 1,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "report",
|
"type": "report",
|
||||||
"is_query_report": True,
|
"is_query_report": True,
|
||||||
@ -228,5 +235,5 @@ def get_data():
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
]
|
]
|
||||||
|
@ -141,6 +141,11 @@ def get_data():
|
|||||||
"name": "Campaign",
|
"name": "Campaign",
|
||||||
"description": _("Sales campaigns."),
|
"description": _("Sales campaigns."),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Email Campaign",
|
||||||
|
"description": _("Sends Mails to lead or contact based on a Campaign schedule"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "SMS Center",
|
"name": "SMS Center",
|
||||||
|
@ -219,6 +219,11 @@ def get_data():
|
|||||||
"name": "Employee Onboarding",
|
"name": "Employee Onboarding",
|
||||||
"dependencies": ["Job Applicant"],
|
"dependencies": ["Job Applicant"],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "doctype",
|
||||||
|
"name": "Employee Skill Map",
|
||||||
|
"dependencies": ["Employee"],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "doctype",
|
"type": "doctype",
|
||||||
"name": "Employee Promotion",
|
"name": "Employee Promotion",
|
||||||
|
@ -861,7 +861,7 @@ class AccountsController(TransactionBase):
|
|||||||
|
|
||||||
if self.doctype in ("Sales Invoice", "Purchase Invoice"):
|
if self.doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||||
grand_total = grand_total - flt(self.write_off_amount)
|
grand_total = grand_total - flt(self.write_off_amount)
|
||||||
if total != grand_total:
|
if total != flt(grand_total, self.precision("grand_total")):
|
||||||
frappe.throw(_("Total Payment Amount in Payment Schedule must be equal to Grand / Rounded Total"))
|
frappe.throw(_("Total Payment Amount in Payment Schedule must be equal to Grand / Rounded Total"))
|
||||||
|
|
||||||
def is_rounded_total_disabled(self):
|
def is_rounded_total_disabled(self):
|
||||||
|
@ -636,7 +636,8 @@ class BuyingController(StockController):
|
|||||||
asset.set_missing_values()
|
asset.set_missing_values()
|
||||||
asset.insert()
|
asset.insert()
|
||||||
|
|
||||||
frappe.msgprint(_("Asset {0} created").format(asset.name))
|
asset_link = frappe.utils.get_link_to_form('Asset', asset.name)
|
||||||
|
frappe.msgprint(_("Asset {0} created").format(asset_link))
|
||||||
return asset.name
|
return asset.name
|
||||||
|
|
||||||
def make_asset_movement(self, row):
|
def make_asset_movement(self, row):
|
||||||
|
@ -207,10 +207,10 @@ def bom(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
idx desc, name
|
idx desc, name
|
||||||
limit %(start)s, %(page_len)s """.format(
|
limit %(start)s, %(page_len)s """.format(
|
||||||
fcond=get_filters_cond(doctype, filters, conditions).replace('%', '%%'),
|
fcond=get_filters_cond(doctype, filters, conditions).replace('%', '%%'),
|
||||||
mcond=get_match_cond(doctype),
|
mcond=get_match_cond(doctype).replace('%', '%%'),
|
||||||
key=frappe.db.escape(searchfield)),
|
key=searchfield),
|
||||||
{
|
{
|
||||||
'txt': "%"+frappe.db.escape(txt)+"%",
|
'txt': '%' + txt + '%',
|
||||||
'_txt': txt.replace("%", ""),
|
'_txt': txt.replace("%", ""),
|
||||||
'start': start or 0,
|
'start': start or 0,
|
||||||
'page_len': page_len or 20
|
'page_len': page_len or 20
|
||||||
|
@ -40,7 +40,6 @@ status_map = {
|
|||||||
["To Bill", "eval:self.per_delivered == 100 and self.per_billed < 100 and self.docstatus == 1"],
|
["To Bill", "eval:self.per_delivered == 100 and self.per_billed < 100 and self.docstatus == 1"],
|
||||||
["To Deliver", "eval:self.per_delivered < 100 and self.per_billed == 100 and self.docstatus == 1"],
|
["To Deliver", "eval:self.per_delivered < 100 and self.per_billed == 100 and self.docstatus == 1"],
|
||||||
["Completed", "eval:self.per_delivered == 100 and self.per_billed == 100 and self.docstatus == 1"],
|
["Completed", "eval:self.per_delivered == 100 and self.per_billed == 100 and self.docstatus == 1"],
|
||||||
["Completed", "eval:self.order_type == 'Maintenance' and self.per_billed == 100 and self.docstatus == 1"],
|
|
||||||
["Cancelled", "eval:self.docstatus==2"],
|
["Cancelled", "eval:self.docstatus==2"],
|
||||||
["Closed", "eval:self.status=='Closed'"],
|
["Closed", "eval:self.status=='Closed'"],
|
||||||
["On Hold", "eval:self.status=='On Hold'"],
|
["On Hold", "eval:self.status=='On Hold'"],
|
||||||
@ -90,7 +89,8 @@ status_map = {
|
|||||||
["Transferred", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Transfer'"],
|
["Transferred", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Transfer'"],
|
||||||
["Issued", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Issue'"],
|
["Issued", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Material Issue'"],
|
||||||
["Received", "eval:self.status != 'Stopped' and self.per_received == 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"],
|
["Received", "eval:self.status != 'Stopped' and self.per_received == 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"],
|
||||||
["Partially Received", "eval:self.status != 'Stopped' and self.per_received > 0 and self.per_received < 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"]
|
["Partially Received", "eval:self.status != 'Stopped' and self.per_received > 0 and self.per_received < 100 and self.docstatus == 1 and self.material_request_type == 'Purchase'"],
|
||||||
|
["Manufactured", "eval:self.status != 'Stopped' and self.per_ordered == 100 and self.docstatus == 1 and self.material_request_type == 'Manufacture'"]
|
||||||
],
|
],
|
||||||
"Bank Transaction": [
|
"Bank Transaction": [
|
||||||
["Unreconciled", "eval:self.docstatus == 1 and self.unallocated_amount>0"],
|
["Unreconciled", "eval:self.docstatus == 1 and self.unallocated_amount>0"],
|
||||||
|
@ -323,7 +323,7 @@ class calculate_taxes_and_totals(object):
|
|||||||
self._set_in_company_currency(self.doc, ["total_taxes_and_charges", "rounding_adjustment"])
|
self._set_in_company_currency(self.doc, ["total_taxes_and_charges", "rounding_adjustment"])
|
||||||
|
|
||||||
if self.doc.doctype in ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]:
|
if self.doc.doctype in ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]:
|
||||||
self.doc.base_grand_total = flt(self.doc.grand_total * self.doc.conversion_rate) \
|
self.doc.base_grand_total = flt(self.doc.grand_total * self.doc.conversion_rate, self.doc.precision("base_grand_total")) \
|
||||||
if self.doc.total_taxes_and_charges else self.doc.base_net_total
|
if self.doc.total_taxes_and_charges else self.doc.base_net_total
|
||||||
else:
|
else:
|
||||||
self.doc.taxes_and_charges_added = self.doc.taxes_and_charges_deducted = 0.0
|
self.doc.taxes_and_charges_added = self.doc.taxes_and_charges_deducted = 0.0
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"creation": "2019-06-30 15:56:20.306901",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"email_template",
|
||||||
|
"send_after_days"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "send_after_days",
|
||||||
|
"fieldtype": "Int",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Send After (days)",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "email_template",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Email Template",
|
||||||
|
"options": "Email Template",
|
||||||
|
"reqd": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"istable": 1,
|
||||||
|
"modified": "2019-07-12 11:46:43.184123",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "CRM",
|
||||||
|
"name": "Campaign Email Schedule",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
# import frappe
|
||||||
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
class CampaignEmailSchedule(Document):
|
||||||
|
pass
|
0
erpnext/crm/doctype/email_campaign/__init__.py
Normal file
0
erpnext/crm/doctype/email_campaign/__init__.py
Normal file
8
erpnext/crm/doctype/email_campaign/email_campaign.js
Normal file
8
erpnext/crm/doctype/email_campaign/email_campaign.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
// For license information, please see license.txt
|
||||||
|
|
||||||
|
frappe.ui.form.on('Email Campaign', {
|
||||||
|
email_campaign_for: function(frm) {
|
||||||
|
frm.set_value('recipient', '');
|
||||||
|
}
|
||||||
|
});
|
95
erpnext/crm/doctype/email_campaign/email_campaign.json
Normal file
95
erpnext/crm/doctype/email_campaign/email_campaign.json
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
{
|
||||||
|
"autoname": "format:MAIL-CAMP-{YYYY}-{#####}",
|
||||||
|
"creation": "2019-06-30 16:05:30.015615",
|
||||||
|
"doctype": "DocType",
|
||||||
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"campaign_name",
|
||||||
|
"email_campaign_for",
|
||||||
|
"recipient",
|
||||||
|
"sender",
|
||||||
|
"column_break_4",
|
||||||
|
"start_date",
|
||||||
|
"end_date",
|
||||||
|
"status"
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "campaign_name",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Campaign",
|
||||||
|
"options": "Campaign",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "status",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"label": "Status",
|
||||||
|
"options": "\nScheduled\nIn Progress\nCompleted\nUnsubscribed",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_4",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "start_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"label": "Start Date",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "end_date",
|
||||||
|
"fieldtype": "Date",
|
||||||
|
"label": "End Date",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "Lead",
|
||||||
|
"fieldname": "email_campaign_for",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"in_list_view": 1,
|
||||||
|
"label": "Email Campaign For ",
|
||||||
|
"options": "\nLead\nContact"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "recipient",
|
||||||
|
"fieldtype": "Dynamic Link",
|
||||||
|
"label": "Recipient",
|
||||||
|
"options": "email_campaign_for",
|
||||||
|
"reqd": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "__user",
|
||||||
|
"fieldname": "sender",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Sender",
|
||||||
|
"options": "User"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"modified": "2019-07-12 13:47:37.261213",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"module": "CRM",
|
||||||
|
"name": "Email Campaign",
|
||||||
|
"owner": "Administrator",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"create": 1,
|
||||||
|
"delete": 1,
|
||||||
|
"email": 1,
|
||||||
|
"export": 1,
|
||||||
|
"print": 1,
|
||||||
|
"read": 1,
|
||||||
|
"report": 1,
|
||||||
|
"role": "System Manager",
|
||||||
|
"share": 1,
|
||||||
|
"write": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quick_entry": 1,
|
||||||
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC",
|
||||||
|
"track_changes": 1
|
||||||
|
}
|
102
erpnext/crm/doctype/email_campaign/email_campaign.py
Normal file
102
erpnext/crm/doctype/email_campaign/email_campaign.py
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils import getdate, add_days, today, nowdate, cstr
|
||||||
|
from frappe.model.document import Document
|
||||||
|
from frappe.core.doctype.communication.email import make
|
||||||
|
|
||||||
|
class EmailCampaign(Document):
|
||||||
|
def validate(self):
|
||||||
|
self.set_date()
|
||||||
|
#checking if email is set for lead. Not checking for contact as email is a mandatory field for contact.
|
||||||
|
if self.email_campaign_for == "Lead":
|
||||||
|
self.validate_lead()
|
||||||
|
self.validate_email_campaign_already_exists()
|
||||||
|
self.update_status()
|
||||||
|
|
||||||
|
def set_date(self):
|
||||||
|
if getdate(self.start_date) < getdate(today()):
|
||||||
|
frappe.throw(_("Start Date cannot be before the current date"))
|
||||||
|
#set the end date as start date + max(send after days) in campaign schedule
|
||||||
|
send_after_days = []
|
||||||
|
campaign = frappe.get_doc("Campaign", self.campaign_name)
|
||||||
|
for entry in campaign.get("campaign_schedules"):
|
||||||
|
send_after_days.append(entry.send_after_days)
|
||||||
|
try:
|
||||||
|
end_date = add_days(getdate(self.start_date), max(send_after_days))
|
||||||
|
except ValueError:
|
||||||
|
frappe.throw(_("Please set up the Campaign Schedule in the Campaign {0}").format(self.campaign_name))
|
||||||
|
|
||||||
|
def validate_lead(self):
|
||||||
|
lead_email_id = frappe.db.get_value("Lead", self.recipient, 'email_id')
|
||||||
|
if not lead_email_id:
|
||||||
|
lead_name = frappe.db.get_value("Lead", self.recipient, 'lead_name')
|
||||||
|
frappe.throw(_("Please set an email id for the Lead {0}").format(lead_name))
|
||||||
|
|
||||||
|
def validate_email_campaign_already_exists(self):
|
||||||
|
email_campaign_exists = frappe.db.exists("Email Campaign", {
|
||||||
|
"campaign_name": self.campaign_name,
|
||||||
|
"recipient": self.recipient,
|
||||||
|
"status": ("in", ["In Progress", "Scheduled"])
|
||||||
|
})
|
||||||
|
if email_campaign_exists:
|
||||||
|
frappe.throw(_("The Campaign '{0}' already exists for the {1} '{2}'").format(self.campaign_name, self.email_campaign_for, self.recipient))
|
||||||
|
|
||||||
|
def update_status(self):
|
||||||
|
start_date = getdate(self.start_date)
|
||||||
|
end_date = getdate(self.end_date)
|
||||||
|
today_date = getdate(today())
|
||||||
|
if start_date > today_date:
|
||||||
|
self.status = "Scheduled"
|
||||||
|
elif end_date >= today_date:
|
||||||
|
self.status = "In Progress"
|
||||||
|
elif end_date < today_date:
|
||||||
|
self.status = "Completed"
|
||||||
|
|
||||||
|
#called through hooks to send campaign mails to leads
|
||||||
|
def send_email_to_leads_or_contacts():
|
||||||
|
email_campaigns = frappe.get_all("Email Campaign", filters = { 'status': ('not in', ['Unsubscribed', 'Completed', 'Scheduled']) })
|
||||||
|
for camp in email_campaigns:
|
||||||
|
email_campaign = frappe.get_doc("Email Campaign", camp.name)
|
||||||
|
campaign = frappe.get_cached_doc("Campaign", email_campaign.campaign_name)
|
||||||
|
for entry in campaign.get("campaign_schedules"):
|
||||||
|
scheduled_date = add_days(email_campaign.get('start_date'), entry.get('send_after_days'))
|
||||||
|
if scheduled_date == getdate(today()):
|
||||||
|
send_mail(entry, email_campaign)
|
||||||
|
|
||||||
|
def send_mail(entry, email_campaign):
|
||||||
|
recipient = frappe.db.get_value(email_campaign.email_campaign_for, email_campaign.get("recipient"), 'email_id')
|
||||||
|
|
||||||
|
email_template = frappe.get_doc("Email Template", entry.get("email_template"))
|
||||||
|
sender = frappe.db.get_value("User", email_campaign.get("sender"), 'email')
|
||||||
|
|
||||||
|
# send mail and link communication to document
|
||||||
|
comm = make(
|
||||||
|
doctype = "Email Campaign",
|
||||||
|
name = email_campaign.name,
|
||||||
|
subject = email_template.get("subject"),
|
||||||
|
content = email_template.get("response"),
|
||||||
|
sender = sender,
|
||||||
|
recipients = recipient,
|
||||||
|
communication_medium = "Email",
|
||||||
|
sent_or_received = "Sent",
|
||||||
|
send_email = True,
|
||||||
|
email_template = email_template.name
|
||||||
|
)
|
||||||
|
return comm
|
||||||
|
|
||||||
|
#called from hooks on doc_event Email Unsubscribe
|
||||||
|
def unsubscribe_recipient(unsubscribe, method):
|
||||||
|
if unsubscribe.reference_doctype == 'Email Campaign':
|
||||||
|
frappe.db.set_value("Email Campaign", unsubscribe.reference_name, "status", "Unsubscribed")
|
||||||
|
|
||||||
|
#called through hooks to update email campaign status daily
|
||||||
|
def set_email_campaign_status():
|
||||||
|
email_campaigns = frappe.get_all("Email Campaign", filters = { 'status': ('!=', 'Unsubscribed')})
|
||||||
|
for entry in email_campaigns:
|
||||||
|
email_campaign = frappe.get_doc("Email Campaign", entry.name)
|
||||||
|
email_campaign.update_status()
|
11
erpnext/crm/doctype/email_campaign/email_campaign_list.js
Normal file
11
erpnext/crm/doctype/email_campaign/email_campaign_list.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
frappe.listview_settings['Email Campaign'] = {
|
||||||
|
get_indicator: function(doc) {
|
||||||
|
var colors = {
|
||||||
|
"Unsubscribed": "red",
|
||||||
|
"Scheduled": "blue",
|
||||||
|
"In Progress": "orange",
|
||||||
|
"Completed": "green"
|
||||||
|
};
|
||||||
|
return [__(doc.status), colors[doc.status], "status,=," + doc.status];
|
||||||
|
}
|
||||||
|
};
|
10
erpnext/crm/doctype/email_campaign/test_email_campaign.py
Normal file
10
erpnext/crm/doctype/email_campaign/test_email_campaign.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
|
# See license.txt
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestEmailCampaign(unittest.TestCase):
|
||||||
|
pass
|
@ -7,14 +7,8 @@ cur_frm.email_field = "email_id";
|
|||||||
erpnext.LeadController = frappe.ui.form.Controller.extend({
|
erpnext.LeadController = frappe.ui.form.Controller.extend({
|
||||||
setup: function () {
|
setup: function () {
|
||||||
this.frm.make_methods = {
|
this.frm.make_methods = {
|
||||||
'Quotation': () => erpnext.utils.create_new_doc('Quotation', {
|
'Quotation': this.make_quotation,
|
||||||
'quotation_to': this.frm.doc.doctype,
|
'Opportunity': this.create_opportunity
|
||||||
'party_name': this.frm.doc.name
|
|
||||||
}),
|
|
||||||
'Opportunity': () => erpnext.utils.create_new_doc('Opportunity', {
|
|
||||||
'opportunity_from': this.frm.doc.doctype,
|
|
||||||
'party_name': this.frm.doc.name
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.frm.fields_dict.customer.get_query = function (doc, cdt, cdn) {
|
this.frm.fields_dict.customer.get_query = function (doc, cdt, cdn) {
|
||||||
|
@ -296,7 +296,9 @@ class TallyMigration(Document):
|
|||||||
else:
|
else:
|
||||||
function = voucher_to_journal_entry
|
function = voucher_to_journal_entry
|
||||||
try:
|
try:
|
||||||
vouchers.append(function(voucher))
|
processed_voucher = function(voucher)
|
||||||
|
if processed_voucher:
|
||||||
|
vouchers.append(processed_voucher)
|
||||||
except:
|
except:
|
||||||
self.log(voucher)
|
self.log(voucher)
|
||||||
return vouchers
|
return vouchers
|
||||||
@ -342,6 +344,10 @@ class TallyMigration(Document):
|
|||||||
account_field = "credit_to"
|
account_field = "credit_to"
|
||||||
account_name = encode_company_abbr(self.tally_creditors_account, self.erpnext_company)
|
account_name = encode_company_abbr(self.tally_creditors_account, self.erpnext_company)
|
||||||
price_list_field = "buying_price_list"
|
price_list_field = "buying_price_list"
|
||||||
|
else:
|
||||||
|
# Do not handle vouchers other than "Purchase", "Debit Note", "Sales" and "Credit Note"
|
||||||
|
# Do not handle Custom Vouchers either
|
||||||
|
return
|
||||||
|
|
||||||
invoice = {
|
invoice = {
|
||||||
"doctype": doctype,
|
"doctype": doctype,
|
||||||
|
@ -233,6 +233,9 @@ doc_events = {
|
|||||||
},
|
},
|
||||||
"Contact":{
|
"Contact":{
|
||||||
"on_trash": "erpnext.support.doctype.issue.issue.update_issue"
|
"on_trash": "erpnext.support.doctype.issue.issue.update_issue"
|
||||||
|
},
|
||||||
|
"Email Unsubscribe": {
|
||||||
|
"after_insert": "erpnext.crm.doctype.email_campaign.email_campaign.unsubscribe_recipient"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,6 +275,8 @@ scheduler_events = {
|
|||||||
"erpnext.projects.doctype.project.project.send_project_status_email_to_users",
|
"erpnext.projects.doctype.project.project.send_project_status_email_to_users",
|
||||||
"erpnext.quality_management.doctype.quality_review.quality_review.review",
|
"erpnext.quality_management.doctype.quality_review.quality_review.review",
|
||||||
"erpnext.support.doctype.service_level_agreement.service_level_agreement.check_agreement_status",
|
"erpnext.support.doctype.service_level_agreement.service_level_agreement.check_agreement_status",
|
||||||
|
"erpnext.crm.doctype.email_campaign.email_campaign.send_email_to_leads_or_contacts",
|
||||||
|
"erpnext.crm.doctype.email_campaign.email_campaign.set_email_campaign_status"
|
||||||
],
|
],
|
||||||
"daily_long": [
|
"daily_long": [
|
||||||
"erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_latest_price_in_all_boms"
|
"erpnext.manufacturing.doctype.bom_update_tool.bom_update_tool.update_latest_price_in_all_boms"
|
||||||
|
@ -4,4 +4,17 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
test_records = frappe.get_test_records('Designation')
|
# test_records = frappe.get_test_records('Designation')
|
||||||
|
|
||||||
|
def create_designation(**args):
|
||||||
|
args = frappe._dict(args)
|
||||||
|
if frappe.db.exists("Designation", args.designation_name or "_Test designation"):
|
||||||
|
return frappe.get_doc("Designation", args.designation_name or "_Test designation")
|
||||||
|
|
||||||
|
designation = frappe.get_doc({
|
||||||
|
"doctype": "Designation",
|
||||||
|
"designation_name": args.designation_name or "_Test designation",
|
||||||
|
"description": args.description or "_Test description"
|
||||||
|
})
|
||||||
|
designation.save()
|
||||||
|
return designation
|
@ -1,516 +1,124 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 1,
|
"allow_import": 1,
|
||||||
"allow_rename": 1,
|
"allow_rename": 1,
|
||||||
"autoname": "naming_series:",
|
"autoname": "naming_series:",
|
||||||
"beta": 0,
|
|
||||||
"creation": "2017-10-17 08:21:50.489773",
|
"creation": "2017-10-17 08:21:50.489773",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Setup",
|
"document_type": "Setup",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"naming_series",
|
||||||
|
"full_name",
|
||||||
|
"status",
|
||||||
|
"transporter",
|
||||||
|
"column_break_2",
|
||||||
|
"employee",
|
||||||
|
"cell_number",
|
||||||
|
"address",
|
||||||
|
"license_details",
|
||||||
|
"license_number",
|
||||||
|
"column_break_8",
|
||||||
|
"issuing_date",
|
||||||
|
"column_break_10",
|
||||||
|
"expiry_date",
|
||||||
|
"driving_license_categories",
|
||||||
|
"driving_license_category"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"default": "",
|
|
||||||
"fieldname": "naming_series",
|
"fieldname": "naming_series",
|
||||||
"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": "Series",
|
"label": "Series",
|
||||||
"length": 0,
|
"options": "HR-DRI-.YYYY.-"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "HR-DRI-.YYYY.-",
|
|
||||||
"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": "full_name",
|
"fieldname": "full_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"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": "Full Name",
|
"label": "Full Name",
|
||||||
"length": 0,
|
"reqd": 1
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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": "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": 1,
|
"in_list_view": 1,
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Status",
|
"label": "Status",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Active\nSuspended\nLeft",
|
"options": "Active\nSuspended\nLeft",
|
||||||
"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": 1,
|
"allow_in_quick_entry": 1,
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"description": "Applicable for external driver",
|
"description": "Applicable for external driver",
|
||||||
"fieldname": "transporter",
|
"fieldname": "transporter",
|
||||||
"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": "Transporter",
|
"label": "Transporter",
|
||||||
"length": 0,
|
"options": "Supplier"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Supplier",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_2",
|
"fieldname": "column_break_2",
|
||||||
"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": "employee",
|
"fieldname": "employee",
|
||||||
"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": "Employee",
|
"label": "Employee",
|
||||||
"length": 0,
|
"options": "Employee"
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Employee",
|
|
||||||
"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": "cell_number",
|
"fieldname": "cell_number",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"label": "Cellphone Number"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Cellphone Number",
|
|
||||||
"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": "license_details",
|
"fieldname": "license_details",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"label": "License Details"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "License Details",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "license_number",
|
"fieldname": "license_number",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"hidden": 0,
|
"label": "License Number"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "License Number",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_8",
|
"fieldname": "column_break_8",
|
||||||
"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": "issuing_date",
|
"fieldname": "issuing_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"hidden": 0,
|
"label": "Issuing 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": "Issuing 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": "column_break_10",
|
"fieldname": "column_break_10",
|
||||||
"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": "expiry_date",
|
"fieldname": "expiry_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"hidden": 0,
|
"label": "Expiry 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": "Expiry 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": "driving_license_categories",
|
"fieldname": "driving_license_categories",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"hidden": 0,
|
"label": "Driving License Categories"
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Driving License Categories",
|
|
||||||
"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": "driving_license_category",
|
"fieldname": "driving_license_category",
|
||||||
"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": "Driving License Category",
|
"label": "Driving License Category",
|
||||||
"length": 0,
|
"options": "Driving License Category"
|
||||||
"no_copy": 0,
|
},
|
||||||
"options": "Driving License Category",
|
{
|
||||||
"permlevel": 0,
|
"fieldname": "address",
|
||||||
"precision": "",
|
"fieldtype": "Link",
|
||||||
"print_hide": 0,
|
"label": "Address",
|
||||||
"print_hide_if_no_value": 0,
|
"options": "Address"
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
|
||||||
"hide_heading": 0,
|
|
||||||
"hide_toolbar": 0,
|
|
||||||
"icon": "fa fa-user",
|
"icon": "fa fa-user",
|
||||||
"idx": 0,
|
"modified": "2019-07-18 16:29:14.151380",
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-10-03 19:53:50.924391",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Driver",
|
"name": "Driver",
|
||||||
@ -518,72 +126,44 @@
|
|||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 0,
|
|
||||||
"delete": 0,
|
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Fleet Manager",
|
"role": "Fleet Manager",
|
||||||
"set_user_permissions": 0,
|
"share": 1
|
||||||
"share": 1,
|
|
||||||
"submit": 0,
|
|
||||||
"write": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "HR User",
|
"role": "HR User",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 0,
|
|
||||||
"cancel": 0,
|
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
|
||||||
"import": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "HR Manager",
|
"role": "HR Manager",
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 0,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"search_fields": "full_name",
|
"search_fields": "full_name",
|
||||||
"show_name_in_global_search": 1,
|
"show_name_in_global_search": 1,
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"title_field": "full_name",
|
"title_field": "full_name",
|
||||||
"track_changes": 1,
|
"track_changes": 1
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
@ -12,6 +12,7 @@ from frappe.permissions import add_user_permission, remove_user_permission, \
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.utilities.transaction_base import delete_events
|
from erpnext.utilities.transaction_base import delete_events
|
||||||
from frappe.utils.nestedset import NestedSet
|
from frappe.utils.nestedset import NestedSet
|
||||||
|
from erpnext.hr.doctype.job_offer.job_offer import get_staffing_plan_detail
|
||||||
|
|
||||||
class EmployeeUserDisabledError(frappe.ValidationError): pass
|
class EmployeeUserDisabledError(frappe.ValidationError): pass
|
||||||
class EmployeeLeftValidationError(frappe.ValidationError): pass
|
class EmployeeLeftValidationError(frappe.ValidationError): pass
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Other",
|
"document_type": "Other",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"employee_settings",
|
"employee_settings",
|
||||||
"retirement_age",
|
"retirement_age",
|
||||||
@ -22,7 +23,9 @@
|
|||||||
"leave_status_notification_template",
|
"leave_status_notification_template",
|
||||||
"column_break_18",
|
"column_break_18",
|
||||||
"leave_approver_mandatory_in_leave_application",
|
"leave_approver_mandatory_in_leave_application",
|
||||||
"show_leaves_of_all_department_members_in_calendar"
|
"show_leaves_of_all_department_members_in_calendar",
|
||||||
|
"hiring_settings",
|
||||||
|
"check_vacancies"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -44,18 +47,6 @@
|
|||||||
"label": "Employee Records to be created by",
|
"label": "Employee Records to be created by",
|
||||||
"options": "Naming Series\nEmployee Number\nFull Name"
|
"options": "Naming Series\nEmployee Number\nFull Name"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "leave_approval_notification_template",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Leave Approval Notification Template",
|
|
||||||
"options": "Email Template"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "leave_status_notification_template",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "Leave Status Notification Template",
|
|
||||||
"options": "Email Template"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_4",
|
"fieldname": "column_break_4",
|
||||||
"fieldtype": "Column Break"
|
"fieldtype": "Column Break"
|
||||||
@ -67,12 +58,6 @@
|
|||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Stop Birthday Reminders"
|
"label": "Stop Birthday Reminders"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"default": "1",
|
|
||||||
"fieldname": "leave_approver_mandatory_in_leave_application",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Leave Approver Mandatory In Leave Application"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"fieldname": "expense_approver_mandatory_in_expense_claim",
|
"fieldname": "expense_approver_mandatory_in_expense_claim",
|
||||||
@ -91,6 +76,15 @@
|
|||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Include holidays in Total no. of Working Days"
|
"label": "Include holidays in Total no. of Working Days"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "max_working_hours_against_timesheet",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"label": "Max working hours against Timesheet"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_11",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"description": "Emails salary slip to employee based on preferred email selected in Employee",
|
"description": "Emails salary slip to employee based on preferred email selected in Employee",
|
||||||
@ -115,15 +109,33 @@
|
|||||||
"label": "Password Policy"
|
"label": "Password Policy"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "max_working_hours_against_timesheet",
|
"collapsible": 1,
|
||||||
"fieldtype": "Float",
|
|
||||||
"label": "Max working hours against Timesheet"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "leave_settings",
|
"fieldname": "leave_settings",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "Leave Settings"
|
"label": "Leave Settings"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "leave_approval_notification_template",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Leave Approval Notification Template",
|
||||||
|
"options": "Email Template"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "leave_status_notification_template",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "Leave Status Notification Template",
|
||||||
|
"options": "Email Template"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_18",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "1",
|
||||||
|
"fieldname": "leave_approver_mandatory_in_leave_application",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Leave Approver Mandatory In Leave Application"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "0",
|
||||||
"fieldname": "show_leaves_of_all_department_members_in_calendar",
|
"fieldname": "show_leaves_of_all_department_members_in_calendar",
|
||||||
@ -131,18 +143,22 @@
|
|||||||
"label": "Show Leaves Of All Department Members In Calendar"
|
"label": "Show Leaves Of All Department Members In Calendar"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_11",
|
"collapsible": 1,
|
||||||
"fieldtype": "Column Break"
|
"fieldname": "hiring_settings",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Hiring Settings"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break_18",
|
"default": "0",
|
||||||
"fieldtype": "Column Break"
|
"fieldname": "check_vacancies",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Check Vacancies On Job Offer Creation"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-cog",
|
"icon": "fa fa-cog",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"modified": "2019-05-31 16:18:50.245872",
|
"modified": "2019-07-01 18:59:55.256878",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "HR Settings",
|
"name": "HR Settings",
|
||||||
@ -158,5 +174,6 @@
|
|||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"sort_field": "modified",
|
||||||
"sort_order": "ASC"
|
"sort_order": "ASC"
|
||||||
}
|
}
|
@ -39,7 +39,7 @@
|
|||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
@ -71,7 +71,7 @@
|
|||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"remember_last_selected_value": 0,
|
"remember_last_selected_value": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 1,
|
||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"set_only_once": 0,
|
"set_only_once": 0,
|
||||||
"translatable": 0,
|
"translatable": 0,
|
||||||
@ -96,7 +96,7 @@
|
|||||||
"label": "Status",
|
"label": "Status",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"options": "Open\nReplied\nRejected\nHold",
|
"options": "Open\nReplied\nRejected\nHold\nAccepted",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"print_hide_if_no_value": 0,
|
"print_hide_if_no_value": 0,
|
||||||
@ -346,7 +346,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2018-08-21 16:15:43.552049",
|
"modified": "2019-06-21 16:15:43.552049",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Job Applicant",
|
"name": "Job Applicant",
|
||||||
|
@ -10,3 +10,14 @@ import unittest
|
|||||||
|
|
||||||
class TestJobApplicant(unittest.TestCase):
|
class TestJobApplicant(unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def create_job_applicant(**args):
|
||||||
|
args = frappe._dict(args)
|
||||||
|
job_applicant = frappe.get_doc({
|
||||||
|
"doctype": "Job Applicant",
|
||||||
|
"applicant_name": args.applicant_name or "_Test Applicant",
|
||||||
|
"email_id": args.email_id or "test_applicant@example.com",
|
||||||
|
"status": args.status or "Open"
|
||||||
|
})
|
||||||
|
job_applicant.save()
|
||||||
|
return job_applicant
|
@ -5,12 +5,56 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.model.mapper import get_mapped_doc
|
from frappe.model.mapper import get_mapped_doc
|
||||||
|
from frappe import _
|
||||||
|
from frappe.utils.data import get_link_to_form
|
||||||
|
|
||||||
class JobOffer(Document):
|
class JobOffer(Document):
|
||||||
def onload(self):
|
def onload(self):
|
||||||
employee = frappe.db.get_value("Employee", {"job_applicant": self.job_applicant}, "name") or ""
|
employee = frappe.db.get_value("Employee", {"job_applicant": self.job_applicant}, "name") or ""
|
||||||
self.set_onload("employee", employee)
|
self.set_onload("employee", employee)
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
self.validate_vacancies()
|
||||||
|
|
||||||
|
def validate_vacancies(self):
|
||||||
|
staffing_plan = get_staffing_plan_detail(self.designation, self.company, self.offer_date)
|
||||||
|
check_vacancies = frappe.get_single("HR Settings").check_vacancies
|
||||||
|
if staffing_plan and check_vacancies:
|
||||||
|
vacancies = frappe.db.get_value("Staffing Plan Detail", filters={"name": staffing_plan.name}, fieldname=['vacancies'])
|
||||||
|
job_offers = len(self.get_job_offer(staffing_plan.from_date, staffing_plan.to_date))
|
||||||
|
if vacancies - job_offers <= 0:
|
||||||
|
frappe.throw(_("There are no vacancies under staffing plan {0}").format(get_link_to_form("Staffing Plan", staffing_plan.parent)))
|
||||||
|
|
||||||
|
def on_change(self):
|
||||||
|
update_job_applicant(self.status, self.job_applicant)
|
||||||
|
|
||||||
|
def get_job_offer(self, from_date, to_date):
|
||||||
|
''' Returns job offer created during a time period '''
|
||||||
|
return frappe.get_all("Job Offer", filters={
|
||||||
|
"offer_date": ['between', (from_date, to_date)],
|
||||||
|
"designation": self.designation,
|
||||||
|
"company": self.company
|
||||||
|
}, fields=['name'])
|
||||||
|
|
||||||
|
def update_job_applicant(status, job_applicant):
|
||||||
|
if status in ("Accepted", "Rejected"):
|
||||||
|
frappe.set_value("Job Applicant", job_applicant, "status", status)
|
||||||
|
|
||||||
|
def get_staffing_plan_detail(designation, company, offer_date):
|
||||||
|
detail = frappe.db.sql("""
|
||||||
|
SELECT spd.name as name,
|
||||||
|
sp.from_date as from_date,
|
||||||
|
sp.to_date as to_date,
|
||||||
|
sp.name as parent
|
||||||
|
FROM `tabStaffing Plan Detail` spd, `tabStaffing Plan` sp
|
||||||
|
WHERE
|
||||||
|
sp.docstatus=1
|
||||||
|
AND spd.designation=%s
|
||||||
|
AND sp.company=%s
|
||||||
|
AND %s between sp.from_date and sp.to_date
|
||||||
|
""", (designation, company, offer_date), as_dict=1)
|
||||||
|
return detail[0] if detail else None
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def make_employee(source_name, target_doc=None):
|
def make_employee(source_name, target_doc=None):
|
||||||
def set_missing_values(source, target):
|
def set_missing_values(source, target):
|
||||||
@ -23,4 +67,3 @@ def make_employee(source_name, target_doc=None):
|
|||||||
}}
|
}}
|
||||||
}, target_doc, set_missing_values)
|
}, target_doc, set_missing_values)
|
||||||
return doc
|
return doc
|
||||||
|
|
||||||
|
@ -4,8 +4,78 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
import unittest
|
import unittest
|
||||||
|
from frappe.utils import nowdate, add_days
|
||||||
|
from erpnext.hr.doctype.job_applicant.test_job_applicant import create_job_applicant
|
||||||
|
from erpnext.hr.doctype.designation.test_designation import create_designation
|
||||||
|
from erpnext.hr.doctype.staffing_plan.test_staffing_plan import make_company
|
||||||
|
|
||||||
# test_records = frappe.get_test_records('Job Offer')
|
# test_records = frappe.get_test_records('Job Offer')
|
||||||
|
|
||||||
class TestJobOffer(unittest.TestCase):
|
class TestJobOffer(unittest.TestCase):
|
||||||
pass
|
def test_job_offer_creation_against_vacancies(self):
|
||||||
|
create_staffing_plan(staffing_details=[{
|
||||||
|
"designation": "Designer",
|
||||||
|
"vacancies": 0,
|
||||||
|
"estimated_cost_per_position": 5000
|
||||||
|
}])
|
||||||
|
frappe.db.set_value("HR Settings", None, "check_vacancies", 1)
|
||||||
|
job_applicant = create_job_applicant(email_id="test_job_offer@example.com")
|
||||||
|
job_offer = create_job_offer(job_applicant=job_applicant.name, designation="Researcher")
|
||||||
|
self.assertRaises(frappe.ValidationError, job_offer.submit)
|
||||||
|
|
||||||
|
# test creation of job offer when vacancies are not present
|
||||||
|
frappe.db.set_value("HR Settings", None, "check_vacancies", 0)
|
||||||
|
job_offer.submit()
|
||||||
|
self.assertTrue(frappe.db.exists("Job Offer", job_offer.name))
|
||||||
|
|
||||||
|
def test_job_applicant_update(self):
|
||||||
|
create_staffing_plan()
|
||||||
|
job_applicant = create_job_applicant(email_id="test_job_applicants@example.com")
|
||||||
|
job_offer = create_job_offer(job_applicant=job_applicant.name)
|
||||||
|
job_offer.submit()
|
||||||
|
job_applicant.reload()
|
||||||
|
self.assertEquals(job_applicant.status, "Accepted")
|
||||||
|
|
||||||
|
# status update after rejection
|
||||||
|
job_offer.status = "Rejected"
|
||||||
|
job_offer.submit()
|
||||||
|
job_applicant.reload()
|
||||||
|
self.assertEquals(job_applicant.status, "Rejected")
|
||||||
|
|
||||||
|
def create_job_offer(**args):
|
||||||
|
args = frappe._dict(args)
|
||||||
|
if not args.job_applicant:
|
||||||
|
job_applicant = create_job_applicant()
|
||||||
|
|
||||||
|
if not frappe.db.exists("Designation", args.designation):
|
||||||
|
designation = create_designation(designation_name=args.designation)
|
||||||
|
|
||||||
|
job_offer = frappe.get_doc({
|
||||||
|
"doctype": "Job Offer",
|
||||||
|
"job_applicant": args.job_applicant or job_applicant.name,
|
||||||
|
"offer_date": args.offer_date or nowdate(),
|
||||||
|
"designation": args.designation or "Researcher",
|
||||||
|
"status": args.status or "Accepted"
|
||||||
|
})
|
||||||
|
return job_offer
|
||||||
|
|
||||||
|
def create_staffing_plan(**args):
|
||||||
|
args = frappe._dict(args)
|
||||||
|
make_company()
|
||||||
|
frappe.db.set_value("Company", "_Test Company", "is_group", 1)
|
||||||
|
if frappe.db.exists("Staffing Plan", args.name or "Test"):
|
||||||
|
return
|
||||||
|
staffing_plan = frappe.get_doc({
|
||||||
|
"doctype": "Staffing Plan",
|
||||||
|
"name": args.name or "Test",
|
||||||
|
"from_date": args.from_date or nowdate(),
|
||||||
|
"to_date": args.to_date or add_days(nowdate(), 10),
|
||||||
|
"staffing_details": args.staffing_details or [{
|
||||||
|
"designation": "Researcher",
|
||||||
|
"vacancies": 1,
|
||||||
|
"estimated_cost_per_position": 50000
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
staffing_plan.insert()
|
||||||
|
staffing_plan.submit()
|
||||||
|
return staffing_plan
|
@ -30,11 +30,11 @@ class LoanApplication(Document):
|
|||||||
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:
|
||||||
min_repayment_amount = self.loan_amount*monthly_interest_rate
|
min_repayment_amount = self.loan_amount*monthly_interest_rate
|
||||||
if self.repayment_amount - min_repayment_amount < 0:
|
if self.repayment_amount - min_repayment_amount <= 0:
|
||||||
frappe.throw(_("Repayment Amount must be greater than " \
|
frappe.throw(_("Repayment Amount must be greater than " \
|
||||||
+ str(flt(min_repayment_amount, 2))))
|
+ str(flt(min_repayment_amount, 2))))
|
||||||
self.repayment_periods = math.ceil(math.log(self.repayment_amount) -
|
self.repayment_periods = math.ceil((math.log(self.repayment_amount) -
|
||||||
math.log(self.repayment_amount - min_repayment_amount) /(math.log(1 + monthly_interest_rate)))
|
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
|
||||||
|
|
||||||
|
@ -119,6 +119,8 @@ class PayrollEntry(Document):
|
|||||||
frappe.enqueue(create_salary_slips_for_employees, timeout=600, employees=emp_list, args=args)
|
frappe.enqueue(create_salary_slips_for_employees, timeout=600, employees=emp_list, args=args)
|
||||||
else:
|
else:
|
||||||
create_salary_slips_for_employees(emp_list, args, publish_progress=False)
|
create_salary_slips_for_employees(emp_list, args, publish_progress=False)
|
||||||
|
# since this method is called via frm.call this doc needs to be updated manually
|
||||||
|
self.reload()
|
||||||
|
|
||||||
def get_sal_slip_list(self, ss_status, as_dict=False):
|
def get_sal_slip_list(self, ss_status, as_dict=False):
|
||||||
"""
|
"""
|
||||||
|
@ -5,7 +5,7 @@ frappe.ui.form.on('Staffing Plan', {
|
|||||||
setup: function(frm) {
|
setup: function(frm) {
|
||||||
frm.set_query("designation", "staffing_details", function() {
|
frm.set_query("designation", "staffing_details", function() {
|
||||||
let designations = [];
|
let designations = [];
|
||||||
$.each(frm.doc.staffing_details, function(index, staff_detail) {
|
(frm.doc.staffing_details || []).forEach(function(staff_detail) {
|
||||||
if(staff_detail.designation){
|
if(staff_detail.designation){
|
||||||
designations.push(staff_detail.designation)
|
designations.push(staff_detail.designation)
|
||||||
}
|
}
|
||||||
@ -25,69 +25,63 @@ frappe.ui.form.on('Staffing Plan', {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.ui.form.on('Staffing Plan Detail', {
|
frappe.ui.form.on('Staffing Plan Detail', {
|
||||||
designation: function(frm, cdt, cdn) {
|
designation: function(frm, cdt, cdn) {
|
||||||
let child = locals[cdt][cdn]
|
let child = locals[cdt][cdn];
|
||||||
if(frm.doc.company && child.designation){
|
if(frm.doc.company && child.designation) {
|
||||||
frappe.call({
|
set_number_of_positions(frm, cdt, cdn);
|
||||||
"method": "erpnext.hr.doctype.staffing_plan.staffing_plan.get_designation_counts",
|
|
||||||
args: {
|
|
||||||
designation: child.designation,
|
|
||||||
company: frm.doc.company
|
|
||||||
},
|
|
||||||
callback: function (data) {
|
|
||||||
if(data.message){
|
|
||||||
frappe.model.set_value(cdt, cdn, 'current_count', data.message.employee_count);
|
|
||||||
frappe.model.set_value(cdt, cdn, 'current_openings', data.message.job_openings);
|
|
||||||
if (child.number_of_positions < (data.message.employee_count + data.message.job_openings)){
|
|
||||||
frappe.model.set_value(cdt, cdn, 'number_of_positions', data.message.employee_count + data.message.job_openings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{ // No employees for this designation
|
|
||||||
frappe.model.set_value(cdt, cdn, 'current_count', 0);
|
|
||||||
frappe.model.set_value(cdt, cdn, 'current_openings', 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
number_of_positions: function(frm, cdt, cdn) {
|
vacancies: function(frm, cdt, cdn) {
|
||||||
set_vacancies(frm, cdt, cdn);
|
let child = locals[cdt][cdn];
|
||||||
|
if(child.vacancies < child.current_openings) {
|
||||||
|
frappe.throw(__("Vacancies cannot be lower than the current openings"));
|
||||||
|
}
|
||||||
|
set_number_of_positions(frm, cdt, cdn);
|
||||||
},
|
},
|
||||||
|
|
||||||
current_count: function(frm, cdt, cdn) {
|
current_count: function(frm, cdt, cdn) {
|
||||||
set_vacancies(frm, cdt, cdn);
|
set_number_of_positions(frm, cdt, cdn);
|
||||||
},
|
},
|
||||||
|
|
||||||
estimated_cost_per_position: function(frm, cdt, cdn) {
|
estimated_cost_per_position: function(frm, cdt, cdn) {
|
||||||
let child = locals[cdt][cdn];
|
|
||||||
set_total_estimated_cost(frm, cdt, cdn);
|
set_total_estimated_cost(frm, cdt, cdn);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var set_vacancies = function(frm, cdt, cdn) {
|
var set_number_of_positions = function(frm, cdt, cdn) {
|
||||||
let child = locals[cdt][cdn]
|
let child = locals[cdt][cdn];
|
||||||
if (child.number_of_positions < (child.current_count + child.current_openings)){
|
if (!child.designation) frappe.throw(__("Please enter the designation"));
|
||||||
frappe.throw(__("Number of positions cannot be less then current count of employees"))
|
frappe.call({
|
||||||
}
|
"method": "erpnext.hr.doctype.staffing_plan.staffing_plan.get_designation_counts",
|
||||||
|
args: {
|
||||||
if(child.number_of_positions > 0) {
|
designation: child.designation,
|
||||||
frappe.model.set_value(cdt, cdn, 'vacancies', child.number_of_positions - (child.current_count + child.current_openings));
|
company: frm.doc.company
|
||||||
}
|
},
|
||||||
else{
|
callback: function (data) {
|
||||||
frappe.model.set_value(cdt, cdn, 'vacancies', 0);
|
if(data.message){
|
||||||
}
|
frappe.model.set_value(cdt, cdn, 'current_count', data.message.employee_count);
|
||||||
|
frappe.model.set_value(cdt, cdn, 'current_openings', data.message.job_openings);
|
||||||
|
let total_positions = cint(data.message.employee_count) + cint(child.vacancies);
|
||||||
|
if (cint(child.number_of_positions) < total_positions){
|
||||||
|
frappe.model.set_value(cdt, cdn, 'number_of_positions', total_positions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{ // No employees for this designation
|
||||||
|
frappe.model.set_value(cdt, cdn, 'current_count', 0);
|
||||||
|
frappe.model.set_value(cdt, cdn, 'current_openings', 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
refresh_field("staffing_details");
|
||||||
set_total_estimated_cost(frm, cdt, cdn);
|
set_total_estimated_cost(frm, cdt, cdn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: Estimated Cost is calculated on number of Vacancies
|
// Note: Estimated Cost is calculated on number of Vacancies
|
||||||
// Validate for > 0 ?
|
|
||||||
var set_total_estimated_cost = function(frm, cdt, cdn) {
|
var set_total_estimated_cost = function(frm, cdt, cdn) {
|
||||||
let child = locals[cdt][cdn]
|
let child = locals[cdt][cdn]
|
||||||
if(child.vacancies > 0 && child.estimated_cost_per_position) {
|
if(child.vacancies > 0 && child.estimated_cost_per_position) {
|
||||||
@ -102,11 +96,11 @@ var set_total_estimated_cost = function(frm, cdt, cdn) {
|
|||||||
var set_total_estimated_budget = function(frm) {
|
var set_total_estimated_budget = function(frm) {
|
||||||
let estimated_budget = 0.0
|
let estimated_budget = 0.0
|
||||||
if(frm.doc.staffing_details) {
|
if(frm.doc.staffing_details) {
|
||||||
$.each(frm.doc.staffing_details, function(index, staff_detail) {
|
(frm.doc.staffing_details || []).forEach(function(staff_detail) {
|
||||||
if(staff_detail.total_estimated_cost){
|
if(staff_detail.total_estimated_cost){
|
||||||
estimated_budget += staff_detail.total_estimated_cost
|
estimated_budget += staff_detail.total_estimated_cost
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
frm.set_value('total_estimated_budget', estimated_budget);
|
frm.set_value('total_estimated_budget', estimated_budget);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,41 +13,39 @@ class ParentCompanyError(frappe.ValidationError): pass
|
|||||||
|
|
||||||
class StaffingPlan(Document):
|
class StaffingPlan(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
|
self.validate_period()
|
||||||
|
self.validate_details()
|
||||||
|
self.set_total_estimated_budget()
|
||||||
|
|
||||||
|
def validate_period(self):
|
||||||
# Validate Dates
|
# Validate Dates
|
||||||
if self.from_date and self.to_date and self.from_date > self.to_date:
|
if self.from_date and self.to_date and self.from_date > self.to_date:
|
||||||
frappe.throw(_("From Date cannot be greater than To Date"))
|
frappe.throw(_("From Date cannot be greater than To Date"))
|
||||||
|
|
||||||
self.total_estimated_budget = 0
|
def validate_details(self):
|
||||||
|
|
||||||
for detail in self.get("staffing_details"):
|
for detail in self.get("staffing_details"):
|
||||||
self.set_vacancies(detail)
|
|
||||||
self.validate_overlap(detail)
|
self.validate_overlap(detail)
|
||||||
self.validate_with_subsidiary_plans(detail)
|
self.validate_with_subsidiary_plans(detail)
|
||||||
self.validate_with_parent_plan(detail)
|
self.validate_with_parent_plan(detail)
|
||||||
|
|
||||||
|
def set_total_estimated_budget(self):
|
||||||
|
self.total_estimated_budget = 0
|
||||||
|
|
||||||
|
for detail in self.get("staffing_details"):
|
||||||
#Set readonly fields
|
#Set readonly fields
|
||||||
|
self.set_number_of_positions(detail)
|
||||||
designation_counts = get_designation_counts(detail.designation, self.company)
|
designation_counts = get_designation_counts(detail.designation, self.company)
|
||||||
detail.current_count = designation_counts['employee_count']
|
detail.current_count = designation_counts['employee_count']
|
||||||
detail.current_openings = designation_counts['job_openings']
|
detail.current_openings = designation_counts['job_openings']
|
||||||
|
|
||||||
if detail.number_of_positions < (detail.current_count + detail.current_openings):
|
if detail.number_of_positions > 0:
|
||||||
frappe.throw(_("Number of positions cannot be less then current count of employees"))
|
|
||||||
elif detail.number_of_positions > 0:
|
|
||||||
detail.vacancies = detail.number_of_positions - (detail.current_count + detail.current_openings)
|
|
||||||
if detail.vacancies > 0 and detail.estimated_cost_per_position:
|
if detail.vacancies > 0 and detail.estimated_cost_per_position:
|
||||||
detail.total_estimated_cost = detail.vacancies * detail.estimated_cost_per_position
|
detail.total_estimated_cost = cint(detail.vacancies) * flt(detail.estimated_cost_per_position)
|
||||||
else: detail.total_estimated_cost = 0
|
|
||||||
else: detail.vacancies = detail.number_of_positions = detail.total_estimated_cost = 0
|
|
||||||
self.total_estimated_budget += detail.total_estimated_cost
|
self.total_estimated_budget += detail.total_estimated_cost
|
||||||
|
|
||||||
def set_vacancies(self, row):
|
def set_number_of_positions(self, detail):
|
||||||
if not row.vacancies:
|
detail.number_of_positions = cint(detail.vacancies) + cint(detail.current_count)
|
||||||
current_openings = 0
|
|
||||||
for field in ['current_count', 'current_openings']:
|
|
||||||
if row.get(field):
|
|
||||||
current_openings += row.get(field)
|
|
||||||
|
|
||||||
row.vacancies = row.number_of_positions - current_openings
|
|
||||||
|
|
||||||
def validate_overlap(self, staffing_plan_detail):
|
def validate_overlap(self, staffing_plan_detail):
|
||||||
# Validate if any submitted Staffing Plan exist for any Designations in this plan
|
# Validate if any submitted Staffing Plan exist for any Designations in this plan
|
||||||
@ -132,19 +130,24 @@ def get_designation_counts(designation, company):
|
|||||||
if not designation:
|
if not designation:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
employee_counts_dict = {}
|
employee_counts = {}
|
||||||
lft, rgt = frappe.get_cached_value('Company', company, ["lft", "rgt"])
|
company_set = get_company_set(company)
|
||||||
employee_counts_dict["employee_count"] = frappe.db.sql("""select count(*) from `tabEmployee`
|
|
||||||
where designation = %s and status='Active'
|
|
||||||
and company in (select name from tabCompany where lft>=%s and rgt<=%s)
|
|
||||||
""", (designation, lft, rgt))[0][0]
|
|
||||||
|
|
||||||
employee_counts_dict['job_openings'] = frappe.db.sql("""select count(*) from `tabJob Opening` \
|
employee_counts["employee_count"] = frappe.db.get_value("Employee",
|
||||||
where designation=%s and status='Open'
|
filters={
|
||||||
and company in (select name from tabCompany where lft>=%s and rgt<=%s)
|
'designation': designation,
|
||||||
""", (designation, lft, rgt))[0][0]
|
'status': 'Active',
|
||||||
|
'company': ('in', company_set)
|
||||||
|
}, fieldname=['count(name)'])
|
||||||
|
|
||||||
return employee_counts_dict
|
employee_counts['job_openings'] = frappe.db.get_value("Job Opening",
|
||||||
|
filters={
|
||||||
|
'designation': designation,
|
||||||
|
'status': 'Open',
|
||||||
|
'company': ('in', company_set)
|
||||||
|
}, fieldname=['count(name)'])
|
||||||
|
|
||||||
|
return employee_counts
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_active_staffing_plan_details(company, designation, from_date=getdate(nowdate()), to_date=getdate(nowdate())):
|
def get_active_staffing_plan_details(company, designation, from_date=getdate(nowdate()), to_date=getdate(nowdate())):
|
||||||
@ -165,3 +168,13 @@ def get_active_staffing_plan_details(company, designation, from_date=getdate(now
|
|||||||
|
|
||||||
# Only a single staffing plan can be active for a designation on given date
|
# Only a single staffing plan can be active for a designation on given date
|
||||||
return staffing_plan if staffing_plan else None
|
return staffing_plan if staffing_plan else None
|
||||||
|
|
||||||
|
def get_company_set(company):
|
||||||
|
return frappe.db.sql_list("""
|
||||||
|
SELECT
|
||||||
|
name
|
||||||
|
FROM `tabCompany`
|
||||||
|
WHERE
|
||||||
|
parent_company=%(company)s
|
||||||
|
OR name=%(company)s
|
||||||
|
""", (dict(company=company)))
|
@ -24,7 +24,7 @@ class TestStaffingPlan(unittest.TestCase):
|
|||||||
staffing_plan.to_date = add_days(nowdate(), 10)
|
staffing_plan.to_date = add_days(nowdate(), 10)
|
||||||
staffing_plan.append("staffing_details", {
|
staffing_plan.append("staffing_details", {
|
||||||
"designation": "Designer",
|
"designation": "Designer",
|
||||||
"number_of_positions": 6,
|
"vacancies": 6,
|
||||||
"estimated_cost_per_position": 50000
|
"estimated_cost_per_position": 50000
|
||||||
})
|
})
|
||||||
staffing_plan.insert()
|
staffing_plan.insert()
|
||||||
@ -42,7 +42,7 @@ class TestStaffingPlan(unittest.TestCase):
|
|||||||
staffing_plan.to_date = add_days(nowdate(), 10)
|
staffing_plan.to_date = add_days(nowdate(), 10)
|
||||||
staffing_plan.append("staffing_details", {
|
staffing_plan.append("staffing_details", {
|
||||||
"designation": "Designer",
|
"designation": "Designer",
|
||||||
"number_of_positions": 3,
|
"vacancies": 3,
|
||||||
"estimated_cost_per_position": 45000
|
"estimated_cost_per_position": 45000
|
||||||
})
|
})
|
||||||
self.assertRaises(SubsidiaryCompanyError, staffing_plan.insert)
|
self.assertRaises(SubsidiaryCompanyError, staffing_plan.insert)
|
||||||
@ -58,7 +58,7 @@ class TestStaffingPlan(unittest.TestCase):
|
|||||||
staffing_plan.to_date = add_days(nowdate(), 10)
|
staffing_plan.to_date = add_days(nowdate(), 10)
|
||||||
staffing_plan.append("staffing_details", {
|
staffing_plan.append("staffing_details", {
|
||||||
"designation": "Designer",
|
"designation": "Designer",
|
||||||
"number_of_positions": 7,
|
"vacancies": 7,
|
||||||
"estimated_cost_per_position": 50000
|
"estimated_cost_per_position": 50000
|
||||||
})
|
})
|
||||||
staffing_plan.insert()
|
staffing_plan.insert()
|
||||||
@ -73,7 +73,7 @@ class TestStaffingPlan(unittest.TestCase):
|
|||||||
staffing_plan.to_date = add_days(nowdate(), 10)
|
staffing_plan.to_date = add_days(nowdate(), 10)
|
||||||
staffing_plan.append("staffing_details", {
|
staffing_plan.append("staffing_details", {
|
||||||
"designation": "Designer",
|
"designation": "Designer",
|
||||||
"number_of_positions": 7,
|
"vacancies": 7,
|
||||||
"estimated_cost_per_position": 60000
|
"estimated_cost_per_position": 60000
|
||||||
})
|
})
|
||||||
staffing_plan.insert()
|
staffing_plan.insert()
|
||||||
@ -93,4 +93,4 @@ def make_company():
|
|||||||
company.parent_company = "_Test Company"
|
company.parent_company = "_Test Company"
|
||||||
company.default_currency = "INR"
|
company.default_currency = "INR"
|
||||||
company.country = "India"
|
company.country = "India"
|
||||||
company.insert()
|
company.insert()
|
@ -1,297 +1,79 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
|
||||||
"allow_guest_to_view": 0,
|
|
||||||
"allow_import": 0,
|
|
||||||
"allow_rename": 0,
|
|
||||||
"beta": 0,
|
|
||||||
"creation": "2018-04-13 18:04:20.978931",
|
"creation": "2018-04-13 18:04:20.978931",
|
||||||
"custom": 0,
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "",
|
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
|
"field_order": [
|
||||||
|
"designation",
|
||||||
|
"vacancies",
|
||||||
|
"estimated_cost_per_position",
|
||||||
|
"total_estimated_cost",
|
||||||
|
"column_break_5",
|
||||||
|
"current_count",
|
||||||
|
"current_openings",
|
||||||
|
"number_of_positions"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "designation",
|
"fieldname": "designation",
|
||||||
"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": "Designation",
|
"label": "Designation",
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Designation",
|
"options": "Designation",
|
||||||
"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": "number_of_positions",
|
"fieldname": "number_of_positions",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"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": "Number Of Positions",
|
"label": "Number Of Positions",
|
||||||
"length": 0,
|
"read_only": 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": 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": "estimated_cost_per_position",
|
"fieldname": "estimated_cost_per_position",
|
||||||
"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": "Estimated Cost Per Position"
|
||||||
"label": "Estimated Cost Per Position",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_5",
|
"fieldname": "column_break_5",
|
||||||
"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": "current_count",
|
"fieldname": "current_count",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Current Count",
|
"label": "Current Count",
|
||||||
"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,
|
|
||||||
"fieldname": "current_openings",
|
"fieldname": "current_openings",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Current Openings",
|
"label": "Current Openings",
|
||||||
"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,
|
|
||||||
"fieldname": "vacancies",
|
"fieldname": "vacancies",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"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": "Vacancies"
|
||||||
"label": "Vacancies",
|
},
|
||||||
"length": 0,
|
{
|
||||||
"no_copy": 0,
|
"fieldname": "total_estimated_cost",
|
||||||
"permlevel": 0,
|
"fieldtype": "Currency",
|
||||||
"precision": "",
|
"in_list_view": 1,
|
||||||
"print_hide": 0,
|
"label": "Total Estimated Cost",
|
||||||
"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
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_bulk_edit": 0,
|
|
||||||
"allow_in_quick_entry": 0,
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "total_estimated_cost",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Total Estimated Cost",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"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-06-24 18:40:37.140178",
|
||||||
"modified": "2018-06-01 17:03:38.020993",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Staffing Plan Detail",
|
"name": "Staffing Plan Detail",
|
||||||
"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
|
}
|
||||||
}
|
|
@ -73,7 +73,7 @@ def create_columns():
|
|||||||
def get_record():
|
def get_record():
|
||||||
data = []
|
data = []
|
||||||
loans = frappe.get_all("Loan",
|
loans = frappe.get_all("Loan",
|
||||||
filters=[("status", "=", "Fully Disbursed")],
|
filters=[("status", "=", "Disbursed")],
|
||||||
fields=["applicant", "applicant_name", "name", "loan_amount", "rate_of_interest",
|
fields=["applicant", "applicant_name", "name", "loan_amount", "rate_of_interest",
|
||||||
"total_payment", "monthly_repayment_amount", "total_amount_paid"]
|
"total_payment", "monthly_repayment_amount", "total_amount_paid"]
|
||||||
)
|
)
|
||||||
|
@ -578,6 +578,8 @@ class BOM(WebsiteGenerator):
|
|||||||
for d in self.operations:
|
for d in self.operations:
|
||||||
if not d.description:
|
if not d.description:
|
||||||
d.description = frappe.db.get_value('Operation', d.operation, 'description')
|
d.description = frappe.db.get_value('Operation', d.operation, 'description')
|
||||||
|
if not d.batch_size > 0:
|
||||||
|
d.batch_size = 1
|
||||||
|
|
||||||
def get_list_context(context):
|
def get_list_context(context):
|
||||||
context.title = _("Bill of Materials")
|
context.title = _("Bill of Materials")
|
||||||
|
@ -1,361 +1,119 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"creation": "2013-02-22 01:27:49",
|
||||||
"allow_guest_to_view": 0,
|
"doctype": "DocType",
|
||||||
"allow_import": 0,
|
"document_type": "Setup",
|
||||||
"allow_rename": 0,
|
"editable_grid": 1,
|
||||||
"beta": 0,
|
"engine": "InnoDB",
|
||||||
"creation": "2013-02-22 01:27:49",
|
"field_order": [
|
||||||
"custom": 0,
|
"operation",
|
||||||
"docstatus": 0,
|
"workstation",
|
||||||
"doctype": "DocType",
|
"description",
|
||||||
"document_type": "Setup",
|
"col_break1",
|
||||||
"editable_grid": 1,
|
"hour_rate",
|
||||||
"engine": "InnoDB",
|
"time_in_mins",
|
||||||
|
"batch_size",
|
||||||
|
"operating_cost",
|
||||||
|
"base_hour_rate",
|
||||||
|
"base_operating_cost",
|
||||||
|
"image"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "operation",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Operation",
|
||||||
"columns": 0,
|
"oldfieldname": "operation_no",
|
||||||
"fieldname": "operation",
|
"oldfieldtype": "Data",
|
||||||
"fieldtype": "Link",
|
"options": "Operation",
|
||||||
"hidden": 0,
|
"reqd": 1
|
||||||
"ignore_user_permissions": 0,
|
},
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Operation",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "operation_no",
|
|
||||||
"oldfieldtype": "Data",
|
|
||||||
"options": "Operation",
|
|
||||||
"permlevel": 0,
|
|
||||||
"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,
|
"fieldname": "workstation",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Workstation",
|
||||||
"columns": 0,
|
"oldfieldname": "workstation",
|
||||||
"fieldname": "workstation",
|
"oldfieldtype": "Link",
|
||||||
"fieldtype": "Link",
|
"options": "Workstation"
|
||||||
"hidden": 0,
|
},
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Workstation",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "workstation",
|
|
||||||
"oldfieldtype": "Link",
|
|
||||||
"options": "Workstation",
|
|
||||||
"permlevel": 0,
|
|
||||||
"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,
|
"fieldname": "description",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Text Editor",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Description",
|
||||||
"columns": 0,
|
"oldfieldname": "opn_description",
|
||||||
"fieldname": "description",
|
"oldfieldtype": "Text"
|
||||||
"fieldtype": "Text Editor",
|
},
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Description",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "opn_description",
|
|
||||||
"oldfieldtype": "Text",
|
|
||||||
"permlevel": 0,
|
|
||||||
"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,
|
"fieldname": "col_break1",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Column Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "col_break1",
|
|
||||||
"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,
|
|
||||||
"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,
|
"fieldname": "hour_rate",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Currency",
|
||||||
"bold": 0,
|
"label": "Hour Rate",
|
||||||
"collapsible": 0,
|
"oldfieldname": "hour_rate",
|
||||||
"columns": 0,
|
"oldfieldtype": "Currency",
|
||||||
"fieldname": "hour_rate",
|
"options": "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": "Hour Rate",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "hour_rate",
|
|
||||||
"oldfieldtype": "Currency",
|
|
||||||
"options": "currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"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,
|
"description": "In minutes",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "time_in_mins",
|
||||||
"bold": 0,
|
"fieldtype": "Float",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 0,
|
"label": "Operation Time ",
|
||||||
"description": "In minutes",
|
"oldfieldname": "time_in_mins",
|
||||||
"fieldname": "time_in_mins",
|
"oldfieldtype": "Currency",
|
||||||
"fieldtype": "Float",
|
"reqd": 1
|
||||||
"hidden": 0,
|
},
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Operation Time ",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "time_in_mins",
|
|
||||||
"oldfieldtype": "Currency",
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"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,
|
"fieldname": "operating_cost",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Currency",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Operating Cost",
|
||||||
"columns": 0,
|
"oldfieldname": "operating_cost",
|
||||||
"fieldname": "operating_cost",
|
"oldfieldtype": "Currency",
|
||||||
"fieldtype": "Currency",
|
"options": "currency",
|
||||||
"hidden": 0,
|
"read_only": 1
|
||||||
"ignore_user_permissions": 0,
|
},
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Operating Cost",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "operating_cost",
|
|
||||||
"oldfieldtype": "Currency",
|
|
||||||
"options": "currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"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,
|
"fieldname": "base_hour_rate",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Currency",
|
||||||
"bold": 0,
|
"label": "Base Hour Rate(Company Currency)",
|
||||||
"collapsible": 0,
|
"options": "Company:company:default_currency",
|
||||||
"columns": 0,
|
"print_hide": 1,
|
||||||
"fieldname": "base_hour_rate",
|
"read_only": 1
|
||||||
"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": "Base Hour Rate(Company Currency)",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 1,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"default": "5",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "base_operating_cost",
|
||||||
"bold": 0,
|
"fieldtype": "Currency",
|
||||||
"collapsible": 0,
|
"label": "Operating Cost(Company Currency)",
|
||||||
"columns": 0,
|
"options": "Company:company:default_currency",
|
||||||
"default": "5",
|
"print_hide": 1,
|
||||||
"fieldname": "base_operating_cost",
|
"read_only": 1
|
||||||
"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": "Operating Cost(Company Currency)",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 1,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "image",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Attach",
|
||||||
"bold": 0,
|
"label": "Image"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
{
|
||||||
"fieldname": "image",
|
"default": "1",
|
||||||
"fieldtype": "Attach",
|
"fieldname": "batch_size",
|
||||||
"hidden": 0,
|
"fieldtype": "Int",
|
||||||
"ignore_user_permissions": 0,
|
"label": "Batch Size"
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Image",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"idx": 1,
|
||||||
"hide_heading": 0,
|
"istable": 1,
|
||||||
"hide_toolbar": 0,
|
"modified": "2019-07-16 22:35:55.374037",
|
||||||
"idx": 1,
|
"modified_by": "govindsmenokee@gmail.com",
|
||||||
"image_view": 0,
|
"module": "Manufacturing",
|
||||||
"in_create": 0,
|
"name": "BOM Operation",
|
||||||
"is_submittable": 0,
|
"owner": "Administrator",
|
||||||
"issingle": 0,
|
"permissions": [],
|
||||||
"istable": 1,
|
"sort_field": "modified",
|
||||||
"max_attachments": 0,
|
"sort_order": "DESC"
|
||||||
"modified": "2018-03-26 09:55:28.107451",
|
}
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Manufacturing",
|
|
||||||
"name": "BOM Operation",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [],
|
|
||||||
"quick_entry": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"track_changes": 0,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
|
||||||
|
@ -505,7 +505,7 @@ def get_material_request_items(row, sales_order,
|
|||||||
total_qty = row['qty']
|
total_qty = row['qty']
|
||||||
|
|
||||||
required_qty = 0
|
required_qty = 0
|
||||||
if ignore_existing_ordered_qty or bin_dict.get("projected_qty") < 0:
|
if ignore_existing_ordered_qty or bin_dict.get("projected_qty", 0) < 0:
|
||||||
required_qty = total_qty
|
required_qty = total_qty
|
||||||
elif total_qty > bin_dict.get("projected_qty"):
|
elif total_qty > bin_dict.get("projected_qty"):
|
||||||
required_qty = total_qty - bin_dict.get("projected_qty")
|
required_qty = total_qty - bin_dict.get("projected_qty")
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
import json
|
import json
|
||||||
|
import math
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import flt, get_datetime, getdate, date_diff, cint, nowdate
|
from frappe.utils import flt, get_datetime, getdate, date_diff, cint, nowdate
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
@ -323,7 +324,7 @@ class WorkOrder(Document):
|
|||||||
select
|
select
|
||||||
operation, description, workstation, idx,
|
operation, description, workstation, idx,
|
||||||
base_hour_rate as hour_rate, time_in_mins,
|
base_hour_rate as hour_rate, time_in_mins,
|
||||||
"Pending" as status, parent as bom
|
"Pending" as status, parent as bom, batch_size
|
||||||
from
|
from
|
||||||
`tabBOM Operation`
|
`tabBOM Operation`
|
||||||
where
|
where
|
||||||
@ -348,7 +349,7 @@ class WorkOrder(Document):
|
|||||||
bom_qty = frappe.db.get_value("BOM", self.bom_no, "quantity")
|
bom_qty = frappe.db.get_value("BOM", self.bom_no, "quantity")
|
||||||
|
|
||||||
for d in self.get("operations"):
|
for d in self.get("operations"):
|
||||||
d.time_in_mins = flt(d.time_in_mins) / flt(bom_qty) * flt(self.qty)
|
d.time_in_mins = flt(d.time_in_mins) / flt(bom_qty) * math.ceil(flt(self.qty) / flt(d.batch_size))
|
||||||
|
|
||||||
self.calculate_operating_cost()
|
self.calculate_operating_cost()
|
||||||
|
|
||||||
|
@ -1,690 +1,200 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"creation": "2014-10-16 14:35:41.950175",
|
||||||
"allow_guest_to_view": 0,
|
"doctype": "DocType",
|
||||||
"allow_import": 0,
|
"editable_grid": 1,
|
||||||
"allow_rename": 0,
|
"engine": "InnoDB",
|
||||||
"beta": 0,
|
"field_order": [
|
||||||
"creation": "2014-10-16 14:35:41.950175",
|
"details",
|
||||||
"custom": 0,
|
"operation",
|
||||||
"docstatus": 0,
|
"bom",
|
||||||
"doctype": "DocType",
|
"description",
|
||||||
"document_type": "",
|
"col_break1",
|
||||||
"editable_grid": 1,
|
"completed_qty",
|
||||||
"engine": "InnoDB",
|
"status",
|
||||||
|
"workstation",
|
||||||
|
"estimated_time_and_cost",
|
||||||
|
"planned_start_time",
|
||||||
|
"planned_end_time",
|
||||||
|
"column_break_10",
|
||||||
|
"time_in_mins",
|
||||||
|
"hour_rate",
|
||||||
|
"batch_size",
|
||||||
|
"planned_operating_cost",
|
||||||
|
"section_break_9",
|
||||||
|
"actual_start_time",
|
||||||
|
"actual_end_time",
|
||||||
|
"column_break_11",
|
||||||
|
"actual_operation_time",
|
||||||
|
"actual_operating_cost"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "details",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Section Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "details",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "operation",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Operation",
|
||||||
"columns": 0,
|
"oldfieldname": "operation_no",
|
||||||
"fieldname": "operation",
|
"oldfieldtype": "Data",
|
||||||
"fieldtype": "Link",
|
"options": "Operation",
|
||||||
"hidden": 0,
|
"read_only": 1,
|
||||||
"ignore_user_permissions": 0,
|
"reqd": 1
|
||||||
"ignore_xss_filter": 0,
|
},
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Operation",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "operation_no",
|
|
||||||
"oldfieldtype": "Data",
|
|
||||||
"options": "Operation",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "bom",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"label": "BOM",
|
||||||
"collapsible": 0,
|
"no_copy": 1,
|
||||||
"columns": 0,
|
"options": "BOM",
|
||||||
"fieldname": "bom",
|
"print_hide": 1,
|
||||||
"fieldtype": "Link",
|
"read_only": 1
|
||||||
"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": "BOM",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "BOM",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 1,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "description",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Text Editor",
|
||||||
"bold": 0,
|
"label": "Operation Description",
|
||||||
"collapsible": 0,
|
"oldfieldname": "opn_description",
|
||||||
"columns": 0,
|
"oldfieldtype": "Text",
|
||||||
"fieldname": "description",
|
"read_only": 1
|
||||||
"fieldtype": "Text Editor",
|
},
|
||||||
"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": "Operation Description",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "opn_description",
|
|
||||||
"oldfieldtype": "Text",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "col_break1",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Column Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "col_break1",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"description": "Operation completed for how many finished goods?",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "completed_qty",
|
||||||
"bold": 0,
|
"fieldtype": "Float",
|
||||||
"collapsible": 0,
|
"label": "Completed Qty",
|
||||||
"columns": 0,
|
"no_copy": 1,
|
||||||
"description": "Operation completed for how many finished goods?",
|
"read_only": 1
|
||||||
"fieldname": "completed_qty",
|
},
|
||||||
"fieldtype": "Float",
|
|
||||||
"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": "Completed Qty",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"default": "Pending",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "status",
|
||||||
"bold": 0,
|
"fieldtype": "Select",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 0,
|
"label": "Status",
|
||||||
"default": "Pending",
|
"no_copy": 1,
|
||||||
"fieldname": "status",
|
"options": "Pending\nWork in Progress\nCompleted",
|
||||||
"fieldtype": "Select",
|
"read_only": 1
|
||||||
"hidden": 0,
|
},
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Status",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Pending\nWork in Progress\nCompleted",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "workstation",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Workstation",
|
||||||
"columns": 0,
|
"oldfieldname": "workstation",
|
||||||
"fieldname": "workstation",
|
"oldfieldtype": "Link",
|
||||||
"fieldtype": "Link",
|
"options": "Workstation"
|
||||||
"hidden": 0,
|
},
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Workstation",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "workstation",
|
|
||||||
"oldfieldtype": "Link",
|
|
||||||
"options": "Workstation",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "estimated_time_and_cost",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Section Break",
|
||||||
"bold": 0,
|
"label": "Estimated Time and Cost"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "estimated_time_and_cost",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Estimated Time and Cost",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "planned_start_time",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Datetime",
|
||||||
"bold": 0,
|
"label": "Planned Start Time",
|
||||||
"collapsible": 0,
|
"no_copy": 1,
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"fieldname": "planned_start_time",
|
},
|
||||||
"fieldtype": "Datetime",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Planned Start Time",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "planned_end_time",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Datetime",
|
||||||
"bold": 0,
|
"label": "Planned End Time",
|
||||||
"collapsible": 0,
|
"no_copy": 1,
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"fieldname": "planned_end_time",
|
},
|
||||||
"fieldtype": "Datetime",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Planned End Time",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "column_break_10",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Column Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_10",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"description": "in Minutes",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "time_in_mins",
|
||||||
"bold": 0,
|
"fieldtype": "Float",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 0,
|
"label": "Operation Time",
|
||||||
"description": "in Minutes",
|
"oldfieldname": "time_in_mins",
|
||||||
"fieldname": "time_in_mins",
|
"oldfieldtype": "Currency",
|
||||||
"fieldtype": "Float",
|
"reqd": 1
|
||||||
"hidden": 0,
|
},
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Operation Time",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "time_in_mins",
|
|
||||||
"oldfieldtype": "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": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "hour_rate",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Float",
|
||||||
"bold": 0,
|
"label": "Hour Rate",
|
||||||
"collapsible": 0,
|
"oldfieldname": "hour_rate",
|
||||||
"columns": 0,
|
"oldfieldtype": "Currency",
|
||||||
"fieldname": "hour_rate",
|
"read_only": 1
|
||||||
"fieldtype": "Float",
|
},
|
||||||
"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": "Hour Rate",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "hour_rate",
|
|
||||||
"oldfieldtype": "Currency",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "planned_operating_cost",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Currency",
|
||||||
"bold": 0,
|
"label": "Planned Operating Cost",
|
||||||
"collapsible": 0,
|
"options": "Company:company:default_currency",
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"fieldname": "planned_operating_cost",
|
},
|
||||||
"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": "Planned Operating Cost",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "section_break_9",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Section Break",
|
||||||
"bold": 0,
|
"label": "Actual Time and Cost"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_9",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Actual Time and Cost",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "actual_start_time",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Datetime",
|
||||||
"bold": 0,
|
"label": "Actual Start Time",
|
||||||
"collapsible": 0,
|
"no_copy": 1,
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"fieldname": "actual_start_time",
|
},
|
||||||
"fieldtype": "Datetime",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Actual Start Time",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"description": "Updated via 'Time Log'",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "actual_end_time",
|
||||||
"bold": 0,
|
"fieldtype": "Datetime",
|
||||||
"collapsible": 0,
|
"label": "Actual End Time",
|
||||||
"columns": 0,
|
"no_copy": 1,
|
||||||
"description": "Updated via 'Time Log'",
|
"read_only": 1
|
||||||
"fieldname": "actual_end_time",
|
},
|
||||||
"fieldtype": "Datetime",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Actual End Time",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "column_break_11",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Column Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_11",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"description": "in Minutes\nUpdated via 'Time Log'",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "actual_operation_time",
|
||||||
"bold": 0,
|
"fieldtype": "Float",
|
||||||
"collapsible": 0,
|
"label": "Actual Operation Time",
|
||||||
"columns": 0,
|
"no_copy": 1,
|
||||||
"description": "in Minutes\nUpdated via 'Time Log'",
|
"read_only": 1
|
||||||
"fieldname": "actual_operation_time",
|
},
|
||||||
"fieldtype": "Float",
|
|
||||||
"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": "Actual Operation Time",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"description": "(Hour Rate / 60) * Actual Operation Time",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "actual_operating_cost",
|
||||||
"bold": 0,
|
"fieldtype": "Currency",
|
||||||
"collapsible": 0,
|
"label": "Actual Operating Cost",
|
||||||
"columns": 0,
|
"no_copy": 1,
|
||||||
"description": "(Hour Rate / 60) * Actual Operation Time",
|
"options": "Company:company:default_currency",
|
||||||
"fieldname": "actual_operating_cost",
|
"read_only": 1
|
||||||
"fieldtype": "Currency",
|
},
|
||||||
"hidden": 0,
|
{
|
||||||
"ignore_user_permissions": 0,
|
"fieldname": "batch_size",
|
||||||
"ignore_xss_filter": 0,
|
"fieldtype": "Int",
|
||||||
"in_filter": 0,
|
"label": "Batch Size",
|
||||||
"in_global_search": 0,
|
"read_only": 1
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Actual Operating Cost",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"istable": 1,
|
||||||
"hide_heading": 0,
|
"modified": "2019-07-16 23:01:07.720337",
|
||||||
"hide_toolbar": 0,
|
"modified_by": "govindsmenokee@gmail.com",
|
||||||
"idx": 0,
|
"module": "Manufacturing",
|
||||||
"image_view": 0,
|
|
||||||
"in_create": 0,
|
|
||||||
"is_submittable": 0,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 1,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-02-13 02:58:11.328693",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Manufacturing",
|
|
||||||
"name": "Work Order Operation",
|
"name": "Work Order Operation",
|
||||||
"name_case": "",
|
"owner": "Administrator",
|
||||||
"owner": "Administrator",
|
"permissions": [],
|
||||||
"permissions": [],
|
"sort_field": "modified",
|
||||||
"quick_entry": 0,
|
"sort_order": "DESC",
|
||||||
"read_only": 0,
|
"track_changes": 1
|
||||||
"read_only_onload": 0,
|
}
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 1,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
|
||||||
|
@ -618,8 +618,10 @@ erpnext.patches.v11_1.set_missing_opportunity_from
|
|||||||
erpnext.patches.v12_0.set_quotation_status
|
erpnext.patches.v12_0.set_quotation_status
|
||||||
erpnext.patches.v12_0.set_priority_for_support
|
erpnext.patches.v12_0.set_priority_for_support
|
||||||
erpnext.patches.v12_0.delete_priority_property_setter
|
erpnext.patches.v12_0.delete_priority_property_setter
|
||||||
|
erpnext.patches.v12_0.set_default_batch_size
|
||||||
execute:frappe.delete_doc("DocType", "Project Task")
|
execute:frappe.delete_doc("DocType", "Project Task")
|
||||||
erpnext.patches.v11_1.update_default_supplier_in_item_defaults
|
erpnext.patches.v11_1.update_default_supplier_in_item_defaults
|
||||||
erpnext.patches.v12_0.update_due_date_in_gle
|
erpnext.patches.v12_0.update_due_date_in_gle
|
||||||
erpnext.patches.v12_0.add_default_buying_selling_terms_in_company
|
erpnext.patches.v12_0.add_default_buying_selling_terms_in_company
|
||||||
erpnext.patches.v12_0.update_ewaybill_field_position
|
erpnext.patches.v12_0.update_ewaybill_field_position
|
||||||
|
erpnext.patches.v11_1.set_status_for_material_request_type_manufacture
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.db.sql("""
|
||||||
|
update `tabMaterial Request`
|
||||||
|
set status='Manufactured'
|
||||||
|
where docstatus=1 and material_request_type='Manufacture' and per_ordered=100 and status != 'Stopped'
|
||||||
|
""")
|
19
erpnext/patches/v12_0/set_default_batch_size.py
Normal file
19
erpnext/patches/v12_0/set_default_batch_size.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.reload_doc("manufacturing", "doctype", "bom_operation")
|
||||||
|
frappe.reload_doc("manufacturing", "doctype", "work_order_operation")
|
||||||
|
|
||||||
|
frappe.db.sql("""
|
||||||
|
UPDATE
|
||||||
|
`tabBOM Operation` bo
|
||||||
|
SET
|
||||||
|
bo.batch_size = 1
|
||||||
|
""")
|
||||||
|
frappe.db.sql("""
|
||||||
|
UPDATE
|
||||||
|
`tabWork Order Operation` wop
|
||||||
|
SET
|
||||||
|
wop.batch_size = 1
|
||||||
|
""")
|
@ -1,6 +1,23 @@
|
|||||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
// License: GNU General Public License v3. See license.txt
|
// License: GNU General Public License v3. See license.txt
|
||||||
frappe.ui.form.on("Project", {
|
frappe.ui.form.on("Project", {
|
||||||
|
setup(frm) {
|
||||||
|
frm.make_methods = {
|
||||||
|
'Timesheet': () => {
|
||||||
|
let doctype = 'Timesheet';
|
||||||
|
frappe.model.with_doctype(doctype, () => {
|
||||||
|
let new_doc = frappe.model.get_new_doc(doctype);
|
||||||
|
|
||||||
|
// add a new row and set the project
|
||||||
|
let time_log = frappe.model.get_new_doc('Timesheet Detail');
|
||||||
|
time_log.project = frm.doc.name;
|
||||||
|
new_doc.time_logs = [time_log];
|
||||||
|
|
||||||
|
frappe.ui.form.make_quick_entry(doctype, null, null, new_doc);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
onload: function (frm) {
|
onload: function (frm) {
|
||||||
var so = frappe.meta.get_docfield("Project", "sales_order");
|
var so = frappe.meta.get_docfield("Project", "sales_order");
|
||||||
so.get_route_options_for_new_doc = function (field) {
|
so.get_route_options_for_new_doc = function (field) {
|
||||||
|
@ -6,18 +6,13 @@
|
|||||||
"description": "Keep Track of Sales Campaigns. Keep track of Leads, Quotations, Sales Order etc from Campaigns to gauge Return on Investment. ",
|
"description": "Keep Track of Sales Campaigns. Keep track of Leads, Quotations, Sales Order etc from Campaigns to gauge Return on Investment. ",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"document_type": "Setup",
|
"document_type": "Setup",
|
||||||
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"campaign",
|
"campaign",
|
||||||
"campaign_name",
|
"campaign_name",
|
||||||
"naming_series",
|
"naming_series",
|
||||||
"from_date",
|
"campaign_schedules_section",
|
||||||
"column_break1",
|
"campaign_schedules",
|
||||||
"status",
|
|
||||||
"to_date",
|
|
||||||
"budget_section",
|
|
||||||
"currency",
|
|
||||||
"column_break2",
|
|
||||||
"budget",
|
|
||||||
"description_section",
|
"description_section",
|
||||||
"description"
|
"description"
|
||||||
],
|
],
|
||||||
@ -52,57 +47,25 @@
|
|||||||
"oldfieldtype": "Text",
|
"oldfieldtype": "Text",
|
||||||
"width": "300px"
|
"width": "300px"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"fieldname": "status",
|
|
||||||
"fieldtype": "Select",
|
|
||||||
"in_list_view": 1,
|
|
||||||
"label": "Status",
|
|
||||||
"options": "\nPlanned\nIn Progress\nCompleted\nCancelled",
|
|
||||||
"reqd": 1,
|
|
||||||
"default": "Planned"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "from_date",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"label": "From Date"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "to_date",
|
|
||||||
"fieldtype": "Date",
|
|
||||||
"label": "To Date"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "column_break1",
|
|
||||||
"fieldtype": "Column Break"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "budget",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"label": "Budget"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "description_section",
|
"fieldname": "description_section",
|
||||||
"fieldtype": "Section Break"
|
"fieldtype": "Section Break"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "currency",
|
"fieldname": "campaign_schedules",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Table",
|
||||||
"label": "Currency",
|
"label": "Campaign Schedules",
|
||||||
"options": "Currency"
|
"options": "Campaign Email Schedule"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "column_break2",
|
"fieldname": "campaign_schedules_section",
|
||||||
"fieldtype": "Column Break"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "budget_section",
|
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "BUDGET"
|
"label": "Campaign Schedules"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-bullhorn",
|
"icon": "fa fa-bullhorn",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"modified": "2019-04-29 22:09:39.251884",
|
"modified": "2019-07-22 12:03:39.832342",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Campaign",
|
"name": "Campaign",
|
||||||
@ -140,5 +103,7 @@
|
|||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1
|
"quick_entry": 1,
|
||||||
}
|
"sort_field": "modified",
|
||||||
|
"sort_order": "DESC"
|
||||||
|
}
|
13
erpnext/selling/doctype/campaign/campaign_dashboard.py
Normal file
13
erpnext/selling/doctype/campaign/campaign_dashboard.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
|
def get_data():
|
||||||
|
return {
|
||||||
|
'fieldname': 'campaign_name',
|
||||||
|
'transactions': [
|
||||||
|
{
|
||||||
|
'label': _('Email Campaigns'),
|
||||||
|
'items': ['Email Campaign']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
@ -509,10 +509,12 @@ def make_material_request(source_name, target_doc=None):
|
|||||||
doc.material_request_type = "Purchase"
|
doc.material_request_type = "Purchase"
|
||||||
|
|
||||||
def update_item(source, target, source_parent):
|
def update_item(source, target, source_parent):
|
||||||
|
# qty is for packed items, because packed items don't have stock_qty field
|
||||||
|
qty = source.get("stock_qty") or source.get("qty")
|
||||||
target.project = source_parent.project
|
target.project = source_parent.project
|
||||||
target.qty = source.stock_qty - requested_item_qty.get(source.name, 0)
|
target.qty = qty - requested_item_qty.get(source.name, 0)
|
||||||
target.conversion_factor = 1
|
target.conversion_factor = 1
|
||||||
target.stock_qty = source.stock_qty - requested_item_qty.get(source.name, 0)
|
target.stock_qty = qty - requested_item_qty.get(source.name, 0)
|
||||||
|
|
||||||
doc = get_mapped_doc("Sales Order", source_name, {
|
doc = get_mapped_doc("Sales Order", source_name, {
|
||||||
"Sales Order": {
|
"Sales Order": {
|
||||||
|
@ -69,8 +69,7 @@ class ItemGroup(NestedSet, WebsiteGenerator):
|
|||||||
"items": get_product_list_for_group(product_group = self.name, start=start,
|
"items": get_product_list_for_group(product_group = self.name, start=start,
|
||||||
limit=context.page_length + 1, search=frappe.form_dict.get("search")),
|
limit=context.page_length + 1, search=frappe.form_dict.get("search")),
|
||||||
"parents": get_parent_item_groups(self.parent_item_group),
|
"parents": get_parent_item_groups(self.parent_item_group),
|
||||||
"title": self.name,
|
"title": self.name
|
||||||
"products_as_list": cint(frappe.db.get_single_value('Products Settings', 'products_as_list'))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if self.slideshow:
|
if self.slideshow:
|
||||||
|
@ -16,18 +16,47 @@ erpnext.stock.ItemDashboard = Class.extend({
|
|||||||
this.content = $(frappe.render_template('item_dashboard')).appendTo(this.parent);
|
this.content = $(frappe.render_template('item_dashboard')).appendTo(this.parent);
|
||||||
this.result = this.content.find('.result');
|
this.result = this.content.find('.result');
|
||||||
|
|
||||||
// move
|
|
||||||
this.content.on('click', '.btn-move', function() {
|
this.content.on('click', '.btn-move', function() {
|
||||||
erpnext.stock.move_item(unescape($(this).attr('data-item')), $(this).attr('data-warehouse'),
|
handle_move_add($(this), "Move")
|
||||||
null, $(this).attr('data-actual_qty'), null, function() { me.refresh(); });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.content.on('click', '.btn-add', function() {
|
this.content.on('click', '.btn-add', function() {
|
||||||
erpnext.stock.move_item(unescape($(this).attr('data-item')), null, $(this).attr('data-warehouse'),
|
handle_move_add($(this), "Add")
|
||||||
$(this).attr('data-actual_qty'), $(this).attr('data-rate'),
|
|
||||||
function() { me.refresh(); });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function handle_move_add(element, action) {
|
||||||
|
let item = unescape(element.attr('data-item'));
|
||||||
|
let warehouse = unescape(element.attr('data-warehouse'));
|
||||||
|
let actual_qty = unescape(element.attr('data-actual_qty'));
|
||||||
|
let disable_quick_entry = Number(unescape(element.attr('data-disable_quick_entry')));
|
||||||
|
let entry_type = action === "Move" ? "Material Transfer": null;
|
||||||
|
|
||||||
|
if (disable_quick_entry) {
|
||||||
|
open_stock_entry(item, warehouse, entry_type);
|
||||||
|
} else {
|
||||||
|
if (action === "Add") {
|
||||||
|
let rate = unescape($(this).attr('data-rate'));
|
||||||
|
erpnext.stock.move_item(item, null, warehouse, actual_qty, rate, function() { me.refresh(); });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
erpnext.stock.move_item(item, warehouse, null, actual_qty, null, function() { me.refresh(); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function open_stock_entry(item, warehouse, entry_type) {
|
||||||
|
frappe.model.with_doctype('Stock Entry', function() {
|
||||||
|
var doc = frappe.model.get_new_doc('Stock Entry');
|
||||||
|
if (entry_type) doc.stock_entry_type = entry_type;
|
||||||
|
|
||||||
|
var row = frappe.model.add_child(doc, 'items');
|
||||||
|
row.item_code = item;
|
||||||
|
row.s_warehouse = warehouse;
|
||||||
|
|
||||||
|
frappe.set_route('Form', doc.doctype, doc.name);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// more
|
// more
|
||||||
this.content.find('.btn-more').on('click', function() {
|
this.content.find('.btn-more').on('click', function() {
|
||||||
me.start += 20;
|
me.start += 20;
|
||||||
@ -196,4 +225,4 @@ erpnext.stock.move_item = function(item, source, target, actual_qty, rate, callb
|
|||||||
frappe.set_route('Form', doc.doctype, doc.name);
|
frappe.set_route('Form', doc.doctype, doc.name);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,9 @@ def get_data(item_code=None, warehouse=None, item_group=None,
|
|||||||
|
|
||||||
for item in items:
|
for item in items:
|
||||||
item.update({
|
item.update({
|
||||||
'item_name': frappe.get_cached_value("Item", item.item_code, 'item_name')
|
'item_name': frappe.get_cached_value("Item", item.item_code, 'item_name'),
|
||||||
|
'disable_quick_entry': frappe.get_cached_value("Item", item.item_code, 'has_batch_no')
|
||||||
|
or frappe.get_cached_value("Item", item.item_code, 'has_serial_no'),
|
||||||
})
|
})
|
||||||
|
|
||||||
return items
|
return items
|
||||||
|
@ -43,11 +43,13 @@
|
|||||||
<div class="col-sm-2 text-right" style="margin-top: 8px;">
|
<div class="col-sm-2 text-right" style="margin-top: 8px;">
|
||||||
{% if d.actual_qty %}
|
{% if d.actual_qty %}
|
||||||
<button class="btn btn-default btn-xs btn-move"
|
<button class="btn btn-default btn-xs btn-move"
|
||||||
|
data-disable_quick_entry="{{ d.disable_quick_entry }}"
|
||||||
data-warehouse="{{ d.warehouse }}"
|
data-warehouse="{{ d.warehouse }}"
|
||||||
data-actual_qty="{{ d.actual_qty }}"
|
data-actual_qty="{{ d.actual_qty }}"
|
||||||
data-item="{{ escape(d.item_code) }}">{{ __("Move") }}</a>
|
data-item="{{ escape(d.item_code) }}">{{ __("Move") }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<button style="margin-left: 7px;" class="btn btn-default btn-xs btn-add"
|
<button style="margin-left: 7px;" class="btn btn-default btn-xs btn-add"
|
||||||
|
data-disable_quick_entry="{{ d.disable_quick_entry }}"
|
||||||
data-warehouse="{{ d.warehouse }}"
|
data-warehouse="{{ d.warehouse }}"
|
||||||
data-actual_qty="{{ d.actual_qty }}"
|
data-actual_qty="{{ d.actual_qty }}"
|
||||||
data-item="{{ escape(d.item_code) }}"
|
data-item="{{ escape(d.item_code) }}"
|
||||||
|
@ -122,8 +122,8 @@ class Batch(Document):
|
|||||||
self.expiry_date = add_days(self.manufacturing_date, shelf_life_in_days)
|
self.expiry_date = add_days(self.manufacturing_date, shelf_life_in_days)
|
||||||
|
|
||||||
if has_expiry_date and not self.expiry_date:
|
if has_expiry_date and not self.expiry_date:
|
||||||
frappe.throw(_('Expiry date is mandatory for selected item'))
|
frappe.msgprint(_('Expiry date is mandatory for selected item.'))
|
||||||
frappe.msgprint(_('Set items shelf life in days, to set expiry based on manufacturing_date plus self life'))
|
frappe.throw(_("Set item's shelf life in days, to set expiry based on manufacturing date plus shelf-life."))
|
||||||
|
|
||||||
def get_name_from_naming_series(self):
|
def get_name_from_naming_series(self):
|
||||||
"""
|
"""
|
||||||
|
@ -67,43 +67,34 @@ frappe.ui.form.on('Delivery Trip', {
|
|||||||
},
|
},
|
||||||
|
|
||||||
calculate_arrival_time: function (frm) {
|
calculate_arrival_time: function (frm) {
|
||||||
frappe.db.get_value("Google Maps Settings", { name: "Google Maps Settings" }, "enabled", (r) => {
|
if (!frm.doc.driver_address) {
|
||||||
if (r.enabled == 0) {
|
frappe.throw(__("Cannot Calculate Arrival Time as Driver Address is Missing."));
|
||||||
frappe.throw(__("Please enable Google Maps Settings to estimate and optimize routes"));
|
}
|
||||||
} else {
|
frappe.show_alert({
|
||||||
frappe.call({
|
message: "Calculating Arrival Times",
|
||||||
method: 'erpnext.stock.doctype.delivery_trip.delivery_trip.get_arrival_times',
|
indicator: 'orange'
|
||||||
freeze: true,
|
});
|
||||||
freeze_message: __("Updating estimated arrival times."),
|
frm.call("process_route", {
|
||||||
args: {
|
optimize: false,
|
||||||
delivery_trip: frm.doc.name,
|
}, () => {
|
||||||
},
|
frm.reload_doc();
|
||||||
callback: function (r) {
|
});
|
||||||
frm.reload_doc();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
optimize_route: function (frm) {
|
optimize_route: function (frm) {
|
||||||
frappe.db.get_value("Google Maps Settings", {name: "Google Maps Settings"}, "enabled", (r) => {
|
if (!frm.doc.driver_address) {
|
||||||
if (r.enabled == 0) {
|
frappe.throw(__("Cannot Optimize Route as Driver Address is Missing."));
|
||||||
frappe.throw(__("Please enable Google Maps Settings to estimate and optimize routes"));
|
}
|
||||||
} else {
|
frappe.show_alert({
|
||||||
frappe.call({
|
message: "Optimizing Route",
|
||||||
method: 'erpnext.stock.doctype.delivery_trip.delivery_trip.optimize_route',
|
indicator: 'orange'
|
||||||
freeze: true,
|
});
|
||||||
freeze_message: __("Optimizing routes."),
|
frm.call("process_route", {
|
||||||
args: {
|
optimize: true,
|
||||||
delivery_trip: frm.doc.name,
|
}, () => {
|
||||||
},
|
frm.reload_doc();
|
||||||
callback: function (r) {
|
});
|
||||||
frm.reload_doc();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
notify_customers: function (frm) {
|
notify_customers: function (frm) {
|
||||||
|
@ -1,735 +1,214 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"autoname": "naming_series:",
|
||||||
"allow_events_in_timeline": 0,
|
"creation": "2017-10-16 16:45:48.293335",
|
||||||
"allow_guest_to_view": 0,
|
"doctype": "DocType",
|
||||||
"allow_import": 0,
|
"document_type": "Document",
|
||||||
"allow_rename": 0,
|
"editable_grid": 1,
|
||||||
"autoname": "naming_series:",
|
"engine": "InnoDB",
|
||||||
"beta": 0,
|
"field_order": [
|
||||||
"creation": "2017-10-16 16:45:48.293335",
|
"naming_series",
|
||||||
"custom": 0,
|
"company",
|
||||||
"docstatus": 0,
|
"column_break_2",
|
||||||
"doctype": "DocType",
|
"email_notification_sent",
|
||||||
"document_type": "Document",
|
"section_break_3",
|
||||||
"editable_grid": 1,
|
"driver",
|
||||||
"engine": "InnoDB",
|
"driver_name",
|
||||||
|
"driver_address",
|
||||||
|
"total_distance",
|
||||||
|
"uom",
|
||||||
|
"column_break_4",
|
||||||
|
"vehicle",
|
||||||
|
"departure_time",
|
||||||
|
"delivery_service_stops",
|
||||||
|
"delivery_stops",
|
||||||
|
"calculate_arrival_time",
|
||||||
|
"optimize_route",
|
||||||
|
"section_break_15",
|
||||||
|
"status",
|
||||||
|
"cb_more_info",
|
||||||
|
"amended_from"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "naming_series",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Select",
|
||||||
"allow_on_submit": 0,
|
"label": "Series",
|
||||||
"bold": 0,
|
"options": "MAT-DT-.YYYY.-"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"default": "",
|
|
||||||
"fieldname": "naming_series",
|
|
||||||
"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": "Series",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "MAT-DT-.YYYY.-",
|
|
||||||
"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,
|
"fieldname": "company",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"label": "Company",
|
||||||
"bold": 0,
|
"options": "Company",
|
||||||
"collapsible": 0,
|
"reqd": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "company",
|
|
||||||
"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": "Company",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company",
|
|
||||||
"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,
|
"fieldname": "column_break_2",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Column Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_2",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"allow_on_submit": 1,
|
||||||
"allow_in_quick_entry": 0,
|
"default": "0",
|
||||||
"allow_on_submit": 1,
|
"fieldname": "email_notification_sent",
|
||||||
"bold": 0,
|
"fieldtype": "Check",
|
||||||
"collapsible": 0,
|
"label": "Initial Email Notification Sent",
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"fieldname": "email_notification_sent",
|
},
|
||||||
"fieldtype": "Check",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Initial Email Notification Sent",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "section_break_3",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Section Break",
|
||||||
"allow_on_submit": 0,
|
"label": "Delivery Details"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_3",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Delivery Details",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "driver",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"label": "Driver",
|
||||||
"bold": 0,
|
"options": "Driver",
|
||||||
"collapsible": 0,
|
"reqd": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "driver",
|
|
||||||
"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": "Driver",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Driver",
|
|
||||||
"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,
|
"fetch_from": "driver.full_name",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "driver_name",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Data",
|
||||||
"bold": 0,
|
"in_list_view": 1,
|
||||||
"collapsible": 0,
|
"label": "Driver Name",
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"fetch_from": "driver.full_name",
|
},
|
||||||
"fieldname": "driver_name",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Driver Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "total_distance",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Float",
|
||||||
"allow_on_submit": 0,
|
"label": "Total Estimated Distance",
|
||||||
"bold": 0,
|
"precision": "2",
|
||||||
"collapsible": 0,
|
"read_only": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "total_distance",
|
|
||||||
"fieldtype": "Float",
|
|
||||||
"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 Estimated Distance",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "2",
|
|
||||||
"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,
|
"depends_on": "eval:doc.total_distance",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "uom",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Link",
|
||||||
"bold": 0,
|
"label": "Distance UOM",
|
||||||
"collapsible": 0,
|
"options": "UOM",
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"default": "",
|
},
|
||||||
"depends_on": "eval:doc.total_distance",
|
|
||||||
"fieldname": "uom",
|
|
||||||
"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": "Distance UOM",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "UOM",
|
|
||||||
"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,
|
"fieldname": "column_break_4",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Column Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_4",
|
|
||||||
"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,
|
"fieldname": "vehicle",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"label": "Vehicle",
|
||||||
"bold": 0,
|
"options": "Vehicle",
|
||||||
"collapsible": 0,
|
"reqd": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "vehicle",
|
|
||||||
"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": "Vehicle",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Vehicle",
|
|
||||||
"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,
|
"fieldname": "departure_time",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Datetime",
|
||||||
"allow_on_submit": 0,
|
"in_list_view": 1,
|
||||||
"bold": 0,
|
"label": "Departure Time",
|
||||||
"collapsible": 0,
|
"reqd": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "departure_time",
|
|
||||||
"fieldtype": "Datetime",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Departure Time",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 1,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "delivery_service_stops",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Section Break",
|
||||||
"allow_on_submit": 0,
|
"label": "Delivery Stops"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "delivery_service_stops",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Delivery Stops",
|
|
||||||
"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,
|
"fieldname": "delivery_stops",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Table",
|
||||||
"allow_on_submit": 0,
|
"label": "Delivery Stop",
|
||||||
"bold": 0,
|
"options": "Delivery Stop",
|
||||||
"collapsible": 0,
|
"reqd": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "delivery_stops",
|
|
||||||
"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": "Delivery Stop",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Delivery Stop",
|
|
||||||
"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,
|
"depends_on": "eval:!doc.__islocal",
|
||||||
"allow_in_quick_entry": 0,
|
"description": "Use Google Maps Direction API to calculate estimated arrival times",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "calculate_arrival_time",
|
||||||
"bold": 0,
|
"fieldtype": "Button",
|
||||||
"collapsible": 0,
|
"label": "Calculate Estimated Arrival Times"
|
||||||
"columns": 0,
|
},
|
||||||
"depends_on": "eval:!doc.__islocal",
|
|
||||||
"fieldname": "calculate_arrival_time",
|
|
||||||
"fieldtype": "Button",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Calculate Estimated Arrival Times",
|
|
||||||
"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,
|
"depends_on": "eval:!doc.__islocal",
|
||||||
"allow_in_quick_entry": 0,
|
"description": "Use Google Maps Direction API to optimize route",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "optimize_route",
|
||||||
"bold": 0,
|
"fieldtype": "Button",
|
||||||
"collapsible": 0,
|
"label": "Optimize Route"
|
||||||
"columns": 0,
|
},
|
||||||
"depends_on": "eval:!doc.__islocal",
|
|
||||||
"fieldname": "optimize_route",
|
|
||||||
"fieldtype": "Button",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Optimize Route",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "",
|
|
||||||
"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_on_submit": 1,
|
||||||
"allow_in_quick_entry": 0,
|
"fieldname": "section_break_15",
|
||||||
"allow_on_submit": 1,
|
"fieldtype": "Section Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_15",
|
|
||||||
"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,
|
"fieldname": "status",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Select",
|
||||||
"allow_on_submit": 0,
|
"in_standard_filter": 1,
|
||||||
"bold": 0,
|
"label": "Status",
|
||||||
"collapsible": 0,
|
"no_copy": 1,
|
||||||
"columns": 0,
|
"options": "Draft\nScheduled\nIn Transit\nCompleted\nCancelled",
|
||||||
"fieldname": "status",
|
"print_hide": 1,
|
||||||
"fieldtype": "Select",
|
"read_only": 1
|
||||||
"hidden": 0,
|
},
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 1,
|
|
||||||
"label": "Status",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Draft\nScheduled\nIn Transit\nCompleted\nCancelled",
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 1,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "cb_more_info",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Column Break"
|
||||||
"allow_on_submit": 0,
|
},
|
||||||
"bold": 0,
|
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "cb_more_info",
|
|
||||||
"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,
|
"fieldname": "amended_from",
|
||||||
"allow_in_quick_entry": 0,
|
"fieldtype": "Link",
|
||||||
"allow_on_submit": 0,
|
"label": "Amended From",
|
||||||
"bold": 0,
|
"no_copy": 1,
|
||||||
"collapsible": 0,
|
"options": "Delivery Trip",
|
||||||
"columns": 0,
|
"print_hide": 1,
|
||||||
"fieldname": "amended_from",
|
"read_only": 1
|
||||||
"fieldtype": "Link",
|
},
|
||||||
"hidden": 0,
|
{
|
||||||
"ignore_user_permissions": 0,
|
"fetch_from": "driver.address",
|
||||||
"ignore_xss_filter": 0,
|
"fieldname": "driver_address",
|
||||||
"in_filter": 0,
|
"fieldtype": "Link",
|
||||||
"in_global_search": 0,
|
"label": "Driver Address",
|
||||||
"in_list_view": 0,
|
"options": "Address",
|
||||||
"in_standard_filter": 0,
|
"read_only": 1
|
||||||
"label": "Amended From",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Delivery Trip",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 1,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"translatable": 0,
|
|
||||||
"unique": 0
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"is_submittable": 1,
|
||||||
"hide_heading": 0,
|
"modified": "2019-07-18 16:38:44.112651",
|
||||||
"hide_toolbar": 0,
|
"modified_by": "Administrator",
|
||||||
"idx": 0,
|
"module": "Stock",
|
||||||
"image_view": 0,
|
"name": "Delivery Trip",
|
||||||
"in_create": 0,
|
"owner": "Administrator",
|
||||||
"is_submittable": 1,
|
|
||||||
"issingle": 0,
|
|
||||||
"istable": 0,
|
|
||||||
"max_attachments": 0,
|
|
||||||
"modified": "2018-10-22 08:25:42.323147",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Stock",
|
|
||||||
"name": "Delivery Trip",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
{
|
{
|
||||||
"amend": 1,
|
"amend": 1,
|
||||||
"cancel": 1,
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
"print": 1,
|
||||||
"import": 0,
|
"read": 1,
|
||||||
"permlevel": 0,
|
"report": 1,
|
||||||
"print": 1,
|
"role": "Fulfillment User",
|
||||||
"read": 1,
|
"share": 1,
|
||||||
"report": 1,
|
"submit": 1,
|
||||||
"role": "Fulfillment User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 1,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amend": 1,
|
"amend": 1,
|
||||||
"cancel": 1,
|
"cancel": 1,
|
||||||
"create": 1,
|
"create": 1,
|
||||||
"delete": 1,
|
"delete": 1,
|
||||||
"email": 1,
|
"email": 1,
|
||||||
"export": 1,
|
"export": 1,
|
||||||
"if_owner": 0,
|
"print": 1,
|
||||||
"import": 0,
|
"read": 1,
|
||||||
"permlevel": 0,
|
"report": 1,
|
||||||
"print": 1,
|
"role": "Stock User",
|
||||||
"read": 1,
|
"share": 1,
|
||||||
"report": 1,
|
"submit": 1,
|
||||||
"role": "Stock User",
|
|
||||||
"set_user_permissions": 0,
|
|
||||||
"share": 1,
|
|
||||||
"submit": 1,
|
|
||||||
"write": 1
|
"write": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 0,
|
"sort_field": "modified",
|
||||||
"read_only": 0,
|
"sort_order": "DESC",
|
||||||
"read_only_onload": 0,
|
"title_field": "driver_name"
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"title_field": "driver_name",
|
|
||||||
"track_changes": 0,
|
|
||||||
"track_seen": 0,
|
|
||||||
"track_views": 0
|
|
||||||
}
|
}
|
@ -100,16 +100,13 @@ class DeliveryTrip(Document):
|
|||||||
optimize (bool): True if route needs to be optimized, else False
|
optimize (bool): True if route needs to be optimized, else False
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not frappe.db.get_single_value("Google Maps Settings", "enabled"):
|
|
||||||
frappe.throw(_("Cannot process route, since Google Maps Settings is disabled."))
|
|
||||||
|
|
||||||
departure_datetime = get_datetime(self.departure_time)
|
departure_datetime = get_datetime(self.departure_time)
|
||||||
route_list = self.form_route_list(optimize)
|
route_list = self.form_route_list(optimize)
|
||||||
|
|
||||||
# For locks, maintain idx count while looping through route list
|
# For locks, maintain idx count while looping through route list
|
||||||
idx = 0
|
idx = 0
|
||||||
for route in route_list:
|
for route in route_list:
|
||||||
directions = get_directions(route, optimize)
|
directions = self.get_directions(route, optimize)
|
||||||
|
|
||||||
if directions:
|
if directions:
|
||||||
if optimize and len(directions.get("waypoint_order")) > 1:
|
if optimize and len(directions.get("waypoint_order")) > 1:
|
||||||
@ -157,9 +154,10 @@ class DeliveryTrip(Document):
|
|||||||
Returns:
|
Returns:
|
||||||
(list of list of str): List of address routes split at locks, if optimize is `True`
|
(list of list of str): List of address routes split at locks, if optimize is `True`
|
||||||
"""
|
"""
|
||||||
|
if not self.driver_address:
|
||||||
|
frappe.throw(_("Cannot Calculate Arrival Time as Driver Address is Missing."))
|
||||||
|
|
||||||
settings = frappe.get_single("Google Maps Settings")
|
home_address = get_address_display(frappe.get_doc("Address", self.driver_address).as_dict())
|
||||||
home_address = get_address_display(frappe.get_doc("Address", settings.home_address).as_dict())
|
|
||||||
|
|
||||||
route_list = []
|
route_list = []
|
||||||
# Initialize first leg with origin as the home address
|
# Initialize first leg with origin as the home address
|
||||||
@ -204,6 +202,47 @@ class DeliveryTrip(Document):
|
|||||||
|
|
||||||
self.delivery_stops[start:start + len(stops_order)] = stops_order
|
self.delivery_stops[start:start + len(stops_order)] = stops_order
|
||||||
|
|
||||||
|
def get_directions(self, route, optimize):
|
||||||
|
"""
|
||||||
|
Retrieve map directions for a given route and departure time.
|
||||||
|
If optimize is `True`, Google Maps will return an optimized
|
||||||
|
order for the intermediate waypoints.
|
||||||
|
|
||||||
|
NOTE: Google's API does take an additional `departure_time` key,
|
||||||
|
but it only works for routes without any waypoints.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
route (list of str): Route addresses (origin -> waypoint(s), if any -> destination)
|
||||||
|
optimize (bool): `True` if route needs to be optimized, else `False`
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
(dict): Route legs and, if `optimize` is `True`, optimized waypoint order
|
||||||
|
"""
|
||||||
|
if not frappe.db.get_single_value("Google Settings", "api_key"):
|
||||||
|
frappe.throw(_("Enter API key in Google Settings."))
|
||||||
|
|
||||||
|
import googlemaps
|
||||||
|
|
||||||
|
try:
|
||||||
|
maps_client = googlemaps.Client(key=frappe.db.get_single_value("Google Settings", "api_key"))
|
||||||
|
except Exception as e:
|
||||||
|
frappe.throw(e)
|
||||||
|
|
||||||
|
directions_data = {
|
||||||
|
"origin": route[0],
|
||||||
|
"destination": route[-1],
|
||||||
|
"waypoints": route[1: -1],
|
||||||
|
"optimize_waypoints": optimize
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
directions = maps_client.directions(**directions_data)
|
||||||
|
except Exception as e:
|
||||||
|
frappe.throw(_(e.message))
|
||||||
|
|
||||||
|
return directions[0] if directions else False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_contact_and_address(name):
|
def get_contact_and_address(name):
|
||||||
@ -278,18 +317,6 @@ def get_contact_display(contact):
|
|||||||
return contact_info.html
|
return contact_info.html
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
|
||||||
def optimize_route(delivery_trip):
|
|
||||||
delivery_trip = frappe.get_doc("Delivery Trip", delivery_trip)
|
|
||||||
delivery_trip.process_route(optimize=True)
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
|
||||||
def get_arrival_times(delivery_trip):
|
|
||||||
delivery_trip = frappe.get_doc("Delivery Trip", delivery_trip)
|
|
||||||
delivery_trip.process_route(optimize=False)
|
|
||||||
|
|
||||||
|
|
||||||
def sanitize_address(address):
|
def sanitize_address(address):
|
||||||
"""
|
"""
|
||||||
Remove HTML breaks in a given address
|
Remove HTML breaks in a given address
|
||||||
@ -310,41 +337,6 @@ def sanitize_address(address):
|
|||||||
return ', '.join(address[:3])
|
return ', '.join(address[:3])
|
||||||
|
|
||||||
|
|
||||||
def get_directions(route, optimize):
|
|
||||||
"""
|
|
||||||
Retrieve map directions for a given route and departure time.
|
|
||||||
If optimize is `True`, Google Maps will return an optimized
|
|
||||||
order for the intermediate waypoints.
|
|
||||||
|
|
||||||
NOTE: Google's API does take an additional `departure_time` key,
|
|
||||||
but it only works for routes without any waypoints.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
route (list of str): Route addresses (origin -> waypoint(s), if any -> destination)
|
|
||||||
optimize (bool): `True` if route needs to be optimized, else `False`
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
(dict): Route legs and, if `optimize` is `True`, optimized waypoint order
|
|
||||||
"""
|
|
||||||
|
|
||||||
settings = frappe.get_single("Google Maps Settings")
|
|
||||||
maps_client = settings.get_client()
|
|
||||||
|
|
||||||
directions_data = {
|
|
||||||
"origin": route[0],
|
|
||||||
"destination": route[-1],
|
|
||||||
"waypoints": route[1: -1],
|
|
||||||
"optimize_waypoints": optimize
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
|
||||||
directions = maps_client.directions(**directions_data)
|
|
||||||
except Exception as e:
|
|
||||||
frappe.throw(_(e.message))
|
|
||||||
|
|
||||||
return directions[0] if directions else False
|
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def notify_customers(delivery_trip):
|
def notify_customers(delivery_trip):
|
||||||
delivery_trip = frappe.get_doc("Delivery Trip", delivery_trip)
|
delivery_trip = frappe.get_doc("Delivery Trip", delivery_trip)
|
||||||
|
@ -14,16 +14,13 @@ from frappe.utils import add_days, flt, now_datetime, nowdate
|
|||||||
|
|
||||||
class TestDeliveryTrip(unittest.TestCase):
|
class TestDeliveryTrip(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
create_driver()
|
driver = create_driver()
|
||||||
create_vehicle()
|
create_vehicle()
|
||||||
create_delivery_notification()
|
create_delivery_notification()
|
||||||
create_test_contact_and_address()
|
create_test_contact_and_address()
|
||||||
|
address = create_address(driver)
|
||||||
|
|
||||||
settings = frappe.get_single("Google Maps Settings")
|
self.delivery_trip = create_delivery_trip(driver, address)
|
||||||
settings.home_address = frappe.get_last_doc("Address").name
|
|
||||||
settings.save()
|
|
||||||
|
|
||||||
self.delivery_trip = create_delivery_trip()
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
frappe.db.sql("delete from `tabDriver`")
|
frappe.db.sql("delete from `tabDriver`")
|
||||||
@ -99,17 +96,42 @@ class TestDeliveryTrip(unittest.TestCase):
|
|||||||
self.delivery_trip.save()
|
self.delivery_trip.save()
|
||||||
self.assertEqual(self.delivery_trip.status, "Completed")
|
self.assertEqual(self.delivery_trip.status, "Completed")
|
||||||
|
|
||||||
|
def create_address(driver):
|
||||||
|
if not frappe.db.exists("Address", {"address_title": "_Test Address for Driver"}):
|
||||||
|
address = frappe.get_doc({
|
||||||
|
"doctype": "Address",
|
||||||
|
"address_title": "_Test Address for Driver",
|
||||||
|
"address_type": "Office",
|
||||||
|
"address_line1": "Station Road",
|
||||||
|
"city": "_Test City",
|
||||||
|
"state": "Test State",
|
||||||
|
"country": "India",
|
||||||
|
"links":[
|
||||||
|
{
|
||||||
|
"link_doctype": "Driver",
|
||||||
|
"link_name": driver.name
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}).insert(ignore_permissions=True)
|
||||||
|
|
||||||
|
frappe.db.set_value("Driver", driver.name, "address", address.name)
|
||||||
|
|
||||||
|
return address
|
||||||
|
|
||||||
|
return frappe.get_doc("Address", {"address_title": "_Test Address for Driver"})
|
||||||
|
|
||||||
def create_driver():
|
def create_driver():
|
||||||
if not frappe.db.exists("Driver", "Newton Scmander"):
|
if not frappe.db.exists("Driver", {"full_name": "Newton Scmander"}):
|
||||||
driver = frappe.get_doc({
|
driver = frappe.get_doc({
|
||||||
"doctype": "Driver",
|
"doctype": "Driver",
|
||||||
"full_name": "Newton Scmander",
|
"full_name": "Newton Scmander",
|
||||||
"cell_number": "98343424242",
|
"cell_number": "98343424242",
|
||||||
"license_number": "B809"
|
"license_number": "B809",
|
||||||
})
|
}).insert(ignore_permissions=True)
|
||||||
driver.insert()
|
|
||||||
|
|
||||||
|
return driver
|
||||||
|
|
||||||
|
return frappe.get_doc("Driver", {"full_name": "Newton Scmander"})
|
||||||
|
|
||||||
def create_delivery_notification():
|
def create_delivery_notification():
|
||||||
if not frappe.db.exists("Email Template", "Delivery Notification"):
|
if not frappe.db.exists("Email Template", "Delivery Notification"):
|
||||||
@ -144,16 +166,16 @@ def create_vehicle():
|
|||||||
vehicle.insert()
|
vehicle.insert()
|
||||||
|
|
||||||
|
|
||||||
def create_delivery_trip(contact=None):
|
def create_delivery_trip(driver, address, contact=None):
|
||||||
if not contact:
|
if not contact:
|
||||||
contact = get_contact_and_address("_Test Customer")
|
contact = get_contact_and_address("_Test Customer")
|
||||||
|
|
||||||
delivery_trip = frappe.new_doc("Delivery Trip")
|
delivery_trip = frappe.get_doc({
|
||||||
delivery_trip.update({
|
|
||||||
"doctype": "Delivery Trip",
|
"doctype": "Delivery Trip",
|
||||||
"company": erpnext.get_default_company(),
|
"company": erpnext.get_default_company(),
|
||||||
"departure_time": add_days(now_datetime(), 5),
|
"departure_time": add_days(now_datetime(), 5),
|
||||||
"driver": frappe.db.get_value('Driver', {"full_name": "Newton Scmander"}),
|
"driver": driver.name,
|
||||||
|
"driver_address": address.name,
|
||||||
"vehicle": "JB 007",
|
"vehicle": "JB 007",
|
||||||
"delivery_stops": [{
|
"delivery_stops": [{
|
||||||
"customer": "_Test Customer",
|
"customer": "_Test Customer",
|
||||||
@ -165,7 +187,6 @@ def create_delivery_trip(contact=None):
|
|||||||
"address": contact.shipping_address.parent,
|
"address": contact.shipping_address.parent,
|
||||||
"contact": contact.contact_person.parent
|
"contact": contact.contact_person.parent
|
||||||
}]
|
}]
|
||||||
})
|
}).insert(ignore_permissions=True)
|
||||||
delivery_trip.insert()
|
|
||||||
|
|
||||||
return delivery_trip
|
return delivery_trip
|
||||||
|
@ -197,6 +197,9 @@ class Item(WebsiteGenerator):
|
|||||||
'route')) + '/' + self.scrub((self.item_name if self.item_name else self.item_code) + '-' + random_string(5))
|
'route')) + '/' + self.scrub((self.item_name if self.item_name else self.item_code) + '-' + random_string(5))
|
||||||
|
|
||||||
def validate_website_image(self):
|
def validate_website_image(self):
|
||||||
|
if frappe.flags.in_import:
|
||||||
|
return
|
||||||
|
|
||||||
"""Validate if the website image is a public file"""
|
"""Validate if the website image is a public file"""
|
||||||
auto_set_website_image = False
|
auto_set_website_image = False
|
||||||
if not self.website_image and self.image:
|
if not self.website_image and self.image:
|
||||||
@ -216,8 +219,7 @@ class Item(WebsiteGenerator):
|
|||||||
|
|
||||||
if not file_doc:
|
if not file_doc:
|
||||||
if not auto_set_website_image:
|
if not auto_set_website_image:
|
||||||
frappe.msgprint(_("Website Image {0} attached to Item {1} cannot be found")
|
frappe.msgprint(_("Website Image {0} attached to Item {1} cannot be found").format(self.website_image, self.name))
|
||||||
.format(self.website_image, self.name))
|
|
||||||
|
|
||||||
self.website_image = None
|
self.website_image = None
|
||||||
|
|
||||||
@ -228,6 +230,9 @@ class Item(WebsiteGenerator):
|
|||||||
self.website_image = None
|
self.website_image = None
|
||||||
|
|
||||||
def make_thumbnail(self):
|
def make_thumbnail(self):
|
||||||
|
if frappe.flags.in_import:
|
||||||
|
return
|
||||||
|
|
||||||
"""Make a thumbnail of `website_image`"""
|
"""Make a thumbnail of `website_image`"""
|
||||||
import requests.exceptions
|
import requests.exceptions
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@ frappe.listview_settings['Material Request'] = {
|
|||||||
return [__("Issued"), "green", "per_ordered,=,100"];
|
return [__("Issued"), "green", "per_ordered,=,100"];
|
||||||
} else if (doc.material_request_type == "Customer Provided") {
|
} else if (doc.material_request_type == "Customer Provided") {
|
||||||
return [__("Received"), "green", "per_ordered,=,100"];
|
return [__("Received"), "green", "per_ordered,=,100"];
|
||||||
|
} else if (doc.material_request_type == "Manufacture") {
|
||||||
|
return [__("Manufactured"), "green", "per_ordered,=,100"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -264,8 +264,12 @@ frappe.ui.form.on('Purchase Receipt Item', {
|
|||||||
var d = locals[cdt][cdn];
|
var d = locals[cdt][cdn];
|
||||||
frappe.db.get_value('Item', {name: d.item_code}, 'sample_quantity', (r) => {
|
frappe.db.get_value('Item', {name: d.item_code}, 'sample_quantity', (r) => {
|
||||||
frappe.model.set_value(cdt, cdn, "sample_quantity", r.sample_quantity);
|
frappe.model.set_value(cdt, cdn, "sample_quantity", r.sample_quantity);
|
||||||
|
validate_sample_quantity(frm, cdt, cdn);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
qty: function(frm, cdt, cdn) {
|
||||||
|
validate_sample_quantity(frm, cdt, cdn);
|
||||||
|
},
|
||||||
sample_quantity: function(frm, cdt, cdn) {
|
sample_quantity: function(frm, cdt, cdn) {
|
||||||
validate_sample_quantity(frm, cdt, cdn);
|
validate_sample_quantity(frm, cdt, cdn);
|
||||||
},
|
},
|
||||||
@ -283,7 +287,7 @@ cur_frm.cscript['Make Stock Entry'] = function() {
|
|||||||
|
|
||||||
var validate_sample_quantity = function(frm, cdt, cdn) {
|
var validate_sample_quantity = function(frm, cdt, cdn) {
|
||||||
var d = locals[cdt][cdn];
|
var d = locals[cdt][cdn];
|
||||||
if (d.sample_quantity) {
|
if (d.sample_quantity && d.qty) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: 'erpnext.stock.doctype.stock_entry.stock_entry.validate_sample_quantity',
|
method: 'erpnext.stock.doctype.stock_entry.stock_entry.validate_sample_quantity',
|
||||||
args: {
|
args: {
|
||||||
|
@ -222,7 +222,7 @@ def validate_serial_no(sle, item_det):
|
|||||||
frappe.throw(_("Serial No {0} has already been received").format(serial_no),
|
frappe.throw(_("Serial No {0} has already been received").format(serial_no),
|
||||||
SerialNoDuplicateError)
|
SerialNoDuplicateError)
|
||||||
|
|
||||||
if (sr.delivery_document_no and sle.voucher_type != 'Stock Entry'
|
if (sr.delivery_document_no and sle.voucher_type not in ['Stock Entry', 'Stock Reconciliation']
|
||||||
and sle.voucher_type == sr.delivery_document_type):
|
and sle.voucher_type == sr.delivery_document_type):
|
||||||
return_against = frappe.db.get_value(sle.voucher_type, sle.voucher_no, 'return_against')
|
return_against = frappe.db.get_value(sle.voucher_type, sle.voucher_no, 'return_against')
|
||||||
if return_against and return_against != sr.delivery_document_no:
|
if return_against and return_against != sr.delivery_document_no:
|
||||||
@ -299,7 +299,7 @@ def validate_so_serial_no(sr, sales_order,):
|
|||||||
be delivered""").format(sales_order, sr.item_code, sr.name))
|
be delivered""").format(sales_order, sr.item_code, sr.name))
|
||||||
|
|
||||||
def has_duplicate_serial_no(sn, sle):
|
def has_duplicate_serial_no(sn, sle):
|
||||||
if sn.warehouse:
|
if sn.warehouse and sle.voucher_type != 'Stock Reconciliation':
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if sn.company != sle.company:
|
if sn.company != sle.company:
|
||||||
@ -415,16 +415,20 @@ def update_serial_nos_after_submit(controller, parentfield):
|
|||||||
if not stock_ledger_entries: return
|
if not stock_ledger_entries: return
|
||||||
|
|
||||||
for d in controller.get(parentfield):
|
for d in controller.get(parentfield):
|
||||||
|
if d.serial_no:
|
||||||
|
continue
|
||||||
|
|
||||||
update_rejected_serial_nos = True if (controller.doctype in ("Purchase Receipt", "Purchase Invoice")
|
update_rejected_serial_nos = True if (controller.doctype in ("Purchase Receipt", "Purchase Invoice")
|
||||||
and d.rejected_qty) else False
|
and d.rejected_qty) else False
|
||||||
accepted_serial_nos_updated = False
|
accepted_serial_nos_updated = False
|
||||||
|
|
||||||
if controller.doctype == "Stock Entry":
|
if controller.doctype == "Stock Entry":
|
||||||
warehouse = d.t_warehouse
|
warehouse = d.t_warehouse
|
||||||
qty = d.transfer_qty
|
qty = d.transfer_qty
|
||||||
else:
|
else:
|
||||||
warehouse = d.warehouse
|
warehouse = d.warehouse
|
||||||
qty = d.stock_qty
|
qty = (d.qty if controller.doctype == "Stock Reconciliation"
|
||||||
|
else d.stock_qty)
|
||||||
for sle in stock_ledger_entries:
|
for sle in stock_ledger_entries:
|
||||||
if sle.voucher_detail_no==d.name:
|
if sle.voucher_detail_no==d.name:
|
||||||
if not accepted_serial_nos_updated and qty and abs(sle.actual_qty)==qty \
|
if not accepted_serial_nos_updated and qty and abs(sle.actual_qty)==qty \
|
||||||
|
@ -359,7 +359,7 @@ class StockEntry(StockController):
|
|||||||
d.basic_rate = 0.0
|
d.basic_rate = 0.0
|
||||||
elif d.t_warehouse and not d.basic_rate:
|
elif d.t_warehouse and not d.basic_rate:
|
||||||
d.basic_rate = get_valuation_rate(d.item_code, d.t_warehouse,
|
d.basic_rate = get_valuation_rate(d.item_code, d.t_warehouse,
|
||||||
self.doctype, d.name, d.allow_zero_valuation_rate,
|
self.doctype, self.name, d.allow_zero_valuation_rate,
|
||||||
currency=erpnext.get_company_currency(self.company))
|
currency=erpnext.get_company_currency(self.company))
|
||||||
|
|
||||||
def set_actual_qty(self):
|
def set_actual_qty(self):
|
||||||
|
@ -38,7 +38,7 @@ class StockLedgerEntry(Document):
|
|||||||
self.check_stock_frozen_date()
|
self.check_stock_frozen_date()
|
||||||
self.actual_amt_check()
|
self.actual_amt_check()
|
||||||
|
|
||||||
if not self.get("via_landed_cost_voucher") and self.voucher_type != 'Stock Reconciliation':
|
if not self.get("via_landed_cost_voucher"):
|
||||||
from erpnext.stock.doctype.serial_no.serial_no import process_serial_no
|
from erpnext.stock.doctype.serial_no.serial_no import process_serial_no
|
||||||
process_serial_no(self)
|
process_serial_no(self)
|
||||||
|
|
||||||
|
@ -12,8 +12,7 @@ frappe.ui.form.on("Stock Reconciliation", {
|
|||||||
return {
|
return {
|
||||||
query: "erpnext.controllers.queries.item_query",
|
query: "erpnext.controllers.queries.item_query",
|
||||||
filters:{
|
filters:{
|
||||||
"is_stock_item": 1,
|
"is_stock_item": 1
|
||||||
"has_serial_no": 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -77,6 +76,7 @@ frappe.ui.form.on("Stock Reconciliation", {
|
|||||||
|
|
||||||
set_valuation_rate_and_qty: function(frm, cdt, cdn) {
|
set_valuation_rate_and_qty: function(frm, cdt, cdn) {
|
||||||
var d = frappe.model.get_doc(cdt, cdn);
|
var d = frappe.model.get_doc(cdt, cdn);
|
||||||
|
|
||||||
if(d.item_code && d.warehouse) {
|
if(d.item_code && d.warehouse) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.stock.doctype.stock_reconciliation.stock_reconciliation.get_stock_balance_for",
|
method: "erpnext.stock.doctype.stock_reconciliation.stock_reconciliation.get_stock_balance_for",
|
||||||
@ -84,7 +84,8 @@ frappe.ui.form.on("Stock Reconciliation", {
|
|||||||
item_code: d.item_code,
|
item_code: d.item_code,
|
||||||
warehouse: d.warehouse,
|
warehouse: d.warehouse,
|
||||||
posting_date: frm.doc.posting_date,
|
posting_date: frm.doc.posting_date,
|
||||||
posting_time: frm.doc.posting_time
|
posting_time: frm.doc.posting_time,
|
||||||
|
batch_no: d.batch_no
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
frappe.model.set_value(cdt, cdn, "qty", r.message.qty);
|
frappe.model.set_value(cdt, cdn, "qty", r.message.qty);
|
||||||
@ -93,7 +94,7 @@ frappe.ui.form.on("Stock Reconciliation", {
|
|||||||
frappe.model.set_value(cdt, cdn, "current_valuation_rate", r.message.rate);
|
frappe.model.set_value(cdt, cdn, "current_valuation_rate", r.message.rate);
|
||||||
frappe.model.set_value(cdt, cdn, "current_amount", r.message.rate * r.message.qty);
|
frappe.model.set_value(cdt, cdn, "current_amount", r.message.rate * r.message.qty);
|
||||||
frappe.model.set_value(cdt, cdn, "amount", r.message.rate * r.message.qty);
|
frappe.model.set_value(cdt, cdn, "amount", r.message.rate * r.message.qty);
|
||||||
|
frappe.model.set_value(cdt, cdn, "current_serial_no", r.message.serial_nos);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -152,17 +153,44 @@ frappe.ui.form.on("Stock Reconciliation Item", {
|
|||||||
barcode: function(frm, cdt, cdn) {
|
barcode: function(frm, cdt, cdn) {
|
||||||
frm.events.set_item_code(frm, cdt, cdn);
|
frm.events.set_item_code(frm, cdt, cdn);
|
||||||
},
|
},
|
||||||
|
|
||||||
warehouse: function(frm, cdt, cdn) {
|
warehouse: function(frm, cdt, cdn) {
|
||||||
|
var child = locals[cdt][cdn];
|
||||||
|
if (child.batch_no) {
|
||||||
|
frappe.model.set_value(child.cdt, child.cdn, "batch_no", "");
|
||||||
|
}
|
||||||
|
|
||||||
frm.events.set_valuation_rate_and_qty(frm, cdt, cdn);
|
frm.events.set_valuation_rate_and_qty(frm, cdt, cdn);
|
||||||
},
|
},
|
||||||
|
|
||||||
item_code: function(frm, cdt, cdn) {
|
item_code: function(frm, cdt, cdn) {
|
||||||
|
var child = locals[cdt][cdn];
|
||||||
|
if (child.batch_no) {
|
||||||
|
frappe.model.set_value(cdt, cdn, "batch_no", "");
|
||||||
|
}
|
||||||
|
|
||||||
frm.events.set_valuation_rate_and_qty(frm, cdt, cdn);
|
frm.events.set_valuation_rate_and_qty(frm, cdt, cdn);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
batch_no: function(frm, cdt, cdn) {
|
||||||
|
frm.events.set_valuation_rate_and_qty(frm, cdt, cdn);
|
||||||
|
},
|
||||||
|
|
||||||
qty: function(frm, cdt, cdn) {
|
qty: function(frm, cdt, cdn) {
|
||||||
frm.events.set_amount_quantity(frm, cdt, cdn);
|
frm.events.set_amount_quantity(frm, cdt, cdn);
|
||||||
},
|
},
|
||||||
|
|
||||||
valuation_rate: function(frm, cdt, cdn) {
|
valuation_rate: function(frm, cdt, cdn) {
|
||||||
frm.events.set_amount_quantity(frm, cdt, cdn);
|
frm.events.set_amount_quantity(frm, cdt, cdn);
|
||||||
|
},
|
||||||
|
|
||||||
|
serial_no: function(frm, cdt, cdn) {
|
||||||
|
var child = locals[cdt][cdn];
|
||||||
|
|
||||||
|
if (child.serial_no) {
|
||||||
|
const serial_nos = child.serial_no.trim().split('\n');
|
||||||
|
frappe.model.set_value(cdt, cdn, "qty", serial_nos.length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -9,7 +9,9 @@ from frappe.utils import cstr, flt, cint
|
|||||||
from erpnext.stock.stock_ledger import update_entries_after
|
from erpnext.stock.stock_ledger import update_entries_after
|
||||||
from erpnext.controllers.stock_controller import StockController
|
from erpnext.controllers.stock_controller import StockController
|
||||||
from erpnext.accounts.utils import get_company_default
|
from erpnext.accounts.utils import get_company_default
|
||||||
from erpnext.stock.utils import get_stock_balance
|
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||||
|
from erpnext.stock.utils import get_stock_balance, get_incoming_rate, get_available_serial_nos
|
||||||
|
from erpnext.stock.doctype.batch.batch import get_batch_qty
|
||||||
|
|
||||||
class OpeningEntryAccountError(frappe.ValidationError): pass
|
class OpeningEntryAccountError(frappe.ValidationError): pass
|
||||||
class EmptyStockReconciliationItemsError(frappe.ValidationError): pass
|
class EmptyStockReconciliationItemsError(frappe.ValidationError): pass
|
||||||
@ -30,10 +32,16 @@ class StockReconciliation(StockController):
|
|||||||
self.validate_expense_account()
|
self.validate_expense_account()
|
||||||
self.set_total_qty_and_amount()
|
self.set_total_qty_and_amount()
|
||||||
|
|
||||||
|
if self._action=="submit":
|
||||||
|
self.make_batches('warehouse')
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
self.update_stock_ledger()
|
self.update_stock_ledger()
|
||||||
self.make_gl_entries()
|
self.make_gl_entries()
|
||||||
|
|
||||||
|
from erpnext.stock.doctype.serial_no.serial_no import update_serial_nos_after_submit
|
||||||
|
update_serial_nos_after_submit(self, "items")
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.delete_and_repost_sle()
|
self.delete_and_repost_sle()
|
||||||
self.make_gl_entries_on_cancel()
|
self.make_gl_entries_on_cancel()
|
||||||
@ -42,23 +50,28 @@ class StockReconciliation(StockController):
|
|||||||
"""Remove items if qty or rate is not changed"""
|
"""Remove items if qty or rate is not changed"""
|
||||||
self.difference_amount = 0.0
|
self.difference_amount = 0.0
|
||||||
def _changed(item):
|
def _changed(item):
|
||||||
qty, rate = get_stock_balance(item.item_code, item.warehouse,
|
item_dict = get_stock_balance_for(item.item_code, item.warehouse,
|
||||||
self.posting_date, self.posting_time, with_valuation_rate=True)
|
self.posting_date, self.posting_time, batch_no=item.batch_no)
|
||||||
if (item.qty==None or item.qty==qty) and (item.valuation_rate==None or item.valuation_rate==rate):
|
if (((item.qty is None or item.qty==item_dict.get("qty")) and
|
||||||
|
(item.valuation_rate is None or item.valuation_rate==item_dict.get("rate")) and not item.serial_no)
|
||||||
|
or (item.serial_no and item.serial_no == item_dict.get("serial_nos"))):
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
# set default as current rates
|
# set default as current rates
|
||||||
if item.qty==None:
|
if item.qty is None:
|
||||||
item.qty = qty
|
item.qty = item_dict.get("qty")
|
||||||
|
|
||||||
if item.valuation_rate==None:
|
if item.valuation_rate is None:
|
||||||
item.valuation_rate = rate
|
item.valuation_rate = item_dict.get("rate")
|
||||||
|
|
||||||
item.current_qty = qty
|
if item_dict.get("serial_nos"):
|
||||||
item.current_valuation_rate = rate
|
item.current_serial_no = item_dict.get("serial_nos")
|
||||||
|
|
||||||
|
item.current_qty = item_dict.get("qty")
|
||||||
|
item.current_valuation_rate = item_dict.get("rate")
|
||||||
self.difference_amount += (flt(item.qty, item.precision("qty")) * \
|
self.difference_amount += (flt(item.qty, item.precision("qty")) * \
|
||||||
flt(item.valuation_rate or rate, item.precision("valuation_rate")) \
|
flt(item.valuation_rate or item_dict.get("rate"), item.precision("valuation_rate")) \
|
||||||
- flt(qty, item.precision("qty")) * flt(rate, item.precision("valuation_rate")))
|
- flt(item_dict.get("qty"), item.precision("qty")) * flt(item_dict.get("rate"), item.precision("valuation_rate")))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
items = list(filter(lambda d: _changed(d), self.items))
|
items = list(filter(lambda d: _changed(d), self.items))
|
||||||
@ -84,12 +97,17 @@ class StockReconciliation(StockController):
|
|||||||
|
|
||||||
for row_num, row in enumerate(self.items):
|
for row_num, row in enumerate(self.items):
|
||||||
# find duplicates
|
# find duplicates
|
||||||
if [row.item_code, row.warehouse] in item_warehouse_combinations:
|
key = [row.item_code, row.warehouse]
|
||||||
|
for field in ['serial_no', 'batch_no']:
|
||||||
|
if row.get(field):
|
||||||
|
key.append(row.get(field))
|
||||||
|
|
||||||
|
if key in item_warehouse_combinations:
|
||||||
self.validation_messages.append(_get_msg(row_num, _("Duplicate entry")))
|
self.validation_messages.append(_get_msg(row_num, _("Duplicate entry")))
|
||||||
else:
|
else:
|
||||||
item_warehouse_combinations.append([row.item_code, row.warehouse])
|
item_warehouse_combinations.append(key)
|
||||||
|
|
||||||
self.validate_item(row.item_code, row_num+1)
|
self.validate_item(row.item_code, row)
|
||||||
|
|
||||||
# validate warehouse
|
# validate warehouse
|
||||||
if not frappe.db.get_value("Warehouse", row.warehouse):
|
if not frappe.db.get_value("Warehouse", row.warehouse):
|
||||||
@ -131,7 +149,7 @@ class StockReconciliation(StockController):
|
|||||||
|
|
||||||
raise frappe.ValidationError(self.validation_messages)
|
raise frappe.ValidationError(self.validation_messages)
|
||||||
|
|
||||||
def validate_item(self, item_code, row_num):
|
def validate_item(self, item_code, row):
|
||||||
from erpnext.stock.doctype.item.item import validate_end_of_life, \
|
from erpnext.stock.doctype.item.item import validate_end_of_life, \
|
||||||
validate_is_stock_item, validate_cancelled_item
|
validate_is_stock_item, validate_cancelled_item
|
||||||
|
|
||||||
@ -145,51 +163,130 @@ class StockReconciliation(StockController):
|
|||||||
validate_is_stock_item(item_code, item.is_stock_item, verbose=0)
|
validate_is_stock_item(item_code, item.is_stock_item, verbose=0)
|
||||||
|
|
||||||
# item should not be serialized
|
# item should not be serialized
|
||||||
if item.has_serial_no == 1:
|
if item.has_serial_no and not row.serial_no and not item.serial_no_series:
|
||||||
raise frappe.ValidationError(_("Serialized Item {0} cannot be updated using Stock Reconciliation, please use Stock Entry").format(item_code))
|
raise frappe.ValidationError(_("Serial no(s) required for serialized item {0}").format(item_code))
|
||||||
|
|
||||||
# item managed batch-wise not allowed
|
# item managed batch-wise not allowed
|
||||||
if item.has_batch_no == 1:
|
if item.has_batch_no and not row.batch_no and not item.create_new_batch:
|
||||||
raise frappe.ValidationError(_("Batched Item {0} cannot be updated using Stock Reconciliation, instead use Stock Entry").format(item_code))
|
raise frappe.ValidationError(_("Batch no is required for batched item {0}").format(item_code))
|
||||||
|
|
||||||
# docstatus should be < 2
|
# docstatus should be < 2
|
||||||
validate_cancelled_item(item_code, item.docstatus, verbose=0)
|
validate_cancelled_item(item_code, item.docstatus, verbose=0)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.validation_messages.append(_("Row # ") + ("%d: " % (row_num)) + cstr(e))
|
self.validation_messages.append(_("Row # ") + ("%d: " % (row.idx)) + cstr(e))
|
||||||
|
|
||||||
def update_stock_ledger(self):
|
def update_stock_ledger(self):
|
||||||
""" find difference between current and expected entries
|
""" find difference between current and expected entries
|
||||||
and create stock ledger entries based on the difference"""
|
and create stock ledger entries based on the difference"""
|
||||||
from erpnext.stock.stock_ledger import get_previous_sle
|
from erpnext.stock.stock_ledger import get_previous_sle
|
||||||
|
|
||||||
|
sl_entries = []
|
||||||
for row in self.items:
|
for row in self.items:
|
||||||
|
item = frappe.get_doc("Item", row.item_code)
|
||||||
|
if item.has_serial_no or item.has_batch_no:
|
||||||
|
self.get_sle_for_serialized_items(row, sl_entries)
|
||||||
|
else:
|
||||||
|
previous_sle = get_previous_sle({
|
||||||
|
"item_code": row.item_code,
|
||||||
|
"warehouse": row.warehouse,
|
||||||
|
"posting_date": self.posting_date,
|
||||||
|
"posting_time": self.posting_time
|
||||||
|
})
|
||||||
|
|
||||||
|
if previous_sle:
|
||||||
|
if row.qty in ("", None):
|
||||||
|
row.qty = previous_sle.get("qty_after_transaction", 0)
|
||||||
|
|
||||||
|
if row.valuation_rate in ("", None):
|
||||||
|
row.valuation_rate = previous_sle.get("valuation_rate", 0)
|
||||||
|
|
||||||
|
if row.qty and not row.valuation_rate:
|
||||||
|
frappe.throw(_("Valuation Rate required for Item {0} at row {1}").format(row.item_code, row.idx))
|
||||||
|
|
||||||
|
if ((previous_sle and row.qty == previous_sle.get("qty_after_transaction")
|
||||||
|
and (row.valuation_rate == previous_sle.get("valuation_rate") or row.qty == 0))
|
||||||
|
or (not previous_sle and not row.qty)):
|
||||||
|
continue
|
||||||
|
|
||||||
|
sl_entries.append(self.get_sle_for_items(row))
|
||||||
|
|
||||||
|
if sl_entries:
|
||||||
|
self.make_sl_entries(sl_entries)
|
||||||
|
|
||||||
|
def get_sle_for_serialized_items(self, row, sl_entries):
|
||||||
|
from erpnext.stock.stock_ledger import get_previous_sle
|
||||||
|
|
||||||
|
serial_nos = get_serial_nos(row.serial_no)
|
||||||
|
|
||||||
|
|
||||||
|
# To issue existing serial nos
|
||||||
|
if row.current_qty and (row.current_serial_no or row.batch_no):
|
||||||
|
args = self.get_sle_for_items(row)
|
||||||
|
args.update({
|
||||||
|
'actual_qty': -1 * row.current_qty,
|
||||||
|
'serial_no': row.current_serial_no,
|
||||||
|
'batch_no': row.batch_no,
|
||||||
|
'valuation_rate': row.current_valuation_rate
|
||||||
|
})
|
||||||
|
|
||||||
|
if row.current_serial_no:
|
||||||
|
args.update({
|
||||||
|
'qty_after_transaction': 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
sl_entries.append(args)
|
||||||
|
|
||||||
|
for serial_no in serial_nos:
|
||||||
|
args = self.get_sle_for_items(row, [serial_no])
|
||||||
|
|
||||||
previous_sle = get_previous_sle({
|
previous_sle = get_previous_sle({
|
||||||
"item_code": row.item_code,
|
"item_code": row.item_code,
|
||||||
"warehouse": row.warehouse,
|
|
||||||
"posting_date": self.posting_date,
|
"posting_date": self.posting_date,
|
||||||
"posting_time": self.posting_time
|
"posting_time": self.posting_time,
|
||||||
|
"serial_no": serial_no
|
||||||
})
|
})
|
||||||
if previous_sle:
|
|
||||||
if row.qty in ("", None):
|
|
||||||
row.qty = previous_sle.get("qty_after_transaction", 0)
|
|
||||||
|
|
||||||
if row.valuation_rate in ("", None):
|
if previous_sle and row.warehouse != previous_sle.get("warehouse"):
|
||||||
row.valuation_rate = previous_sle.get("valuation_rate", 0)
|
# If serial no exists in different warehouse
|
||||||
|
|
||||||
if row.qty and not row.valuation_rate:
|
new_args = args.copy()
|
||||||
frappe.throw(_("Valuation Rate required for Item in row {0}").format(row.idx))
|
new_args.update({
|
||||||
|
'actual_qty': -1,
|
||||||
|
'qty_after_transaction': cint(previous_sle.get('qty_after_transaction')) - 1,
|
||||||
|
'warehouse': previous_sle.get("warehouse", '') or row.warehouse,
|
||||||
|
'valuation_rate': previous_sle.get("valuation_rate")
|
||||||
|
})
|
||||||
|
|
||||||
if ((previous_sle and row.qty == previous_sle.get("qty_after_transaction")
|
sl_entries.append(new_args)
|
||||||
and (row.valuation_rate == previous_sle.get("valuation_rate") or row.qty == 0))
|
|
||||||
or (not previous_sle and not row.qty)):
|
|
||||||
continue
|
|
||||||
|
|
||||||
self.insert_entries(row)
|
if row.qty:
|
||||||
|
args = self.get_sle_for_items(row)
|
||||||
|
|
||||||
def insert_entries(self, row):
|
args.update({
|
||||||
|
'actual_qty': row.qty,
|
||||||
|
'incoming_rate': row.valuation_rate,
|
||||||
|
'valuation_rate': row.valuation_rate
|
||||||
|
})
|
||||||
|
|
||||||
|
sl_entries.append(args)
|
||||||
|
|
||||||
|
if serial_nos == get_serial_nos(row.current_serial_no):
|
||||||
|
# update valuation rate
|
||||||
|
self.update_valuation_rate_for_serial_nos(row, serial_nos)
|
||||||
|
|
||||||
|
def update_valuation_rate_for_serial_nos(self, row, serial_nos):
|
||||||
|
valuation_rate = row.valuation_rate if self.docstatus == 1 else row.current_valuation_rate
|
||||||
|
for d in serial_nos:
|
||||||
|
frappe.db.set_value("Serial No", d, 'purchase_rate', valuation_rate)
|
||||||
|
|
||||||
|
def get_sle_for_items(self, row, serial_nos=None):
|
||||||
"""Insert Stock Ledger Entries"""
|
"""Insert Stock Ledger Entries"""
|
||||||
args = frappe._dict({
|
|
||||||
|
if not serial_nos and row.serial_no:
|
||||||
|
serial_nos = get_serial_nos(row.serial_no)
|
||||||
|
|
||||||
|
data = frappe._dict({
|
||||||
"doctype": "Stock Ledger Entry",
|
"doctype": "Stock Ledger Entry",
|
||||||
"item_code": row.item_code,
|
"item_code": row.item_code,
|
||||||
"warehouse": row.warehouse,
|
"warehouse": row.warehouse,
|
||||||
@ -197,13 +294,19 @@ class StockReconciliation(StockController):
|
|||||||
"posting_time": self.posting_time,
|
"posting_time": self.posting_time,
|
||||||
"voucher_type": self.doctype,
|
"voucher_type": self.doctype,
|
||||||
"voucher_no": self.name,
|
"voucher_no": self.name,
|
||||||
|
"voucher_detail_no": row.name,
|
||||||
"company": self.company,
|
"company": self.company,
|
||||||
"stock_uom": frappe.db.get_value("Item", row.item_code, "stock_uom"),
|
"stock_uom": frappe.db.get_value("Item", row.item_code, "stock_uom"),
|
||||||
"is_cancelled": "No",
|
"is_cancelled": "No" if self.docstatus != 2 else "Yes",
|
||||||
"qty_after_transaction": flt(row.qty, row.precision("qty")),
|
"serial_no": '\n'.join(serial_nos) if serial_nos else '',
|
||||||
|
"batch_no": row.batch_no,
|
||||||
"valuation_rate": flt(row.valuation_rate, row.precision("valuation_rate"))
|
"valuation_rate": flt(row.valuation_rate, row.precision("valuation_rate"))
|
||||||
})
|
})
|
||||||
self.make_sl_entries([args])
|
|
||||||
|
if not row.batch_no:
|
||||||
|
data.qty_after_transaction = flt(row.qty, row.precision("qty"))
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
def delete_and_repost_sle(self):
|
def delete_and_repost_sle(self):
|
||||||
""" Delete Stock Ledger Entries related to this voucher
|
""" Delete Stock Ledger Entries related to this voucher
|
||||||
@ -217,6 +320,15 @@ class StockReconciliation(StockController):
|
|||||||
frappe.db.sql("""delete from `tabStock Ledger Entry`
|
frappe.db.sql("""delete from `tabStock Ledger Entry`
|
||||||
where voucher_type=%s and voucher_no=%s""", (self.doctype, self.name))
|
where voucher_type=%s and voucher_no=%s""", (self.doctype, self.name))
|
||||||
|
|
||||||
|
sl_entries = []
|
||||||
|
for row in self.items:
|
||||||
|
if row.serial_no or row.batch_no or row.current_serial_no:
|
||||||
|
self.get_sle_for_serialized_items(row, sl_entries)
|
||||||
|
|
||||||
|
if sl_entries:
|
||||||
|
sl_entries.reverse()
|
||||||
|
self.make_sl_entries(sl_entries)
|
||||||
|
|
||||||
# repost future entries for selected item_code, warehouse
|
# repost future entries for selected item_code, warehouse
|
||||||
for entries in existing_entries:
|
for entries in existing_entries:
|
||||||
update_entries_after({
|
update_entries_after({
|
||||||
@ -310,17 +422,52 @@ def get_items(warehouse, posting_date, posting_time, company):
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_stock_balance_for(item_code, warehouse, posting_date, posting_time):
|
def get_stock_balance_for(item_code, warehouse,
|
||||||
|
posting_date, posting_time, batch_no=None, with_valuation_rate= True):
|
||||||
frappe.has_permission("Stock Reconciliation", "write", throw = True)
|
frappe.has_permission("Stock Reconciliation", "write", throw = True)
|
||||||
|
|
||||||
qty, rate = get_stock_balance(item_code, warehouse,
|
item_dict = frappe.db.get_value("Item", item_code,
|
||||||
posting_date, posting_time, with_valuation_rate=True)
|
["has_serial_no", "has_batch_no"], as_dict=1)
|
||||||
|
|
||||||
|
serial_nos = ""
|
||||||
|
if item_dict.get("has_serial_no"):
|
||||||
|
qty, rate, serial_nos = get_qty_rate_for_serial_nos(item_code,
|
||||||
|
warehouse, posting_date, posting_time, item_dict)
|
||||||
|
else:
|
||||||
|
qty, rate = get_stock_balance(item_code, warehouse,
|
||||||
|
posting_date, posting_time, with_valuation_rate=with_valuation_rate)
|
||||||
|
|
||||||
|
if item_dict.get("has_batch_no"):
|
||||||
|
qty = get_batch_qty(batch_no, warehouse) or 0
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'qty': qty,
|
'qty': qty,
|
||||||
'rate': rate
|
'rate': rate,
|
||||||
|
'serial_nos': serial_nos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def get_qty_rate_for_serial_nos(item_code, warehouse, posting_date, posting_time, item_dict):
|
||||||
|
args = {
|
||||||
|
"item_code": item_code,
|
||||||
|
"warehouse": warehouse,
|
||||||
|
"posting_date": posting_date,
|
||||||
|
"posting_time": posting_time,
|
||||||
|
}
|
||||||
|
|
||||||
|
serial_nos_list = [serial_no.get("name")
|
||||||
|
for serial_no in get_available_serial_nos(item_code, warehouse)]
|
||||||
|
|
||||||
|
qty = len(serial_nos_list)
|
||||||
|
serial_nos = '\n'.join(serial_nos_list)
|
||||||
|
args.update({
|
||||||
|
'qty': qty,
|
||||||
|
"serial_nos": serial_nos
|
||||||
|
})
|
||||||
|
|
||||||
|
rate = get_incoming_rate(args, raise_error_if_no_rate=False) or 0
|
||||||
|
|
||||||
|
return qty, rate, serial_nos
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_difference_account(purpose, company):
|
def get_difference_account(purpose, company):
|
||||||
if purpose == 'Stock Reconciliation':
|
if purpose == 'Stock Reconciliation':
|
||||||
|
@ -13,9 +13,12 @@ from erpnext.stock.stock_ledger import get_previous_sle, update_entries_after
|
|||||||
from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import EmptyStockReconciliationItemsError, get_items
|
from erpnext.stock.doctype.stock_reconciliation.stock_reconciliation import EmptyStockReconciliationItemsError, get_items
|
||||||
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
|
||||||
from erpnext.stock.doctype.item.test_item import create_item
|
from erpnext.stock.doctype.item.test_item import create_item
|
||||||
|
from erpnext.stock.utils import get_stock_balance, get_incoming_rate, get_available_serial_nos, get_stock_value_on
|
||||||
|
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||||
|
|
||||||
class TestStockReconciliation(unittest.TestCase):
|
class TestStockReconciliation(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
create_batch_or_serial_no_items()
|
||||||
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
|
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
|
||||||
self.insert_existing_sle()
|
self.insert_existing_sle()
|
||||||
|
|
||||||
@ -106,6 +109,135 @@ class TestStockReconciliation(unittest.TestCase):
|
|||||||
make_stock_entry(posting_date="2013-01-05", posting_time="07:00", item_code="_Test Item",
|
make_stock_entry(posting_date="2013-01-05", posting_time="07:00", item_code="_Test Item",
|
||||||
target="_Test Warehouse - _TC", qty=15, basic_rate=1200)
|
target="_Test Warehouse - _TC", qty=15, basic_rate=1200)
|
||||||
|
|
||||||
|
def test_stock_reco_for_serialized_item(self):
|
||||||
|
set_perpetual_inventory()
|
||||||
|
|
||||||
|
to_delete_records = []
|
||||||
|
to_delete_serial_nos = []
|
||||||
|
|
||||||
|
# Add new serial nos
|
||||||
|
serial_item_code = "Stock-Reco-Serial-Item-1"
|
||||||
|
serial_warehouse = "_Test Warehouse for Stock Reco1 - _TC"
|
||||||
|
|
||||||
|
sr = create_stock_reconciliation(item_code=serial_item_code,
|
||||||
|
warehouse = serial_warehouse, qty=5, rate=200)
|
||||||
|
|
||||||
|
# print(sr.name)
|
||||||
|
serial_nos = get_serial_nos(sr.items[0].serial_no)
|
||||||
|
self.assertEqual(len(serial_nos), 5)
|
||||||
|
|
||||||
|
args = {
|
||||||
|
"item_code": serial_item_code,
|
||||||
|
"warehouse": serial_warehouse,
|
||||||
|
"posting_date": nowdate(),
|
||||||
|
"posting_time": nowtime(),
|
||||||
|
"serial_no": sr.items[0].serial_no
|
||||||
|
}
|
||||||
|
|
||||||
|
valuation_rate = get_incoming_rate(args)
|
||||||
|
self.assertEqual(valuation_rate, 200)
|
||||||
|
|
||||||
|
to_delete_records.append(sr.name)
|
||||||
|
|
||||||
|
sr = create_stock_reconciliation(item_code=serial_item_code,
|
||||||
|
warehouse = serial_warehouse, qty=5, rate=300, serial_no = '\n'.join(serial_nos))
|
||||||
|
|
||||||
|
# print(sr.name)
|
||||||
|
serial_nos1 = get_serial_nos(sr.items[0].serial_no)
|
||||||
|
self.assertEqual(len(serial_nos1), 5)
|
||||||
|
|
||||||
|
args = {
|
||||||
|
"item_code": serial_item_code,
|
||||||
|
"warehouse": serial_warehouse,
|
||||||
|
"posting_date": nowdate(),
|
||||||
|
"posting_time": nowtime(),
|
||||||
|
"serial_no": sr.items[0].serial_no
|
||||||
|
}
|
||||||
|
|
||||||
|
valuation_rate = get_incoming_rate(args)
|
||||||
|
self.assertEqual(valuation_rate, 300)
|
||||||
|
|
||||||
|
to_delete_records.append(sr.name)
|
||||||
|
to_delete_records.reverse()
|
||||||
|
|
||||||
|
for d in to_delete_records:
|
||||||
|
stock_doc = frappe.get_doc("Stock Reconciliation", d)
|
||||||
|
stock_doc.cancel()
|
||||||
|
frappe.delete_doc("Stock Reconciliation", stock_doc.name)
|
||||||
|
|
||||||
|
for d in serial_nos + serial_nos1:
|
||||||
|
if frappe.db.exists("Serial No", d):
|
||||||
|
frappe.delete_doc("Serial No", d)
|
||||||
|
|
||||||
|
def test_stock_reco_for_batch_item(self):
|
||||||
|
set_perpetual_inventory()
|
||||||
|
|
||||||
|
to_delete_records = []
|
||||||
|
to_delete_serial_nos = []
|
||||||
|
|
||||||
|
# Add new serial nos
|
||||||
|
item_code = "Stock-Reco-batch-Item-1"
|
||||||
|
warehouse = "_Test Warehouse for Stock Reco2 - _TC"
|
||||||
|
|
||||||
|
sr = create_stock_reconciliation(item_code=item_code,
|
||||||
|
warehouse = warehouse, qty=5, rate=200, do_not_submit=1)
|
||||||
|
sr.save(ignore_permissions=True)
|
||||||
|
sr.submit()
|
||||||
|
|
||||||
|
self.assertTrue(sr.items[0].batch_no)
|
||||||
|
to_delete_records.append(sr.name)
|
||||||
|
|
||||||
|
sr1 = create_stock_reconciliation(item_code=item_code,
|
||||||
|
warehouse = warehouse, qty=6, rate=300, batch_no=sr.items[0].batch_no)
|
||||||
|
|
||||||
|
args = {
|
||||||
|
"item_code": item_code,
|
||||||
|
"warehouse": warehouse,
|
||||||
|
"posting_date": nowdate(),
|
||||||
|
"posting_time": nowtime(),
|
||||||
|
}
|
||||||
|
|
||||||
|
valuation_rate = get_incoming_rate(args)
|
||||||
|
self.assertEqual(valuation_rate, 300)
|
||||||
|
to_delete_records.append(sr1.name)
|
||||||
|
|
||||||
|
|
||||||
|
sr2 = create_stock_reconciliation(item_code=item_code,
|
||||||
|
warehouse = warehouse, qty=0, rate=0, batch_no=sr.items[0].batch_no)
|
||||||
|
|
||||||
|
stock_value = get_stock_value_on(warehouse, nowdate(), item_code)
|
||||||
|
self.assertEqual(stock_value, 0)
|
||||||
|
to_delete_records.append(sr2.name)
|
||||||
|
|
||||||
|
to_delete_records.reverse()
|
||||||
|
for d in to_delete_records:
|
||||||
|
stock_doc = frappe.get_doc("Stock Reconciliation", d)
|
||||||
|
stock_doc.cancel()
|
||||||
|
|
||||||
|
frappe.delete_doc("Batch", sr.items[0].batch_no)
|
||||||
|
for d in to_delete_records:
|
||||||
|
frappe.delete_doc("Stock Reconciliation", d)
|
||||||
|
|
||||||
|
def create_batch_or_serial_no_items():
|
||||||
|
create_warehouse("_Test Warehouse for Stock Reco1",
|
||||||
|
{"is_group": 0, "parent_warehouse": "_Test Warehouse Group - _TC"})
|
||||||
|
|
||||||
|
create_warehouse("_Test Warehouse for Stock Reco2",
|
||||||
|
{"is_group": 0, "parent_warehouse": "_Test Warehouse Group - _TC"})
|
||||||
|
|
||||||
|
serial_item_doc = create_item("Stock-Reco-Serial-Item-1", is_stock_item=1)
|
||||||
|
if not serial_item_doc.has_serial_no:
|
||||||
|
serial_item_doc.has_serial_no = 1
|
||||||
|
serial_item_doc.serial_no_series = "SRSI.####"
|
||||||
|
serial_item_doc.save(ignore_permissions=True)
|
||||||
|
|
||||||
|
batch_item_doc = create_item("Stock-Reco-batch-Item-1", is_stock_item=1)
|
||||||
|
if not batch_item_doc.has_batch_no:
|
||||||
|
batch_item_doc.has_batch_no = 1
|
||||||
|
batch_item_doc.create_new_batch = 1
|
||||||
|
serial_item_doc.batch_number_series = "BASR.#####"
|
||||||
|
batch_item_doc.save(ignore_permissions=True)
|
||||||
|
|
||||||
def create_stock_reconciliation(**args):
|
def create_stock_reconciliation(**args):
|
||||||
args = frappe._dict(args)
|
args = frappe._dict(args)
|
||||||
sr = frappe.new_doc("Stock Reconciliation")
|
sr = frappe.new_doc("Stock Reconciliation")
|
||||||
@ -120,11 +252,14 @@ def create_stock_reconciliation(**args):
|
|||||||
"item_code": args.item_code or "_Test Item",
|
"item_code": args.item_code or "_Test Item",
|
||||||
"warehouse": args.warehouse or "_Test Warehouse - _TC",
|
"warehouse": args.warehouse or "_Test Warehouse - _TC",
|
||||||
"qty": args.qty,
|
"qty": args.qty,
|
||||||
"valuation_rate": args.rate
|
"valuation_rate": args.rate,
|
||||||
|
"serial_no": args.serial_no,
|
||||||
|
"batch_no": args.batch_no
|
||||||
})
|
})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sr.submit()
|
if not args.do_not_submit:
|
||||||
|
sr.submit()
|
||||||
except EmptyStockReconciliationItemsError:
|
except EmptyStockReconciliationItemsError:
|
||||||
pass
|
pass
|
||||||
return sr
|
return sr
|
||||||
@ -140,3 +275,4 @@ def set_valuation_method(item_code, valuation_method):
|
|||||||
}, allow_negative_stock=1)
|
}, allow_negative_stock=1)
|
||||||
|
|
||||||
test_dependencies = ["Item", "Warehouse"]
|
test_dependencies = ["Item", "Warehouse"]
|
||||||
|
|
||||||
|
@ -1,560 +1,182 @@
|
|||||||
{
|
{
|
||||||
"allow_copy": 0,
|
"creation": "2015-02-17 01:06:05.072764",
|
||||||
"allow_guest_to_view": 0,
|
"doctype": "DocType",
|
||||||
"allow_import": 0,
|
"document_type": "Other",
|
||||||
"allow_rename": 0,
|
"editable_grid": 1,
|
||||||
"beta": 0,
|
"engine": "InnoDB",
|
||||||
"creation": "2015-02-17 01:06:05.072764",
|
"field_order": [
|
||||||
"custom": 0,
|
"barcode",
|
||||||
"docstatus": 0,
|
"item_code",
|
||||||
"doctype": "DocType",
|
"item_name",
|
||||||
"document_type": "Other",
|
"warehouse",
|
||||||
"editable_grid": 1,
|
"column_break_6",
|
||||||
"engine": "InnoDB",
|
"qty",
|
||||||
|
"valuation_rate",
|
||||||
|
"amount",
|
||||||
|
"serial_no_and_batch_section",
|
||||||
|
"serial_no",
|
||||||
|
"column_break_11",
|
||||||
|
"batch_no",
|
||||||
|
"section_break_3",
|
||||||
|
"current_qty",
|
||||||
|
"current_serial_no",
|
||||||
|
"column_break_9",
|
||||||
|
"current_valuation_rate",
|
||||||
|
"current_amount",
|
||||||
|
"section_break_14",
|
||||||
|
"quantity_difference",
|
||||||
|
"column_break_16",
|
||||||
|
"amount_difference"
|
||||||
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "barcode",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Data",
|
||||||
"bold": 0,
|
"label": "Barcode",
|
||||||
"collapsible": 0,
|
"print_hide": 1
|
||||||
"columns": 0,
|
},
|
||||||
"fieldname": "barcode",
|
|
||||||
"fieldtype": "Data",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Barcode",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 1,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 3,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "item_code",
|
||||||
"bold": 0,
|
"fieldtype": "Link",
|
||||||
"collapsible": 0,
|
"in_global_search": 1,
|
||||||
"columns": 3,
|
"in_list_view": 1,
|
||||||
"fieldname": "item_code",
|
"label": "Item Code",
|
||||||
"fieldtype": "Link",
|
"options": "Item",
|
||||||
"hidden": 0,
|
"reqd": 1
|
||||||
"ignore_user_permissions": 0,
|
},
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 1,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Item Code",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Item",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "item_name",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Data",
|
||||||
"bold": 0,
|
"in_global_search": 1,
|
||||||
"collapsible": 0,
|
"label": "Item Name",
|
||||||
"columns": 0,
|
"no_copy": 1,
|
||||||
"fieldname": "item_name",
|
"print_hide": 1,
|
||||||
"fieldtype": "Data",
|
"read_only": 1
|
||||||
"hidden": 0,
|
},
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 1,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Item Name",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 1,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 1,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 3,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "warehouse",
|
||||||
"bold": 0,
|
"fieldtype": "Link",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 3,
|
"label": "Warehouse",
|
||||||
"fieldname": "warehouse",
|
"options": "Warehouse",
|
||||||
"fieldtype": "Link",
|
"reqd": 1
|
||||||
"hidden": 0,
|
},
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Warehouse",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Warehouse",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "column_break_6",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Column Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_6",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "qty",
|
||||||
"bold": 0,
|
"fieldtype": "Float",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 2,
|
"label": "Quantity"
|
||||||
"description": "",
|
},
|
||||||
"fieldname": "qty",
|
|
||||||
"fieldtype": "Float",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Quantity",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"columns": 2,
|
||||||
"allow_on_submit": 0,
|
"fieldname": "valuation_rate",
|
||||||
"bold": 0,
|
"fieldtype": "Currency",
|
||||||
"collapsible": 0,
|
"in_list_view": 1,
|
||||||
"columns": 2,
|
"label": "Valuation Rate",
|
||||||
"description": "",
|
"options": "Company:company:default_currency"
|
||||||
"fieldname": "valuation_rate",
|
},
|
||||||
"fieldtype": "Currency",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 1,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Valuation Rate",
|
|
||||||
"length": 0,
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "amount",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Currency",
|
||||||
"bold": 0,
|
"label": "Amount",
|
||||||
"collapsible": 0,
|
"options": "Company:company:default_currency",
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"fieldname": "amount",
|
},
|
||||||
"fieldtype": "Currency",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Amount",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "serial_no_and_batch_section",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Section Break",
|
||||||
"bold": 0,
|
"label": "Serial No and Batch"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "section_break_3",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Before reconciliation",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "serial_no",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Small Text",
|
||||||
"bold": 0,
|
"label": "Serial No"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"description": "",
|
|
||||||
"fieldname": "current_qty",
|
|
||||||
"fieldtype": "Float",
|
|
||||||
"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": "Current Qty",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 1,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "column_break_11",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Column Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "column_break_9",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "section_break_3",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Section Break",
|
||||||
"bold": 0,
|
"label": "Before reconciliation"
|
||||||
"collapsible": 0,
|
},
|
||||||
"columns": 0,
|
|
||||||
"description": "",
|
|
||||||
"fieldname": "current_valuation_rate",
|
|
||||||
"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": "Current Valuation Rate",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"default": "0",
|
||||||
"allow_on_submit": 0,
|
"fieldname": "current_qty",
|
||||||
"bold": 0,
|
"fieldtype": "Float",
|
||||||
"collapsible": 0,
|
"label": "Current Qty",
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"description": "",
|
},
|
||||||
"fieldname": "current_amount",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"label": "Current Amount",
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "current_serial_no",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Small Text",
|
||||||
"bold": 0,
|
"label": "Current Serial No",
|
||||||
"collapsible": 0,
|
"no_copy": 1,
|
||||||
"columns": 0,
|
"print_hide": 1,
|
||||||
"fieldname": "section_break_14",
|
"read_only": 1
|
||||||
"fieldtype": "Section Break",
|
},
|
||||||
"hidden": 0,
|
|
||||||
"ignore_user_permissions": 0,
|
|
||||||
"ignore_xss_filter": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"in_global_search": 0,
|
|
||||||
"in_list_view": 0,
|
|
||||||
"in_standard_filter": 0,
|
|
||||||
"length": 0,
|
|
||||||
"no_copy": 0,
|
|
||||||
"permlevel": 0,
|
|
||||||
"precision": "",
|
|
||||||
"print_hide": 0,
|
|
||||||
"print_hide_if_no_value": 0,
|
|
||||||
"read_only": 0,
|
|
||||||
"remember_last_selected_value": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0,
|
|
||||||
"set_only_once": 0,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "column_break_9",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Column Break"
|
||||||
"bold": 0,
|
},
|
||||||
"collapsible": 0,
|
|
||||||
"columns": 0,
|
|
||||||
"fieldname": "quantity_difference",
|
|
||||||
"fieldtype": "Read Only",
|
|
||||||
"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": "Quantity Difference",
|
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "current_valuation_rate",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Currency",
|
||||||
"bold": 0,
|
"label": "Current Valuation Rate",
|
||||||
"collapsible": 0,
|
"options": "Company:company:default_currency",
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"fieldname": "column_break_16",
|
},
|
||||||
"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,
|
|
||||||
"unique": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_bulk_edit": 0,
|
"fieldname": "current_amount",
|
||||||
"allow_on_submit": 0,
|
"fieldtype": "Currency",
|
||||||
"bold": 0,
|
"label": "Current Amount",
|
||||||
"collapsible": 0,
|
"options": "Company:company:default_currency",
|
||||||
"columns": 0,
|
"read_only": 1
|
||||||
"fieldname": "amount_difference",
|
},
|
||||||
"fieldtype": "Currency",
|
{
|
||||||
"hidden": 0,
|
"fieldname": "section_break_14",
|
||||||
"ignore_user_permissions": 0,
|
"fieldtype": "Section Break"
|
||||||
"ignore_xss_filter": 0,
|
},
|
||||||
"in_filter": 0,
|
{
|
||||||
"in_global_search": 0,
|
"fieldname": "quantity_difference",
|
||||||
"in_list_view": 0,
|
"fieldtype": "Read Only",
|
||||||
"in_standard_filter": 0,
|
"label": "Quantity Difference"
|
||||||
"label": "Amount Difference",
|
},
|
||||||
"length": 0,
|
{
|
||||||
"no_copy": 0,
|
"fieldname": "column_break_16",
|
||||||
"options": "Company:company:default_currency",
|
"fieldtype": "Column Break"
|
||||||
"permlevel": 0,
|
},
|
||||||
"precision": "",
|
{
|
||||||
"print_hide": 0,
|
"fieldname": "amount_difference",
|
||||||
"print_hide_if_no_value": 0,
|
"fieldtype": "Currency",
|
||||||
"read_only": 1,
|
"label": "Amount Difference",
|
||||||
"remember_last_selected_value": 0,
|
"options": "Company:company:default_currency",
|
||||||
"report_hide": 0,
|
"read_only": 1
|
||||||
"reqd": 0,
|
},
|
||||||
"search_index": 0,
|
{
|
||||||
"set_only_once": 0,
|
"fieldname": "batch_no",
|
||||||
"unique": 0
|
"fieldtype": "Link",
|
||||||
|
"label": "Batch No",
|
||||||
|
"options": "Batch"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"has_web_view": 0,
|
"istable": 1,
|
||||||
"hide_heading": 0,
|
"modified": "2019-06-14 17:10:53.188305",
|
||||||
"hide_toolbar": 0,
|
"modified_by": "Administrator",
|
||||||
"idx": 0,
|
"module": "Stock",
|
||||||
"image_view": 0,
|
"name": "Stock Reconciliation Item",
|
||||||
"in_create": 0,
|
"owner": "Administrator",
|
||||||
"is_submittable": 0,
|
"permissions": [],
|
||||||
"issingle": 0,
|
"quick_entry": 1,
|
||||||
"istable": 1,
|
"sort_field": "modified",
|
||||||
"max_attachments": 0,
|
"sort_order": "DESC",
|
||||||
"menu_index": 0,
|
"track_changes": 1
|
||||||
"modified": "2017-08-03 00:03:40.412071",
|
|
||||||
"modified_by": "Administrator",
|
|
||||||
"module": "Stock",
|
|
||||||
"name": "Stock Reconciliation Item",
|
|
||||||
"name_case": "",
|
|
||||||
"owner": "Administrator",
|
|
||||||
"permissions": [],
|
|
||||||
"quick_entry": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"read_only_onload": 0,
|
|
||||||
"show_name_in_global_search": 0,
|
|
||||||
"sort_field": "modified",
|
|
||||||
"sort_order": "DESC",
|
|
||||||
"track_changes": 1,
|
|
||||||
"track_seen": 0
|
|
||||||
}
|
}
|
@ -55,10 +55,12 @@ def get_conditions(filters):
|
|||||||
#get all details
|
#get all details
|
||||||
def get_stock_ledger_entries(filters):
|
def get_stock_ledger_entries(filters):
|
||||||
conditions = get_conditions(filters)
|
conditions = get_conditions(filters)
|
||||||
return frappe.db.sql("""select item_code, batch_no, warehouse,
|
return frappe.db.sql("""
|
||||||
posting_date, actual_qty
|
select item_code, batch_no, warehouse, posting_date, sum(actual_qty) as actual_qty
|
||||||
from `tabStock Ledger Entry`
|
from `tabStock Ledger Entry`
|
||||||
where docstatus < 2 and ifnull(batch_no, '') != '' %s order by item_code, warehouse""" %
|
where docstatus < 2 and ifnull(batch_no, '') != '' %s
|
||||||
|
group by voucher_no, batch_no, item_code, warehouse
|
||||||
|
order by item_code, warehouse""" %
|
||||||
conditions, as_dict=1)
|
conditions, as_dict=1)
|
||||||
|
|
||||||
def get_item_warehouse_batch_map(filters, float_precision):
|
def get_item_warehouse_batch_map(filters, float_precision):
|
||||||
|
@ -157,9 +157,12 @@ class update_entries_after(object):
|
|||||||
if sle.serial_no:
|
if sle.serial_no:
|
||||||
self.get_serialized_values(sle)
|
self.get_serialized_values(sle)
|
||||||
self.qty_after_transaction += flt(sle.actual_qty)
|
self.qty_after_transaction += flt(sle.actual_qty)
|
||||||
|
if sle.voucher_type == "Stock Reconciliation":
|
||||||
|
self.qty_after_transaction = sle.qty_after_transaction
|
||||||
|
|
||||||
self.stock_value = flt(self.qty_after_transaction) * flt(self.valuation_rate)
|
self.stock_value = flt(self.qty_after_transaction) * flt(self.valuation_rate)
|
||||||
else:
|
else:
|
||||||
if sle.voucher_type=="Stock Reconciliation":
|
if sle.voucher_type=="Stock Reconciliation" and not sle.batch_no:
|
||||||
# assert
|
# assert
|
||||||
self.valuation_rate = sle.valuation_rate
|
self.valuation_rate = sle.valuation_rate
|
||||||
self.qty_after_transaction = sle.qty_after_transaction
|
self.qty_after_transaction = sle.qty_after_transaction
|
||||||
@ -371,7 +374,7 @@ class update_entries_after(object):
|
|||||||
"""get Stock Ledger Entries after a particular datetime, for reposting"""
|
"""get Stock Ledger Entries after a particular datetime, for reposting"""
|
||||||
return get_stock_ledger_entries(self.previous_sle or frappe._dict({
|
return get_stock_ledger_entries(self.previous_sle or frappe._dict({
|
||||||
"item_code": self.args.get("item_code"), "warehouse": self.args.get("warehouse") }),
|
"item_code": self.args.get("item_code"), "warehouse": self.args.get("warehouse") }),
|
||||||
">", "asc", for_update=True)
|
">", "asc", for_update=True, check_serial_no=False)
|
||||||
|
|
||||||
def raise_exceptions(self):
|
def raise_exceptions(self):
|
||||||
deficiency = min(e["diff"] for e in self.exceptions)
|
deficiency = min(e["diff"] for e in self.exceptions)
|
||||||
@ -412,7 +415,8 @@ def get_previous_sle(args, for_update=False):
|
|||||||
sle = get_stock_ledger_entries(args, "<=", "desc", "limit 1", for_update=for_update)
|
sle = get_stock_ledger_entries(args, "<=", "desc", "limit 1", for_update=for_update)
|
||||||
return sle and sle[0] or {}
|
return sle and sle[0] or {}
|
||||||
|
|
||||||
def get_stock_ledger_entries(previous_sle, operator=None, order="desc", limit=None, for_update=False, debug=False):
|
def get_stock_ledger_entries(previous_sle, operator=None,
|
||||||
|
order="desc", limit=None, for_update=False, debug=False, check_serial_no=True):
|
||||||
"""get stock ledger entries filtered by specific posting datetime conditions"""
|
"""get stock ledger entries filtered by specific posting datetime conditions"""
|
||||||
conditions = " and timestamp(posting_date, posting_time) {0} timestamp(%(posting_date)s, %(posting_time)s)".format(operator)
|
conditions = " and timestamp(posting_date, posting_time) {0} timestamp(%(posting_date)s, %(posting_time)s)".format(operator)
|
||||||
if previous_sle.get("warehouse"):
|
if previous_sle.get("warehouse"):
|
||||||
@ -420,6 +424,9 @@ def get_stock_ledger_entries(previous_sle, operator=None, order="desc", limit=No
|
|||||||
elif previous_sle.get("warehouse_condition"):
|
elif previous_sle.get("warehouse_condition"):
|
||||||
conditions += " and " + previous_sle.get("warehouse_condition")
|
conditions += " and " + previous_sle.get("warehouse_condition")
|
||||||
|
|
||||||
|
if check_serial_no and previous_sle.get("serial_no"):
|
||||||
|
conditions += " and serial_no like {}".format(frappe.db.escape('%{0}%'.format(previous_sle.get("serial_no"))))
|
||||||
|
|
||||||
if not previous_sle.get("posting_date"):
|
if not previous_sle.get("posting_date"):
|
||||||
previous_sle["posting_date"] = "1900-01-01"
|
previous_sle["posting_date"] = "1900-01-01"
|
||||||
if not previous_sle.get("posting_time"):
|
if not previous_sle.get("posting_time"):
|
||||||
@ -479,6 +486,7 @@ def get_valuation_rate(item_code, warehouse, voucher_type, voucher_no,
|
|||||||
if not allow_zero_rate and not valuation_rate and raise_error_if_no_rate \
|
if not allow_zero_rate and not valuation_rate and raise_error_if_no_rate \
|
||||||
and cint(erpnext.is_perpetual_inventory_enabled(company)):
|
and cint(erpnext.is_perpetual_inventory_enabled(company)):
|
||||||
frappe.local.message_log = []
|
frappe.local.message_log = []
|
||||||
frappe.throw(_("Valuation rate not found for the Item {0}, which is required to do accounting entries for {1} {2}. If the item is transacting as a zero valuation rate item in the {1}, please mention that in the {1} Item table. Otherwise, please create an incoming stock transaction for the item or mention valuation rate in the Item record, and then try submiting/cancelling this entry").format(item_code, voucher_type, voucher_no))
|
frappe.throw(_("Valuation rate not found for the Item {0}, which is required to do accounting entries for {1} {2}. If the item is transacting as a zero valuation rate item in the {1}, please mention that in the {1} Item table. Otherwise, please create an incoming stock transaction for the item or mention valuation rate in the Item record, and then try submiting / cancelling this entry.")
|
||||||
|
.format(item_code, voucher_type, voucher_no))
|
||||||
|
|
||||||
return valuation_rate
|
return valuation_rate
|
||||||
|
@ -173,7 +173,7 @@ def get_incoming_rate(args, raise_error_if_no_rate=True):
|
|||||||
in_rate = get_valuation_rate(args.get('item_code'), args.get('warehouse'),
|
in_rate = get_valuation_rate(args.get('item_code'), args.get('warehouse'),
|
||||||
args.get('voucher_type'), voucher_no, args.get('allow_zero_valuation'),
|
args.get('voucher_type'), voucher_no, args.get('allow_zero_valuation'),
|
||||||
currency=erpnext.get_company_currency(args.get('company')), company=args.get('company'),
|
currency=erpnext.get_company_currency(args.get('company')), company=args.get('company'),
|
||||||
raise_error_if_no_rate=True)
|
raise_error_if_no_rate=raise_error_if_no_rate)
|
||||||
|
|
||||||
return in_rate
|
return in_rate
|
||||||
|
|
||||||
@ -277,3 +277,7 @@ def update_included_uom_in_report(columns, result, include_uom, conversion_facto
|
|||||||
new_row.append(None)
|
new_row.append(None)
|
||||||
|
|
||||||
result[row_idx] = new_row
|
result[row_idx] = new_row
|
||||||
|
|
||||||
|
def get_available_serial_nos(item_code, warehouse):
|
||||||
|
return frappe.get_all("Serial No", filters = {'item_code': item_code,
|
||||||
|
'warehouse': warehouse, 'delivery_document_no': ''}) or []
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user