diff --git a/accounts/doctype/purchase_invoice/purchase_invoice_list.js b/accounts/doctype/purchase_invoice/purchase_invoice_list.js index a3f667f2126..7b410a3085c 100644 --- a/accounts/doctype/purchase_invoice/purchase_invoice_list.js +++ b/accounts/doctype/purchase_invoice/purchase_invoice_list.js @@ -1,9 +1,9 @@ // render wn.listview_settings['Purchase Invoice'] = { add_fields: ["`tabPurchase Invoice`.grand_total", "`tabPurchase Invoice`.outstanding_amount"], - add_columns: [{"content":"outstanding_amount", width:"10%", type:"bar-graph", label: "Paid"}], + add_columns: [{"content":"paid_amount", width:"10%", type:"bar-graph", label: "Paid"}], prepare_data: function(data) { - data.outstanding_amount = ((flt(data.grand_total) - - flt(data.outstanding_amount)) / flt(data.grand_total)) * 100; + data.paid_amount = flt(data.grand_total) ? (((flt(data.grand_total) - + flt(data.outstanding_amount)) / flt(data.grand_total)) * 100) : 0; } }; diff --git a/accounts/doctype/sales_invoice/sales_invoice.js b/accounts/doctype/sales_invoice/sales_invoice.js index 7863306de1a..be6ec3d0018 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.js +++ b/accounts/doctype/sales_invoice/sales_invoice.js @@ -159,7 +159,6 @@ cur_frm.cscript.update_stock = function(doc, dt, dn) { cur_frm.cscript.hide_fields(doc, dt, dn); } - cur_frm.cscript.warehouse = function(doc, cdt , cdn) { var d = locals[cdt][cdn]; if (!d.item_code) { msgprint("please enter item code first"); return }; diff --git a/accounts/doctype/sales_invoice/sales_invoice.txt b/accounts/doctype/sales_invoice/sales_invoice.txt index 442e665d0a7..d15f2a9b458 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.txt +++ b/accounts/doctype/sales_invoice/sales_invoice.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-04-09 10:18:11", + "creation": "2013-04-19 11:00:14", "docstatus": 0, - "modified": "2013-03-22 18:38:13", + "modified": "2013-04-22 11:59:28", "modified_by": "Administrator", "owner": "Administrator" }, @@ -42,7 +42,8 @@ "fieldtype": "Section Break", "label": "Basic Info", "oldfieldtype": "Section Break", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -50,6 +51,7 @@ "fieldtype": "Column Break", "oldfieldtype": "Column Break", "print_hide": 0, + "read_only": 0, "width": "50%" }, { @@ -63,6 +65,7 @@ "oldfieldtype": "Select", "options": "INV\nINV/10-11/", "print_hide": 1, + "read_only": 0, "reqd": 1 }, { @@ -72,7 +75,8 @@ "label": "Is POS", "oldfieldname": "is_pos", "oldfieldtype": "Check", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "depends_on": "eval:doc.is_pos==1", @@ -82,7 +86,8 @@ "label": "Update Stock", "oldfieldname": "update_stock", "oldfieldtype": "Check", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "description": "The account to which you will pay (have paid) the money to.", @@ -95,6 +100,7 @@ "oldfieldtype": "Link", "options": "Account", "print_hide": 1, + "read_only": 0, "reqd": 1, "search_index": 1 }, @@ -108,7 +114,8 @@ "oldfieldname": "customer", "oldfieldtype": "Link", "options": "Customer", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -158,7 +165,8 @@ "doctype": "DocField", "fieldname": "column_break1", "fieldtype": "Column Break", - "oldfieldtype": "Column Break" + "oldfieldtype": "Column Break", + "read_only": 0 }, { "default": "Today", @@ -172,6 +180,7 @@ "oldfieldname": "posting_date", "oldfieldtype": "Date", "print_hide": 0, + "read_only": 0, "reqd": 1, "search_index": 1 }, @@ -186,6 +195,7 @@ "no_copy": 1, "oldfieldname": "due_date", "oldfieldtype": "Date", + "read_only": 0, "reqd": 1, "search_index": 0 }, @@ -196,14 +206,16 @@ "label": "Mode of Payment", "oldfieldname": "mode_of_payment", "oldfieldtype": "Select", - "options": "link:Mode of Payment" + "options": "link:Mode of Payment", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "items", "fieldtype": "Section Break", "label": "Items", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "read_only": 0 }, { "allow_on_submit": 1, @@ -213,25 +225,29 @@ "label": "Entries", "oldfieldname": "entries", "oldfieldtype": "Table", - "options": "Sales Invoice Item" + "options": "Sales Invoice Item", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "sales_bom_help", "fieldtype": "HTML", "label": "Sales BOM Help", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", "fieldname": "section_break0", "fieldtype": "Section Break", - "options": "Simple" + "options": "Simple", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "col_break26", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -253,12 +269,14 @@ "fieldtype": "Button", "label": "Re-Calculate Values", "oldfieldtype": "Button", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", "fieldname": "col_break25", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -270,7 +288,8 @@ "oldfieldname": "sales_order_main", "oldfieldtype": "Link", "options": "Sales Order", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "description": "Select Items from Delivery Note", @@ -281,7 +300,8 @@ "oldfieldname": "delivery_note_main", "oldfieldtype": "Link", "options": "Delivery Note", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -289,18 +309,21 @@ "fieldtype": "Button", "label": "Get Items", "oldfieldtype": "Button", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", "fieldname": "currency_section", "fieldtype": "Section Break", - "label": "Price List and Currency" + "label": "Price List and Currency", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "col_break27", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -312,6 +335,7 @@ "oldfieldtype": "Select", "options": "link:Price List", "print_hide": 1, + "read_only": 0, "reqd": 1 }, { @@ -322,6 +346,7 @@ "label": "Price List Currency", "options": "Currency", "print_hide": 1, + "read_only": 0, "reqd": 1 }, { @@ -331,12 +356,14 @@ "fieldtype": "Float", "label": "Price List Currency Conversion Rate", "print_hide": 1, + "read_only": 0, "reqd": 1 }, { "doctype": "DocField", "fieldname": "column_break2", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -348,6 +375,7 @@ "oldfieldtype": "Select", "options": "Currency", "print_hide": 1, + "read_only": 0, "reqd": 1 }, { @@ -360,6 +388,7 @@ "oldfieldname": "conversion_rate", "oldfieldtype": "Currency", "print_hide": 1, + "read_only": 0, "reqd": 1 }, { @@ -367,7 +396,8 @@ "fieldname": "taxes", "fieldtype": "Section Break", "label": "Taxes and Charges", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "read_only": 0 }, { "doctype": "DocField", @@ -377,7 +407,8 @@ "oldfieldname": "charge", "oldfieldtype": "Link", "options": "Sales Taxes and Charges Master", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -385,7 +416,8 @@ "fieldtype": "Button", "label": "Get Taxes and Charges", "oldfieldtype": "Button", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "allow_on_submit": 1, @@ -395,7 +427,8 @@ "label": "Taxes and Charges1", "oldfieldname": "other_charges", "oldfieldtype": "Table", - "options": "Sales Taxes and Charges" + "options": "Sales Taxes and Charges", + "read_only": 0 }, { "doctype": "DocField", @@ -403,7 +436,8 @@ "fieldtype": "Button", "label": "Calculate Taxes and Charges", "oldfieldtype": "Button", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -422,7 +456,8 @@ "fieldtype": "HTML", "label": "Taxes and Charges Calculation", "oldfieldtype": "HTML", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -430,7 +465,8 @@ "fieldtype": "Section Break", "label": "Totals", "oldfieldtype": "Section Break", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -438,6 +474,7 @@ "fieldtype": "Column Break", "oldfieldtype": "Column Break", "print_hide": 1, + "read_only": 0, "width": "50%" }, { @@ -506,6 +543,7 @@ "fieldtype": "Column Break", "oldfieldtype": "Column Break", "print_hide": 1, + "read_only": 0, "width": "50%" }, { @@ -567,12 +605,14 @@ "doctype": "DocField", "fieldname": "payments_section", "fieldtype": "Section Break", - "label": "Payments" + "label": "Payments", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "column_break3", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -583,7 +623,8 @@ "oldfieldname": "paid_amount", "oldfieldtype": "Currency", "options": "Company:company:default_currency", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -593,12 +634,14 @@ "oldfieldname": "cash_bank_account", "oldfieldtype": "Link", "options": "Account", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", "fieldname": "column_break4", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -606,7 +649,8 @@ "fieldname": "write_off_outstanding_amount_automatically", "fieldtype": "Check", "label": "Write Off Outstanding Amount", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -614,7 +658,8 @@ "fieldtype": "Currency", "label": "Write Off Amount", "options": "Company:company:default_currency", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -622,7 +667,8 @@ "fieldtype": "Link", "label": "Write Off Account", "options": "Account", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -630,14 +676,16 @@ "fieldtype": "Link", "label": "Write Off Cost Center", "options": "Cost Center", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", "fieldname": "terms_section_break", "fieldtype": "Section Break", "label": "Terms and Conditions", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "read_only": 0 }, { "doctype": "DocField", @@ -647,7 +695,8 @@ "oldfieldname": "tc_name", "oldfieldtype": "Link", "options": "Terms and Conditions", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -656,7 +705,8 @@ "label": "Get Terms and Conditions", "oldfieldtype": "Button", "options": "get_tc_details", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -665,7 +715,8 @@ "label": "Terms and Conditions HTML", "oldfieldtype": "HTML", "options": "You can add Terms and Notes that will be printed in the Transaction", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -673,18 +724,21 @@ "fieldtype": "Text Editor", "label": "Terms and Conditions Details", "oldfieldname": "terms", - "oldfieldtype": "Text Editor" + "oldfieldtype": "Text Editor", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "contact_section", "fieldtype": "Section Break", - "label": "Contact Info" + "label": "Contact Info", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "col_break23", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -693,7 +747,8 @@ "fieldtype": "Link", "label": "Customer Address", "options": "Address", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -701,12 +756,14 @@ "fieldtype": "Link", "label": "Contact Person", "options": "Contact", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", "fieldname": "col_break24", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -717,6 +774,7 @@ "label": "Territory", "options": "Territory", "print_hide": 1, + "read_only": 0, "reqd": 1, "search_index": 0 }, @@ -728,6 +786,7 @@ "label": "Customer Group", "options": "Customer Group", "print_hide": 1, + "read_only": 0, "search_index": 0 }, { @@ -736,7 +795,8 @@ "fieldtype": "Section Break", "label": "More Info", "oldfieldtype": "Section Break", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -744,6 +804,7 @@ "fieldtype": "Column Break", "oldfieldtype": "Column Break", "print_hide": 1, + "read_only": 0, "width": "50%" }, { @@ -758,6 +819,7 @@ "oldfieldtype": "Select", "options": "No\nYes", "print_hide": 1, + "read_only": 0, "search_index": 0 }, { @@ -768,7 +830,8 @@ "label": "Aging Date", "oldfieldname": "aging_date", "oldfieldtype": "Date", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -778,7 +841,8 @@ "no_copy": 1, "oldfieldname": "posting_time", "oldfieldtype": "Time", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "allow_on_submit": 1, @@ -789,7 +853,8 @@ "oldfieldname": "letter_head", "oldfieldtype": "Select", "options": "link:Letter Head", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -799,6 +864,7 @@ "no_copy": 1, "options": "No\nYes", "print_hide": 1, + "read_only": 0, "report_hide": 0 }, { @@ -820,7 +886,8 @@ "oldfieldname": "campaign", "oldfieldtype": "Link", "options": "Campaign", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "description": "Track this Sales Invoice against any Project", @@ -832,6 +899,7 @@ "oldfieldname": "project_name", "oldfieldtype": "Link", "options": "Project", + "read_only": 0, "search_index": 1 }, { @@ -845,6 +913,7 @@ "oldfieldtype": "Link", "options": "Print Heading", "print_hide": 1, + "read_only": 0, "report_hide": 1 }, { @@ -852,7 +921,8 @@ "fieldname": "column_break8", "fieldtype": "Column Break", "oldfieldtype": "Column Break", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -862,7 +932,8 @@ "oldfieldname": "source", "oldfieldtype": "Select", "options": "\nExisting Customer\nReference\nAdvertisement\nCold Calling\nExhibition\nSupplier Reference\nMass Mailing\nCustomer's Vendor\nCampaign", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -874,6 +945,7 @@ "oldfieldtype": "Link", "options": "Company", "print_hide": 1, + "read_only": 0, "reqd": 1, "search_index": 0 }, @@ -888,6 +960,7 @@ "oldfieldtype": "Select", "options": "link:Fiscal Year", "print_hide": 1, + "read_only": 0, "reqd": 1, "search_index": 0 }, @@ -912,7 +985,8 @@ "no_copy": 1, "oldfieldname": "amendment_date", "oldfieldtype": "Date", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "depends_on": "eval:!doc.__islocal", @@ -934,6 +1008,7 @@ "oldfieldname": "remarks", "oldfieldtype": "Text", "print_hide": 1, + "read_only": 0, "reqd": 0 }, { @@ -942,7 +1017,8 @@ "fieldtype": "Section Break", "label": "Advances", "oldfieldtype": "Section Break", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -951,7 +1027,8 @@ "label": "Get Advances Received", "oldfieldtype": "Button", "options": "get_advances", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -961,14 +1038,16 @@ "oldfieldname": "advance_adjustment_details", "oldfieldtype": "Table", "options": "Sales Invoice Advance", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", "fieldname": "packing_list", "fieldtype": "Section Break", "label": "Packing List", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -976,7 +1055,8 @@ "fieldtype": "Table", "label": "Packing Details", "options": "Delivery Note Packing Item", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -984,7 +1064,8 @@ "fieldtype": "Section Break", "label": "Sales Team", "oldfieldtype": "Section Break", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -992,6 +1073,7 @@ "fieldtype": "Column Break", "oldfieldtype": "Column Break", "print_hide": 1, + "read_only": 0, "width": "50%" }, { @@ -1003,7 +1085,8 @@ "oldfieldname": "sales_partner", "oldfieldtype": "Link", "options": "Sales Partner", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -1011,6 +1094,7 @@ "fieldtype": "Column Break", "oldfieldtype": "Column Break", "print_hide": 1, + "read_only": 0, "width": "50%" }, { @@ -1020,7 +1104,8 @@ "label": "Commission Rate (%)", "oldfieldname": "commission_rate", "oldfieldtype": "Currency", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -1030,14 +1115,16 @@ "oldfieldname": "total_commission", "oldfieldtype": "Currency", "options": "Company:company:default_currency", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", "fieldname": "section_break2", "fieldtype": "Section Break", "options": "Simple", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -1047,7 +1134,8 @@ "oldfieldname": "sales_team", "oldfieldtype": "Table", "options": "Sales Team", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "depends_on": "eval:doc.docstatus<2", @@ -1055,13 +1143,15 @@ "fieldname": "recurring_invoice", "fieldtype": "Section Break", "label": "Recurring Invoice", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", "fieldname": "column_break11", "fieldtype": "Column Break", "print_hide": 1, + "read_only": 0, "width": "50%" }, { @@ -1073,7 +1163,8 @@ "fieldtype": "Check", "label": "Convert into Recurring Invoice", "no_copy": 1, - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "allow_on_submit": 1, @@ -1085,7 +1176,8 @@ "label": "Recurring Type", "no_copy": 1, "options": "Monthly\nQuarterly\nHalf-yearly\nYearly", - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "allow_on_submit": 1, @@ -1096,7 +1188,8 @@ "fieldtype": "Int", "label": "Repeat on Day of Month", "no_copy": 1, - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "allow_on_submit": 1, @@ -1107,7 +1200,8 @@ "fieldtype": "Date", "label": "Invoice Period From Date", "no_copy": 1, - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "allow_on_submit": 1, @@ -1118,7 +1212,8 @@ "fieldtype": "Date", "label": "Invoice Period To Date", "no_copy": 1, - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -1126,6 +1221,7 @@ "fieldtype": "Column Break", "no_copy": 0, "print_hide": 1, + "read_only": 0, "width": "50%" }, { @@ -1137,7 +1233,8 @@ "fieldtype": "Small Text", "label": "Notification Email Address", "no_copy": 1, - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "depends_on": "eval:doc.convert_into_recurring_invoice==1", @@ -1170,7 +1267,8 @@ "fieldtype": "Date", "label": "End Date", "no_copy": 1, - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", @@ -1182,20 +1280,9 @@ "oldfieldname": "against_income_account", "oldfieldtype": "Small Text", "print_hide": 1, + "read_only": 0, "report_hide": 1 }, - { - "amend": 0, - "cancel": 0, - "create": 0, - "doctype": "DocPerm", - "match": "", - "permlevel": 1, - "report": 0, - "role": "Accounts Manager", - "submit": 0, - "write": 0 - }, { "amend": 1, "cancel": 1, @@ -1203,43 +1290,15 @@ "doctype": "DocPerm", "permlevel": 0, "report": 1, - "role": "Accounts Manager", - "submit": 1, - "write": 1 - }, - { - "amend": 1, - "cancel": 0, - "create": 1, - "doctype": "DocPerm", - "permlevel": 0, - "report": 1, "role": "Accounts User", "submit": 1, "write": 1 }, - { - "amend": 0, - "cancel": 0, - "create": 0, - "doctype": "DocPerm", - "match": "", - "permlevel": 1, - "report": 0, - "role": "Accounts User", - "submit": 0, - "write": 0 - }, { "doctype": "DocPerm", "match": "customer", "permlevel": 0, "report": 1, "role": "Customer" - }, - { - "doctype": "DocPerm", - "permlevel": 0, - "role": "Retail User" } ] \ No newline at end of file diff --git a/accounts/doctype/sales_invoice/sales_invoice_list.js b/accounts/doctype/sales_invoice/sales_invoice_list.js index c1f80616659..e83611aff05 100644 --- a/accounts/doctype/sales_invoice/sales_invoice_list.js +++ b/accounts/doctype/sales_invoice/sales_invoice_list.js @@ -1,9 +1,10 @@ // render wn.listview_settings['Sales Invoice'] = { add_fields: ["`tabSales Invoice`.grand_total", "`tabSales Invoice`.outstanding_amount"], - add_columns: [{"content":"outstanding_amount", width:"10%", type:"bar-graph"}], + add_columns: [{"content":"paid_amount", width:"10%", type:"bar-graph", + label: "Payment Received"}], prepare_data: function(data) { - data.outstanding_amount = (flt(data.grand_total) - - flt(data.outstanding_amount)) / flt(data.grand_total) * 100; + data.paid_amount = flt(data.grand_total) ? (((flt(data.grand_total) - + flt(data.outstanding_amount)) / flt(data.grand_total)) * 100) : 0; } }; diff --git a/accounts/page/accounts_home/accounts_home.js b/accounts/page/accounts_home/accounts_home.js index 9981ee9a974..3e9ea9243cc 100644 --- a/accounts/page/accounts_home/accounts_home.js +++ b/accounts/page/accounts_home/accounts_home.js @@ -139,6 +139,16 @@ wn.module_page["Accounts"] = [ "page":"Financial Statements", "label": wn._("Financial Statements") }, + { + "label":wn._("Accounts Receivable"), + route: "query-report/Accounts Receivable", + doctype: "Sales Invoice" + }, + { + "label":wn._("Accounts Payable"), + route: "query-report/Accounts Payable", + doctype: "Purchase Invoice" + }, ] }, { diff --git a/accounts/report/accounts_payable/__init__.py b/accounts/report/accounts_payable/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/accounts/report/accounts_payable/accounts_payable.js b/accounts/report/accounts_payable/accounts_payable.js new file mode 100644 index 00000000000..7ee38f2f310 --- /dev/null +++ b/accounts/report/accounts_payable/accounts_payable.js @@ -0,0 +1,42 @@ +wn.query_reports["Accounts Payable"] = { + "filters": [ + { + "fieldname":"company", + "label": "Company", + "fieldtype": "Link", + "options": "Company", + "default": sys_defaults.company + }, + { + "fieldname":"account", + "label": "Account", + "fieldtype": "Link", + "options": "Account", + "get_query": function() { + var company = wn.query_report.filters_by_name.company.get_value(); + return { + "query": "accounts.utils.get_account_list", + "filters": { + "is_pl_account": "No", + "debit_or_credit": "Credit", + "company": company, + "master_type": "Supplier" + } + } + } + }, + { + "fieldname":"report_date", + "label": "Date", + "fieldtype": "Date", + "default": get_today() + }, + { + "fieldname":"ageing_based_on", + "label": "Ageing Based On", + "fieldtype": "Select", + "options": 'Posting Date' + NEWLINE + 'Due Date', + "default": "Posting Date" + } + ] +} \ No newline at end of file diff --git a/accounts/report/accounts_payable/accounts_payable.py b/accounts/report/accounts_payable/accounts_payable.py new file mode 100644 index 00000000000..34c8ccd2be2 --- /dev/null +++ b/accounts/report/accounts_payable/accounts_payable.py @@ -0,0 +1,152 @@ +from __future__ import unicode_literals +import webnotes +from webnotes.utils import getdate, nowdate, flt, cstr + +def execute(filters=None): + if not filters: filters = {} + columns = get_columns() + + entries = get_gl_entries(filters) + + entries_after_report_date = [[gle.voucher_type, gle.voucher_no] + for gle in get_gl_entries(filters, before_report_date=False)] + + account_supplier_type_map = get_account_supplier_type_map() + pi_map = get_pi_map() + + # Age of the invoice on this date + age_on = getdate(filters.get("report_date")) > getdate(nowdate()) \ + and nowdate() or filters.get("report_date") + + data = [] + total_invoiced_amount = total_paid = total_outstanding = 0 + for gle in entries: + if cstr(gle.against_voucher) == gle.voucher_no or not gle.against_voucher \ + or [gle.against_voucher_type, gle.against_voucher] in entries_after_report_date: + + if gle.voucher_type == "Purchase Invoice": + pi_info = pi_map.get(gle.voucher_no) + due_date = pi_info.get("due_date") + bill_no = pi_info.get("bill_no") + bill_date = pi_info.get("bill_date") + else: + due_date = bill_no = bill_date = "" + + invoiced_amount = gle.credit > 0 and gle.credit or 0 + paid_amount = get_paid_amount(gle, filters.get("report_date") or nowdate(), + entries_after_report_date) + outstanding_amount = invoiced_amount - paid_amount + + if abs(flt(outstanding_amount)) > 0.01: + row = [gle.posting_date, gle.account, gle.voucher_type, gle.voucher_no, + gle.remarks, account_supplier_type_map.get(gle.account), due_date, bill_no, + bill_date, invoiced_amount, paid_amount, outstanding_amount] + + # Ageing + if filters.get("ageing_based_on") == "Due Date": + ageing_based_on_date = due_date + else: + ageing_based_on_date = gle.posting_date + row += get_ageing_data(ageing_based_on_date, age_on, outstanding_amount) + + # Add to total + total_invoiced_amount += flt(invoiced_amount) + total_paid += flt(paid_amount) + total_outstanding += flt(outstanding_amount) + data.append(row) + if data: + data.append(["", "", "", "", "", "", "", "Total", "", total_invoiced_amount, total_paid, + total_outstanding, "", "", "", ""]) + + return columns, data + +def get_columns(): + return [ + "Posting Date:Date:80", "Account:Link/Account:150", "Voucher Type::110", + "Voucher No::120", "Remarks::150", "Supplier Type:Link/Supplier Type:120", + "Due Date:Date:80", "Bill No::80", "Bill Date:Date:80", + "Invoiced Amount:Currency:100", "Paid Amount:Currency:100", + "Outstanding Amount:Currency:100", "Age:Int:50", "0-30:Currency:100", + "30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100" + ] + +def get_gl_entries(filters, before_report_date=True): + conditions, supplier_accounts = get_conditions(filters, before_report_date) + gl_entries = [] + gl_entries = webnotes.conn.sql("""select * from `tabGL Entry` + where ifnull(is_cancelled, 'No') = 'No' %s order by posting_date, account""" % + (conditions) % (", ".join(['%s']*len(supplier_accounts))), + tuple(supplier_accounts), as_dict=1) + return gl_entries + +def get_conditions(filters, before_report_date=True): + conditions = "" + if filters.get("company"): + conditions += " and company='%s'" % filters["company"] + + supplier_accounts = [] + if filters.get("account"): + supplier_accounts = [filters["account"]] + elif filters.get("company"): + supplier_accounts = webnotes.conn.sql_list("""select name from `tabAccount` + where ifnull(master_type, '') = 'Supplier' and docstatus < 2 %s""" % + conditions, filters) + + if supplier_accounts: + conditions += " and account in (%s)" + + if filters.get("report_date"): + if before_report_date: + conditions += " and posting_date<='%s'" % filters["report_date"] + else: + conditions += " and posting_date>'%s'" % filters["report_date"] + + return conditions, supplier_accounts + +def get_account_supplier_type_map(): + account_supplier_type_map = {} + for each in webnotes.conn.sql("""select t2.name, t1.supplier_type from `tabSupplier` t1, + `tabAccount` t2 where t1.name = t2.master_name group by t2.name"""): + account_supplier_type_map[each[0]] = each[1] + + return account_supplier_type_map + +def get_pi_map(): + """ get due_date from sales invoice """ + pi_map = {} + for t in webnotes.conn.sql("""select name, due_date, bill_no, bill_date + from `tabPurchase Invoice`""", as_dict=1): + pi_map[t.name] = t + + return pi_map + +def get_paid_amount(gle, report_date, entries_after_report_date): + + paid_amount = 0 + if flt(gle.debit) > 0 and (not gle.against_voucher or + [gle.against_voucher_type, gle.against_voucher] in entries_after_report_date): + paid_amount = gle.debit + elif flt(gle.credit) > 0: + paid_amount = webnotes.conn.sql(""" + select sum(ifnull(debit, 0)) - sum(ifnull(credit, 0)) from `tabGL Entry` + where account = %s and posting_date <= %s and against_voucher_type = %s + and against_voucher = %s and name != %s and ifnull(is_cancelled, 'No') = 'No'""", + (gle.account, report_date, gle.voucher_type, gle.voucher_no, gle.name))[0][0] + + return flt(paid_amount) + +def get_ageing_data(ageing_based_on_date, age_on, outstanding_amount): + val1 = val2 = val3 = val4 = diff = 0 + diff = age_on and ageing_based_on_date \ + and (getdate(age_on) - getdate(ageing_based_on_date)).days or 0 + + if diff <= 30: + val1 = outstanding_amount + elif 30 < diff <= 60: + val2 = outstanding_amount + elif 60 < diff <= 90: + val3 = outstanding_amount + elif diff > 90: + val4 = outstanding_amount + + return [diff, val1, val2, val3, val4] \ No newline at end of file diff --git a/accounts/report/accounts_payable/accounts_payable.txt b/accounts/report/accounts_payable/accounts_payable.txt new file mode 100644 index 00000000000..8920a0bf2ee --- /dev/null +++ b/accounts/report/accounts_payable/accounts_payable.txt @@ -0,0 +1,21 @@ +[ + { + "creation": "2013-04-22 16:16:03", + "docstatus": 0, + "modified": "2013-04-23 14:54:27", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Purchase Invoice", + "report_name": "Accounts Payable", + "report_type": "Report Builder" + }, + { + "doctype": "Report", + "name": "Accounts Payable" + } +] \ No newline at end of file diff --git a/accounts/report/accounts_receivable/__init__.py b/accounts/report/accounts_receivable/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/accounts/report/accounts_receivable/accounts_receivable.js b/accounts/report/accounts_receivable/accounts_receivable.js new file mode 100644 index 00000000000..68c8593dd67 --- /dev/null +++ b/accounts/report/accounts_receivable/accounts_receivable.js @@ -0,0 +1,42 @@ +wn.query_reports["Accounts Receivable"] = { + "filters": [ + { + "fieldname":"company", + "label": "Company", + "fieldtype": "Link", + "options": "Company", + "default": sys_defaults.company + }, + { + "fieldname":"account", + "label": "Account", + "fieldtype": "Link", + "options": "Account", + "get_query": function() { + var company = wn.query_report.filters_by_name.company.get_value(); + return { + "query": "accounts.utils.get_account_list", + "filters": { + "is_pl_account": "No", + "debit_or_credit": "Debit", + "company": company, + "master_type": "Customer" + } + } + } + }, + { + "fieldname":"report_date", + "label": "Date", + "fieldtype": "Date", + "default": get_today() + }, + { + "fieldname":"ageing_based_on", + "label": "Ageing Based On", + "fieldtype": "Select", + "options": 'Posting Date' + NEWLINE + 'Due Date', + "default": "Posting Date" + } + ] +} \ No newline at end of file diff --git a/accounts/report/accounts_receivable/accounts_receivable.py b/accounts/report/accounts_receivable/accounts_receivable.py new file mode 100644 index 00000000000..d385b36b902 --- /dev/null +++ b/accounts/report/accounts_receivable/accounts_receivable.py @@ -0,0 +1,141 @@ +from __future__ import unicode_literals +import webnotes +from webnotes.utils import getdate, nowdate, flt, cstr + +def execute(filters=None): + if not filters: filters = {} + columns = get_columns() + entries = get_gl_entries(filters) + + entries_after_report_date = [[gle.voucher_type, gle.voucher_no] + for gle in get_gl_entries(filters, upto_report_date=False)] + + account_territory_map = get_account_territory_map() + si_due_date_map = get_si_due_date_map() + + # Age of the invoice on this date + age_on = getdate(filters.get("report_date")) > getdate(nowdate()) \ + and nowdate() or filters.get("report_date") + + data = [] + total_invoiced_amount = total_payment = total_outstanding = 0 + for gle in entries: + if cstr(gle.against_voucher) == gle.voucher_no or not gle.against_voucher \ + or [gle.against_voucher_type, gle.against_voucher] in entries_after_report_date: + + due_date = (gle.voucher_type == "Sales Invoice") \ + and si_due_date_map.get(gle.voucher_no) or "" + + invoiced_amount = gle.debit > 0 and gle.debit or 0 + payment_amount = get_payment_amount(gle, filters.get("report_date") or nowdate(), + entries_after_report_date) + outstanding_amount = invoiced_amount - payment_amount + + if abs(flt(outstanding_amount)) > 0.01: + row = [gle.posting_date, gle.account, gle.voucher_type, gle.voucher_no, + gle.remarks, due_date, account_territory_map.get(gle.account), + invoiced_amount, payment_amount, outstanding_amount] + # Ageing + if filters.get("ageing_based_on") == "Due Date": + ageing_based_on_date = due_date + else: + ageing_based_on_date = gle.posting_date + row += get_ageing_data(ageing_based_on_date, age_on, outstanding_amount) + + # Add to total + total_invoiced_amount += flt(invoiced_amount) + total_payment += flt(payment_amount) + total_outstanding += flt(outstanding_amount) + + data.append(row) + if data: + data.append(["", "", "", "", "", "", "Total", total_invoiced_amount, total_payment, + total_outstanding, "", "", "", ""]) + + return columns, data + +def get_columns(): + return [ + "Posting Date:Date:80", "Account:Link/Account:150", "Voucher Type::110", + "Voucher No::120", "Remarks::150", "Due Date:Date:80", "Territory:Link/Territory:80", + "Invoiced Amount:Currency:100", "Payment Received:Currency:100", + "Outstanding Amount:Currency:100", "Age:Int:50", "0-30:Currency:100", + "30-60:Currency:100", "60-90:Currency:100", "90-Above:Currency:100" + ] + +def get_gl_entries(filters, upto_report_date=True): + conditions, customer_accounts = get_conditions(filters, upto_report_date) + return webnotes.conn.sql("""select * from `tabGL Entry` + where ifnull(is_cancelled, 'No') = 'No' %s order by posting_date, account""" % + (conditions) % (", ".join(['%s']*len(customer_accounts))), + tuple(customer_accounts), as_dict=1) + +def get_conditions(filters, upto_report_date=True): + conditions = "" + if filters.get("company"): + conditions += " and company='%s'" % filters["company"] + + customer_accounts = [] + if filters.get("account"): + customer_accounts = [filters["account"]] + elif filters.get("company"): + customer_accounts = webnotes.conn.sql_list("""select name from `tabAccount` + where ifnull(master_type, '') = 'Customer' and docstatus < 2 %s""" % + conditions, filters) + + if customer_accounts: + conditions += " and account in (%s)" + + if filters.get("report_date"): + if upto_report_date: + conditions += " and posting_date<='%s'" % filters["report_date"] + else: + conditions += " and posting_date>'%s'" % filters["report_date"] + + return conditions, customer_accounts + +def get_account_territory_map(): + account_territory_map = {} + for each in webnotes.conn.sql("""select t2.name, t1.territory from `tabCustomer` t1, + `tabAccount` t2 where t1.name = t2.master_name"""): + account_territory_map[each[0]] = each[1] + + return account_territory_map + +def get_si_due_date_map(): + """ get due_date from sales invoice """ + si_due_date_map = {} + for t in webnotes.conn.sql("""select name, due_date from `tabSales Invoice` group by name"""): + si_due_date_map[t[0]] = t[1] + + return si_due_date_map + +def get_payment_amount(gle, report_date, entries_after_report_date): + payment_amount = 0 + if flt(gle.credit) > 0 and (not gle.against_voucher or + [gle.against_voucher_type, gle.against_voucher] in entries_after_report_date): + payment_amount = gle.credit + elif flt(gle.debit) > 0: + payment_amount = webnotes.conn.sql(""" + select sum(ifnull(credit, 0)) - sum(ifnull(debit, 0)) from `tabGL Entry` + where account = %s and posting_date <= %s and against_voucher_type = %s + and against_voucher = %s and name != %s and ifnull(is_cancelled, 'No') = 'No'""", + (gle.account, report_date, gle.voucher_type, gle.voucher_no, gle.name))[0][0] + + return flt(payment_amount) + +def get_ageing_data(ageing_based_on_date, age_on, outstanding_amount): + val1 = val2 = val3 = val4 = diff = 0 + diff = age_on and ageing_based_on_date \ + and (getdate(age_on) - getdate(ageing_based_on_date)).days or 0 + + if diff <= 30: + val1 = outstanding_amount + elif 30 < diff <= 60: + val2 = outstanding_amount + elif 60 < diff <= 90: + val3 = outstanding_amount + elif diff > 90: + val4 = outstanding_amount + + return [diff, val1, val2, val3, val4] \ No newline at end of file diff --git a/accounts/report/accounts_receivable/accounts_receivable.txt b/accounts/report/accounts_receivable/accounts_receivable.txt new file mode 100644 index 00000000000..28f7e4f44dd --- /dev/null +++ b/accounts/report/accounts_receivable/accounts_receivable.txt @@ -0,0 +1,21 @@ +[ + { + "creation": "2013-04-16 11:31:13", + "docstatus": 0, + "modified": "2013-04-16 11:31:13", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Sales Invoice", + "report_name": "Accounts Receivable", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Accounts Receivable" + } +] \ No newline at end of file diff --git a/accounts/search_criteria/accounts_receivable/accounts_receivable.sql b/accounts/search_criteria/accounts_receivable/accounts_receivable.sql index e9f392200d3..6f1c459fdb8 100644 --- a/accounts/search_criteria/accounts_receivable/accounts_receivable.sql +++ b/accounts/search_criteria/accounts_receivable/accounts_receivable.sql @@ -13,4 +13,4 @@ WHERE AND `tabGL Entry`.`is_cancelled` = 'No' AND `tabAccount`.`master_type` = 'Customer' AND `tabAccount`.`name` = `tabGL Entry`.`account` -ORDER BY `tabGL Entry`.`posting_date` +ORDER BY `tabGL Entry`.`posting_date`, `tabGL Entry`.`account` diff --git a/controllers/accounts_controller.py b/controllers/accounts_controller.py index 0e7c108f3d0..04e4bbdaee3 100644 --- a/controllers/accounts_controller.py +++ b/controllers/accounts_controller.py @@ -16,7 +16,6 @@ from __future__ import unicode_literals import webnotes -from webnotes import msgprint, _ from webnotes.utils import flt from utilities.transaction_base import TransactionBase @@ -83,10 +82,13 @@ class AccountsController(TransactionBase): @property def stock_items(self): if not hasattr(self, "_stock_items"): - item_codes = list(set(item.item_code for item in self.doclist.get({"parentfield": self.fname}))) - self._stock_items = [r[0] for r in webnotes.conn.sql("""select name - from `tabItem` where name in (%s) and is_stock_item='Yes'""" % \ - (", ".join((["%s"]*len(item_codes))),), item_codes)] + self._stock_items = [] + item_codes = list(set(item.item_code for item in + self.doclist.get({"parentfield": self.fname}))) + if item_codes: + self._stock_items = [r[0] for r in webnotes.conn.sql("""select name + from `tabItem` where name in (%s) and is_stock_item='Yes'""" % \ + (", ".join((["%s"]*len(item_codes))),), item_codes)] return self._stock_items @@ -95,4 +97,4 @@ class AccountsController(TransactionBase): if not hasattr(self, "_abbr"): self._abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr") - return self._abbr + return self._abbr \ No newline at end of file diff --git a/controllers/buying_controller.py b/controllers/buying_controller.py index 560dec2a15a..429737e53eb 100644 --- a/controllers/buying_controller.py +++ b/controllers/buying_controller.py @@ -419,21 +419,25 @@ class BuyingController(StockController): @property def sub_contracted_items(self): if not hasattr(self, "_sub_contracted_items"): + self._sub_contracted_items = [] item_codes = list(set(item.item_code for item in self.doclist.get({"parentfield": self.fname}))) - self._sub_contracted_items = [r[0] for r in webnotes.conn.sql("""select name - from `tabItem` where name in (%s) and is_sub_contracted_item='Yes'""" % \ - (", ".join((["%s"]*len(item_codes))),), item_codes)] + if item_codes: + self._sub_contracted_items = [r[0] for r in webnotes.conn.sql("""select name + from `tabItem` where name in (%s) and is_sub_contracted_item='Yes'""" % \ + (", ".join((["%s"]*len(item_codes))),), item_codes)] return self._sub_contracted_items @property def purchase_items(self): if not hasattr(self, "_purchase_items"): + self._purchase_items = [] item_codes = list(set(item.item_code for item in self.doclist.get({"parentfield": self.fname}))) - self._purchase_items = [r[0] for r in webnotes.conn.sql("""select name - from `tabItem` where name in (%s) and is_purchase_item='Yes'""" % \ - (", ".join((["%s"]*len(item_codes))),), item_codes)] + if item_codes: + self._purchase_items = [r[0] for r in webnotes.conn.sql("""select name + from `tabItem` where name in (%s) and is_purchase_item='Yes'""" % \ + (", ".join((["%s"]*len(item_codes))),), item_codes)] return self._purchase_items diff --git a/hr/doctype/leave_application/leave_application.js b/hr/doctype/leave_application/leave_application.js index 7f8948a674c..2715a6c5db9 100755 --- a/hr/doctype/leave_application/leave_application.js +++ b/hr/doctype/leave_application/leave_application.js @@ -16,7 +16,6 @@ cur_frm.add_fetch('employee','employee_name','employee_name'); - cur_frm.cscript.onload = function(doc, dt, dn) { if(!doc.posting_date) set_multiple(dt,dn,{posting_date:get_today()}); @@ -127,4 +126,8 @@ cur_frm.cscript.calculate_total_days = function(doc, dt, dn) { } } -cur_frm.fields_dict.employee.get_query = erpnext.utils.employee_query; \ No newline at end of file +cur_frm.fields_dict.employee.get_query = function() { + return { + query: "hr.doctype.leave_application.leave_application.query_for_permitted_employees" + }; +} \ No newline at end of file diff --git a/hr/doctype/leave_application/leave_application.py b/hr/doctype/leave_application/leave_application.py index b9f9e5bfefd..6e39751b716 100755 --- a/hr/doctype/leave_application/leave_application.py +++ b/hr/doctype/leave_application/leave_application.py @@ -330,3 +330,20 @@ def add_holidays(events, start, end, employee, company): "title": _("Holiday") + ": " + cstr(holiday.description), "name": holiday.name }) + +@webnotes.whitelist() +def query_for_permitted_employees(doctype, txt, searchfield, start, page_len, filters): + txt = "%" + cstr(txt) + "%" + + return webnotes.conn.sql("""select name, employee_name from `tabEmployee` emp + where status = 'Active' and docstatus < 2 and + (`%s` like %s or employee_name like %s) and + (exists(select ela.name from `tabEmployee Leave Approver` ela + where ela.parent=emp.name and ela.leave_approver=%s) or + not exists(select ela.name from `tabEmployee Leave Approver` ela where ela.parent=emp.name) + or user_id = %s) + order by + case when name like %s then 0 else 1 end, + case when employee_name like %s then 0 else 1 end, + name limit %s, %s""" % tuple([searchfield] + ["%s"]*8), + (txt, txt, webnotes.session.user, webnotes.session.user, txt, txt, start, page_len)) diff --git a/hr/doctype/salary_structure/salary_structure.py b/hr/doctype/salary_structure/salary_structure.py index 22789e3f499..018aab7e7c3 100644 --- a/hr/doctype/salary_structure/salary_structure.py +++ b/hr/doctype/salary_structure/salary_structure.py @@ -18,31 +18,25 @@ from __future__ import unicode_literals import webnotes from webnotes.utils import cstr, flt -from webnotes.model import db_exists from webnotes.model.doc import addchild, make_autoname -from webnotes.model.bean import copy_doclist -from webnotes import msgprint +from webnotes import msgprint, _ sql = webnotes.conn.sql class DocType: - #init function def __init__(self,doc,doclist=[]): self.doc = doc self.doclist = doclist - - #autoname function - #--------------------------------------------------------- + def autoname(self): self.doc.name = make_autoname(self.doc.employee + '/.SST' + '/.#####') - - #get employee details - #--------------------------------------------------------- + def get_employee_details(self): ret = {} - det = sql("select employee_name, branch, designation, department, grade from `tabEmployee` where name = '%s'" %self.doc.employee) + det = sql("""select employee_name, branch, designation, department, grade + from `tabEmployee` where name = %s""", self.doc.employee) if det: ret = { 'employee_name': cstr(det[0][0]), @@ -53,20 +47,16 @@ class DocType: 'backup_employee': cstr(self.doc.employee) } return ret - - # Set Salary structure field values - #--------------------------------------------------------- def get_ss_values(self,employee): - basic_info = sql("select bank_name, bank_ac_no, esic_card_no, pf_number from `tabEmployee` where name ='%s'" % employee) + basic_info = sql("""select bank_name, bank_ac_no, esic_card_no, pf_number + from `tabEmployee` where name =%s""", employee) ret = {'bank_name': basic_info and basic_info[0][0] or '', 'bank_ac_no': basic_info and basic_info[0][1] or '', 'esic_no': basic_info and basic_info[0][2] or '', 'pf_no': basic_info and basic_info[0][3] or ''} return ret - - # Make earning and deduction table - #--------------------------------------------------------- + def make_table(self, doct_name, tab_fname, tab_name): list1 = sql("select name from `tab%s` where docstatus != 2" % doct_name) for li in list1: @@ -77,37 +67,31 @@ class DocType: elif(tab_fname == 'deduction_details'): child.d_type = cstr(li[0]) child.d_modified_amt = 0 - - # add earning & deduction types to table - #--------------------------------------------------------- + def make_earn_ded_table(self): - #Earning List self.make_table('Earning Type','earning_details','Salary Structure Earning') - - #Deduction List - self.make_table('Deduction Type','deduction_details', - 'Salary Structure Deduction') - + self.make_table('Deduction Type','deduction_details', 'Salary Structure Deduction') - # Check if another active ss exists - #--------------------------------------------------------- def check_existing(self): - ret = sql("select name from `tabSalary Structure` where is_active = 'Yes' and employee = '%s' and name!='%s'" %(self.doc.employee,self.doc.name)) + ret = sql("""select name from `tabSalary Structure` where is_active = 'Yes' + and employee = %s and name!=%s""", (self.doc.employee,self.doc.name)) if ret and self.doc.is_active=='Yes': - msgprint("Another Salary Structure '%s' is active for employee '%s'. Please make its status 'Inactive' to proceed."%(cstr(ret), self.doc.employee)) - raise Exception + msgprint(_("""Another Salary Structure '%s' is active for employee '%s'. + Please make its status 'Inactive' to proceed.""") % + (cstr(ret), self.doc.employee), raise_exception=1) - # Validate net pay - #--------------------------------------------------------- - def validate_net_pay(self): + def validate_amount(self): + if flt(self.doc.ctc) < 12*flt(self.doc.total_earning): + msgprint(_("Annual Cost To Company can not be less than 12 months of Total Earning"), + raise_exception=1) + if flt(self.doc.net_pay) < 0: - msgprint("Net pay can not be negative") - raise Exception - elif flt(self.doc.net_pay) > flt(self.doc.ctc): - msgprint("Net pay can not be greater than CTC") - raise Exception + msgprint(_("Net pay can not be negative"), raise_exception=1) + elif flt(self.doc.net_pay)*12 > flt(self.doc.ctc): + msgprint(_("Net pay can not be greater than 1/12th of Annual Cost To Company"), + raise_exception=1) + def validate(self): self.check_existing() - self.validate_net_pay() - + self.validate_amount() \ No newline at end of file diff --git a/hr/doctype/salary_structure/salary_structure.txt b/hr/doctype/salary_structure/salary_structure.txt index c2efac6a8db..43b36626f6c 100644 --- a/hr/doctype/salary_structure/salary_structure.txt +++ b/hr/doctype/salary_structure/salary_structure.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-01-23 19:57:18", + "creation": "2013-03-07 18:50:29", "docstatus": 0, - "modified": "2013-01-29 17:35:34", + "modified": "2013-04-22 14:09:04", "modified_by": "Administrator", "owner": "Administrator" }, @@ -41,6 +41,7 @@ "doctype": "DocField", "fieldname": "column_break0", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -52,6 +53,7 @@ "oldfieldname": "employee", "oldfieldtype": "Link", "options": "Employee", + "read_only": 0, "reqd": 1 }, { @@ -116,6 +118,7 @@ "doctype": "DocField", "fieldname": "column_break1", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -129,6 +132,7 @@ "oldfieldname": "is_active", "oldfieldtype": "Select", "options": "\nYes\nNo", + "read_only": 0, "reqd": 1 }, { @@ -139,6 +143,7 @@ "label": "From Date", "oldfieldname": "from_date", "oldfieldtype": "Date", + "read_only": 0, "reqd": 1 }, { @@ -148,7 +153,8 @@ "in_list_view": 1, "label": "To Date", "oldfieldname": "to_date", - "oldfieldtype": "Date" + "oldfieldtype": "Date", + "read_only": 0 }, { "description": "Cost to Company", @@ -156,10 +162,11 @@ "fieldname": "ctc", "fieldtype": "Currency", "in_filter": 1, - "label": "CTC", + "label": "Annual Cost To Company", "oldfieldname": "ctc", "oldfieldtype": "Currency", "options": "Company:company:default_currency", + "read_only": 0, "reqd": 1 }, { @@ -169,6 +176,7 @@ "in_filter": 1, "label": "Company", "options": "link:Company", + "read_only": 0, "reqd": 1 }, { @@ -178,7 +186,8 @@ "fieldtype": "Section Break", "label": "Earning & Deduction", "oldfieldname": "earning_deduction", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "read_only": 0 }, { "doctype": "DocField", @@ -188,6 +197,7 @@ "label": "Earning", "oldfieldname": "col_brk2", "oldfieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -198,7 +208,8 @@ "label": "Earning1", "oldfieldname": "earning_details", "oldfieldtype": "Table", - "options": "Salary Structure Earning" + "options": "Salary Structure Earning", + "read_only": 0 }, { "doctype": "DocField", @@ -208,6 +219,7 @@ "label": "Deduction", "oldfieldname": "col_brk3", "oldfieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -218,18 +230,21 @@ "label": "Deduction1", "oldfieldname": "deduction_details", "oldfieldtype": "Table", - "options": "Salary Structure Deduction" + "options": "Salary Structure Deduction", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "section_break0", "fieldtype": "Section Break", - "options": "Simple" + "options": "Simple", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "column_break2", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -256,6 +271,7 @@ "doctype": "DocField", "fieldname": "column_break3", "fieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { diff --git a/patches/october_2012/update_account_property.py b/patches/october_2012/update_account_property.py index efe0649d222..a9d365faf86 100644 --- a/patches/october_2012/update_account_property.py +++ b/patches/october_2012/update_account_property.py @@ -11,4 +11,4 @@ def execute(): for acc in roots: webnotes.conn.sql("""update tabAccount set debit_or_credit = %(debit_or_credit)s, is_pl_account = %(is_pl_account)s, company = %(company)s - where lft > %(lft)s and rgt < %(rgt)s""", acc, debug=1) \ No newline at end of file + where lft > %(lft)s and rgt < %(rgt)s""", acc) \ No newline at end of file diff --git a/projects/report/daily_time_log_summary/daily_time_log_summary.py b/projects/report/daily_time_log_summary/daily_time_log_summary.py index 22e48077b59..8c1e2668cd2 100644 --- a/projects/report/daily_time_log_summary/daily_time_log_summary.py +++ b/projects/report/daily_time_log_summary/daily_time_log_summary.py @@ -1,5 +1,6 @@ from __future__ import unicode_literals import webnotes +from webnotes.utils import flt def execute(filters=None): if not filters: @@ -18,17 +19,29 @@ def execute(filters=None): time_logs = webnotes.conn.sql("""select * from `tabTime Log` where docstatus < 2 %s order by owner asc""" % (conditions, ), filters, as_dict=1) - data = [] if time_logs: profiles = [time_logs[0].owner] + data = [] + total_hours = total_employee_hours = count = 0 for tl in time_logs: if tl.owner not in profiles: profiles.append(tl.owner) - data.append([]) - + data.append(["", "", "", "Total", total_employee_hours, "", "", "", "", ""]) + total_employee_hours = 0 + data.append([tl.name, profile_map[tl.owner], tl.from_time, tl.to_time, tl.hours, tl.activity_type, tl.task, task_map.get(tl.task), tl.project, tl.status]) + + count += 1 + total_hours += flt(tl.hours) + total_employee_hours += flt(tl.hours) + + if count == len(time_logs): + data.append(["", "", "", "Total Hours", total_employee_hours, "", "", "", "", ""]) + + if total_hours: + data.append(["", "", "", "Grand Total", total_hours, "", "", "", "", ""]) return columns, data diff --git a/setup/doctype/backup_manager/backup_dropbox.py b/setup/doctype/backup_manager/backup_dropbox.py index 2901638c048..ac07824a88c 100644 --- a/setup/doctype/backup_manager/backup_dropbox.py +++ b/setup/doctype/backup_manager/backup_dropbox.py @@ -7,12 +7,14 @@ # dropbox_access_key # dropbox_access_secret - +from __future__ import unicode_literals import os import webnotes -from webnotes.utils import get_request_site_address, get_base_path +from webnotes.utils import get_request_site_address, get_base_path, cstr from webnotes import _ +from backup_manager import ignore_list + @webnotes.whitelist() def get_dropbox_authorize_url(): sess = get_dropbox_session() @@ -58,7 +60,7 @@ def dropbox_callback(oauth_token=None, not_approved=False): webnotes.message_title = "Dropbox Approval" webnotes.message = "

%s

Please close this window.

" % message - + webnotes.conn.commit() webnotes.response['type'] = 'page' webnotes.response['page_name'] = 'message.html' @@ -81,12 +83,18 @@ def backup_to_dropbox(): backup = new_backup() filename = os.path.join(get_base_path(), "public", "backups", os.path.basename(backup.backup_path_db)) - upload_file_to_dropbox(filename, "database", dropbox_client) + upload_file_to_dropbox(filename, "/database", dropbox_client) response = dropbox_client.metadata("/files") + # upload files to files folder + did_not_upload = [] + error_log = [] path = os.path.join(get_base_path(), "public", "files") for filename in os.listdir(path): + if filename in ignore_list: + continue + found = False filepath = os.path.join(path, filename) for file_metadata in response["contents"]: @@ -94,7 +102,13 @@ def backup_to_dropbox(): found = True break if not found: - upload_file_to_dropbox(filepath, "files", dropbox_client) + try: + upload_file_to_dropbox(filepath, "/files", dropbox_client) + except Exception, e: + did_not_upload.append(filename) + error_log.append(cstr(e)) + + return did_not_upload, list(set(error_log)) def get_dropbox_session(): try: @@ -113,21 +127,21 @@ def get_dropbox_session(): def upload_file_to_dropbox(filename, folder, dropbox_client): from dropbox import rest size = os.stat(filename).st_size - f = open(filename,'r') - # if max packet size reached, use chunked uploader - max_packet_size = 4194304 + with open(filename, 'r') as f: + # if max packet size reached, use chunked uploader + max_packet_size = 4194304 - if size > max_packet_size: - uploader = dropbox_client.get_chunked_uploader(f, size) - while uploader.offset < size: - try: - uploader.upload_chunked() - uploader.finish(folder + "/" + os.path.basename(filename), overwrite=True) - except rest.ErrorResponse: - pass - else: - dropbox_client.put_file(folder + "/" + os.path.basename(filename), f, overwrite=True) + if size > max_packet_size: + uploader = dropbox_client.get_chunked_uploader(f, size) + while uploader.offset < size: + try: + uploader.upload_chunked() + uploader.finish(folder + "/" + os.path.basename(filename), overwrite=True) + except rest.ErrorResponse: + pass + else: + dropbox_client.put_file(folder + "/" + os.path.basename(filename), f, overwrite=True) if __name__=="__main__": backup_to_dropbox() \ No newline at end of file diff --git a/setup/doctype/backup_manager/backup_googledrive.py b/setup/doctype/backup_manager/backup_googledrive.py index 4b2a82cb891..7d980debe78 100644 --- a/setup/doctype/backup_manager/backup_googledrive.py +++ b/setup/doctype/backup_manager/backup_googledrive.py @@ -10,16 +10,22 @@ # gdrive_client_id # gdrive_client_secret +from __future__ import unicode_literals import httplib2 import os import mimetypes import webnotes import oauth2client.client -from webnotes.utils import get_base_path +from webnotes.utils import get_base_path, cstr from webnotes import _, msgprint from apiclient.discovery import build from apiclient.http import MediaFileUpload +# define log config for google drive api's log messages +# basicConfig redirects log to stderr +import logging +logging.basicConfig() + @webnotes.whitelist() def get_gdrive_authorize_url(): flow = get_gdrive_flow() @@ -67,8 +73,11 @@ def backup_to_gdrive(): # upload files to database folder upload_files(filename, 'application/x-gzip', drive_service, webnotes.conn.get_value("Backup Manager", None, "database_folder_id")) - + # upload files to files folder + did_not_upload = [] + error_log = [] + path = os.path.join(get_base_path(), "public", "files") for filename in os.listdir(path): found = False @@ -78,7 +87,8 @@ def backup_to_gdrive(): if ext == 'gz' or ext == 'gzip': mimetype = 'application/x-gzip' else: - mimetype = mimetypes.types_map["." + ext] + mimetype = mimetypes.types_map.get("." + ext) or "application/octet-stream" + #Compare Local File with Server File param = {} children = drive_service.children().list( @@ -90,7 +100,14 @@ def backup_to_gdrive(): found = True break if not found: - upload_files(filepath, mimetype, drive_service, webnotes.conn.get_value("Backup Manager", None, "files_folder_id")) + try: + upload_files(filepath, mimetype, drive_service, + webnotes.conn.get_value("Backup Manager", None, "files_folder_id")) + except Exception, e: + did_not_upload.append(filename) + error_log.append(cstr(e)) + + return did_not_upload, list(set(error_log)) def get_gdrive_flow(): from oauth2client.client import OAuth2WebServerFlow diff --git a/setup/doctype/backup_manager/backup_manager.js b/setup/doctype/backup_manager/backup_manager.js index 28315c5bc51..8d2d8de853a 100644 --- a/setup/doctype/backup_manager/backup_manager.js +++ b/setup/doctype/backup_manager/backup_manager.js @@ -41,7 +41,9 @@ cur_frm.cscript.allow_gdrive_access = function(doc) { wn.call({ method: "setup.doctype.backup_manager.backup_googledrive.get_gdrive_authorize_url", callback: function(r) { - window.open(r.message.authorize_url); + if(!r.exc) { + window.open(r.message.authorize_url); + } } }) } @@ -49,7 +51,7 @@ cur_frm.cscript.allow_gdrive_access = function(doc) { cur_frm.cscript.validate_gdrive = function(doc) { wn.call({ - method: "setup.doctype.backup_manager.backup_manager.gdrive_callback", + method: "setup.doctype.backup_manager.backup_googledrive.gdrive_callback", args: { verification_code: doc.verification_code }, diff --git a/setup/doctype/backup_manager/backup_manager.py b/setup/doctype/backup_manager/backup_manager.py index 4fb6ab30697..a8ecd636db0 100644 --- a/setup/doctype/backup_manager/backup_manager.py +++ b/setup/doctype/backup_manager/backup_manager.py @@ -4,6 +4,8 @@ from __future__ import unicode_literals import webnotes from webnotes import _ +ignore_list = [] + class DocType: def __init__(self, d, dl): self.doc, self.doclist = d, dl @@ -23,22 +25,34 @@ def take_backups_if(freq): @webnotes.whitelist() def take_backups_dropbox(): + did_not_upload, error_log = [], [] try: from setup.doctype.backup_manager.backup_dropbox import backup_to_dropbox - backup_to_dropbox() + did_not_upload, error_log = backup_to_dropbox() + if did_not_upload: raise Exception + send_email(True, "Dropbox") - except Exception, e: - send_email(False, "Dropbox", e) + except Exception: + file_and_error = [" - ".join(f) for f in zip(did_not_upload, error_log)] + error_message = ("\n".join(file_and_error) + "\n" + webnotes.getTraceback()) + print error_message + send_email(False, "Dropbox", error_message) #backup to gdrive @webnotes.whitelist() def take_backups_gdrive(): + did_not_upload, error_log = [], [] try: from setup.doctype.backup_manager.backup_googledrive import backup_to_gdrive - backup_to_gdrive() + did_not_upload, error_log = backup_to_gdrive() + if did_not_upload: raise Exception + send_email(True, "Google Drive") - except Exception, e: - send_email(False, "Google Drive", e) + except Exception: + file_and_error = [" - ".join(f) for f in zip(did_not_upload, error_log)] + error_message = ("\n".join(file_and_error) + "\n" + webnotes.getTraceback()) + print error_message + send_email(False, "Google Drive", error_message) def send_email(success, service_name, error_status=None): if success: @@ -58,4 +72,4 @@ def send_email(success, service_name, error_status=None): # email system managers from webnotes.utils.email_lib import sendmail sendmail(webnotes.conn.get_value("Backup Manager", None, "send_notifications_to").split(","), - subject=subject, msg=message) \ No newline at end of file + subject=subject, msg=message) diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py index a16296d18b9..4767742e3ef 100644 --- a/stock/doctype/item/item.py +++ b/stock/doctype/item/item.py @@ -24,50 +24,169 @@ from webnotes import msgprint, _ from webnotes.model.controller import DocListController class DocType(DocListController): - def get_tax_rate(self, tax_type): - rate = webnotes.conn.sql("select tax_rate from tabAccount where name = %s", tax_type) - ret = { - 'tax_rate' : rate and flt(rate[0][0]) or 0 - } - return ret + def validate(self): + if not self.doc.stock_uom: + msgprint(_("Please enter Default Unit of Measure"), raise_exception=1) + + self.check_stock_uom_with_bin() + self.validate_conversion_factor() + self.add_default_uom_in_conversion_factor_table() + self.valiadte_item_type() + self.check_for_active_boms() + self.check_ref_rate_detail() + self.fill_customer_code() + self.check_item_tax() + self.validate_barcode() + self.check_non_asset_warehouse() + self.cant_change() + if self.doc.name: + self.old_page_name = webnotes.conn.get_value('Item', self.doc.name, 'page_name') + def on_update(self): self.validate_name_with_item_group() - - # webpage updates self.update_website() - + + def add_default_uom_in_conversion_factor_table(self): + uom_conv_list = [d.uom for d in self.doclist.get({"parentfield": "uom_conversion_details"})] + if self.doc.stock_uom not in uom_conv_list: + ch = addchild(self.doc, 'uom_conversion_details', 'UOM Conversion Detail', self.doclist) + ch.uom = self.doc.stock_uom + ch.conversion_factor = 1 + + def check_stock_uom_with_bin(self): bin = webnotes.conn.sql("select stock_uom from `tabBin` where item_code = %s", self.doc.item_code) - if bin and cstr(bin[0][0]) and cstr(bin[0][0]) != cstr(self.doc.stock_uom): - msgprint("Please Update Stock UOM with the help of Stock UOM Replace Utility.") - raise Exception + if self.doc.stock_uom and bin and cstr(bin[0][0]) \ + and cstr(bin[0][0]) != cstr(self.doc.stock_uom): + msgprint(_("Please Update Stock UOM with the help of Stock UOM Replace Utility."), + raise_exception=1) + + def validate_conversion_factor(self): check_list = [] for d in getlist(self.doclist,'uom_conversion_details'): - if not self.doc.stock_uom: - msgprint("Please enter Stock UOM first.") - raise Exception - if cstr(d.uom) in check_list: - msgprint("UOM %s has been entered more than once in Conversion Factor Details." % cstr(d.uom)) - raise Exception + msgprint(_("UOM %s has been entered more than once in Conversion Factor Table." % + cstr(d.uom)), raise_exception=1) else: check_list.append(cstr(d.uom)) - if cstr(d.uom) == cstr(self.doc.stock_uom): - if flt(d.conversion_factor) != 1: - msgprint("Conversion Factor of UOM : %s should be equal to 1. As UOM : %s is Stock UOM of Item: %s." % ( cstr(d.uom), cstr(d.uom), cstr(self.doc.name))) - raise Exception - elif cstr(d.uom) != cstr(self.doc.stock_uom) and flt(d.conversion_factor) == 1: - msgprint("Conversion Factor of UOM : %s should not be equal to 1. As UOM : %s is not Stock UOM of Item: %s." % ( cstr(d.uom), cstr(d.uom), cstr(self.doc.name))) - raise Exception + if d.uom and cstr(d.uom) == cstr(self.doc.stock_uom) and flt(d.conversion_factor) != 1: + msgprint(_("""Conversion Factor of UOM: %s should be equal to 1. + As UOM: %s is Stock UOM of Item: %s.""" % + (d.uom, d.uom, self.doc.name)), raise_exception=1) + elif d.uom and cstr(d.uom)!= self.doc.stock_uom and flt(d.conversion_factor) == 1: + msgprint(_("""Conversion Factor of UOM: %s should not be equal to 1. + As UOM: %s is not Stock UOM of Item: %s""" % + (d.uom, d.uom, self.doc.name)), raise_exception=1) + + def valiadte_item_type(self): + if cstr(self.doc.is_manufactured_item) == "No": + self.doc.is_pro_applicable = "No" - if not cstr(self.doc.stock_uom) in check_list : - child = addchild( self.doc, 'uom_conversion_details', - 'UOM Conversion Detail', self.doclist) - child.uom = self.doc.stock_uom - child.conversion_factor = 1 - child.save() + if self.doc.is_pro_applicable == 'Yes' and self.doc.is_stock_item == 'No': + msgprint("As Production Order can be made for this Item, then Is Stock Item Should be 'Yes' as we maintain it's stock. Refer Manufacturing and Inventory section.", raise_exception=1) + + if self.doc.has_serial_no == 'Yes' and self.doc.is_stock_item == 'No': + msgprint("'Has Serial No' can not be 'Yes' for non-stock item", raise_exception=1) + + def check_for_active_boms(self): + def _check_for_active_boms(field_label): + if field_label in ['Is Active', 'Is Purchase Item']: + bom_mat = webnotes.conn.sql("""select distinct t1.parent + from `tabBOM Item` t1, `tabBOM` t2 where t2.name = t1.parent + and t1.item_code =%s and ifnull(t1.bom_no, '') = '' and t2.is_active = 1 + and t2.docstatus = 1 and t1.docstatus =1 """, self.doc.name) + if bom_mat and bom_mat[0][0]: + msgprint(_(field_label) + _(" should be 'Yes'. As Item: ") + self.doc.name + + _(" is present in one or many Active BOMs"), raise_exception=1) + + if ((field_label == 'Allow Production Order' + and self.doc.is_sub_contracted_item != 'Yes') + or (field_label == 'Is Sub Contracted Item' + and self.doc.is_manufactured_item != 'Yes')): + bom = webnotes.conn.sql("""select name from `tabBOM` where item = %s + and is_active = 1""", (self.doc.name,)) + if bom and bom[0][0]: + msgprint(_(field_label) + _(" should be 'Yes'. As Item: ") + self.doc.name + + _(" is present in one or many Active BOMs"), raise_exception=1) + + if not cint(self.doc.fields.get("__islocal")): + fl = {'is_manufactured_item' :'Allow Bill of Materials', + 'is_sub_contracted_item':'Is Sub Contracted Item', + 'is_purchase_item' :'Is Purchase Item', + 'is_pro_applicable' :'Allow Production Order'} + for d in fl: + if cstr(self.doc.fields.get(d)) != 'Yes': + _check_for_active_boms(fl[d]) + + def check_ref_rate_detail(self): + check_list=[] + for d in getlist(self.doclist,'ref_rate_details'): + if [cstr(d.price_list_name), cstr(d.ref_currency), + cint(d.selling), cint(d.buying)] in check_list: + msgprint("Ref Rate is entered twice for Price List : '%s' and Currency : '%s'." % + (d.price_list_name,d.ref_currency), raise_exception=1) + else: + check_list.append([cstr(d.price_list_name),cstr(d.ref_currency)]) + + def fill_customer_code(self): + """ Append all the customer codes and insert into "customer_code" field of item table """ + cust_code=[] + for d in getlist(self.doclist,'item_customer_details'): + cust_code.append(d.ref_code) + self.doc.customer_code=','.join(cust_code) + + def check_item_tax(self): + """Check whether Tax Rate is not entered twice for same Tax Type""" + check_list=[] + for d in getlist(self.doclist,'item_tax'): + if d.tax_type: + account_type = webnotes.conn.get_value("Account", d.tax_type, "account_type") + + if account_type not in ['Tax', 'Chargeable']: + msgprint("'%s' is not Tax / Chargeable Account" % d.tax_type, raise_exception=1) + else: + if d.tax_type in check_list: + msgprint("Rate is entered twice for: '%s'" % d.tax_type, raise_exception=1) + else: + check_list.append(d.tax_type) + + def validate_barcode(self): + if self.doc.barcode: + duplicate = webnotes.conn.sql("select name from tabItem where barcode = %s and name != %s", (self.doc.barcode, self.doc.name)) + if duplicate: + msgprint("Barcode: %s already used in item: %s" % + (self.doc.barcode, cstr(duplicate[0][0])), raise_exception = 1) + + def check_non_asset_warehouse(self): + if self.doc.is_asset_item == "Yes": + existing_qty = webnotes.conn.sql("select t1.warehouse, t1.actual_qty from tabBin t1, tabWarehouse t2 where t1.item_code=%s and (t2.warehouse_type!='Fixed Asset' or t2.warehouse_type is null) and t1.warehouse=t2.name and t1.actual_qty > 0", self.doc.name) + for e in existing_qty: + msgprint("%s Units exist in Warehouse %s, which is not an Asset Warehouse." % + (e[1],e[0])) + if existing_qty: + self.doc.is_asset_item = 'No' + msgprint(_("""Please transfer the above quantities to an asset warehouse \ + before changing this item to an asset item"""), raise_exception=1) + + def cant_change(self): + if not self.doc.fields.get("__islocal"): + vals = webnotes.conn.get_value("Item", self.doc.name, + ["has_serial_no", "is_stock_item", "valuation_method"], as_dict=True) + + if vals and ((self.doc.is_stock_item == "No" and vals.is_stock_item == "Yes") or + vals.has_serial_no != self.doc.has_serial_no or + vals.valuation_method != self.doc.valuation_method): + if self.check_if_sle_exists() == "exists": + webnotes.msgprint(_("As there are existing stock transactions for this \ + item, you can not change the values of 'Has Serial No', \ + 'Is Stock Item' and 'Valuation Method'"), raise_exception=1) + + def check_if_sle_exists(self): + sle = webnotes.conn.sql("""select name from `tabStock Ledger Entry` + where item_code = %s and ifnull(is_cancelled, 'No') = 'No'""", self.doc.name) + return sle and 'exists' or 'not exists' def validate_name_with_item_group(self): if webnotes.conn.exists("Item Group", self.doc.name): @@ -104,107 +223,17 @@ class DocType(DocListController): webnotes.conn.set(self.doc, "page_name", None) - # On delete 1. Delete BIN (if none of the corrosponding transactions present, it gets deleted. if present, rolled back due to exception) - def on_trash(self): - webnotes.conn.sql("""delete from tabBin where item_code=%s""", self.doc.item_code) - webnotes.conn.sql("""delete from `tabStock Ledger Entry` - where item_code=%s and is_cancelled='Yes' """, self.doc.item_code) - - if self.doc.page_name: - from webnotes.webutils import clear_cache - clear_cache(self.doc.page_name) - - # Check whether Ref Rate is not entered twice for same Price List and Currency - def check_ref_rate_detail(self): - check_list=[] - for d in getlist(self.doclist,'ref_rate_details'): - if [cstr(d.price_list_name),cstr(d.ref_currency),cint(d.selling),cint(d.buying)] in check_list: - msgprint("Ref Rate is entered twice for Price List : '%s' and Currency : '%s'." % (d.price_list_name,d.ref_currency)) - raise Exception - else: - check_list.append([cstr(d.price_list_name),cstr(d.ref_currency)]) + def get_tax_rate(self, tax_type): + return { "tax_rate": webnotes.conn.get_value("Account", tax_type, "tax_rate") } - # Append all the customer codes and insert into "customer_code" field of item table - def fill_customer_code(self): - cust_code=[] - for d in getlist(self.doclist,'item_customer_details'): - cust_code.append(d.ref_code) - self.doc.customer_code=','.join(cust_code) + def prepare_template_args(self): + from website.helpers.product import get_parent_item_groups + self.parent_groups = get_parent_item_groups(self.doc.item_group) + [{"name":self.doc.name}] + self.doc.title = self.doc.item_name - def check_item_tax(self): - """Check whether Tax Rate is not entered twice for same Tax Type""" - check_list=[] - for d in getlist(self.doclist,'item_tax'): - if d.tax_type: - account_type = webnotes.conn.get_value("Account", d.tax_type, "account_type") - - if account_type not in ['Tax', 'Chargeable']: - msgprint("'%s' is not Tax / Chargeable Account" % d.tax_type, raise_exception=1) - else: - if d.tax_type in check_list: - msgprint("Rate is entered twice for: '%s'" % d.tax_type, raise_exception=1) - else: - check_list.append(d.tax_type) - - def check_for_active_boms(self, field_label): - if field_label in ['Is Active', 'Is Purchase Item']: - bom_mat = webnotes.conn.sql("select distinct t1.parent from `tabBOM Item` t1, `tabBOM` t2 where t1.item_code =%s and (t1.bom_no = '' or t1.bom_no is NULL) and t2.name = t1.parent and t2.is_active = 1 and t2.docstatus = 1 and t1.docstatus =1 ", self.doc.name) - if bom_mat and bom_mat[0][0]: - msgprint("%s should be 'Yes'. As Item %s is present in one or many Active BOMs." % (cstr(field_label), cstr(self.doc.name))) - raise Exception - if ((field_label == 'Allow Production Order' - and self.doc.is_sub_contracted_item != 'Yes') - or (field_label == 'Is Sub Contracted Item' - and self.doc.is_manufactured_item != 'Yes')): - bom = webnotes.conn.sql("select name from `tabBOM` where item = %s and is_active = 1", - (self.doc.name,)) - if bom and bom[0][0]: - msgprint("%s should be 'Yes'. As Item %s is present in one or many Active BOMs." % (cstr(field_label), cstr(self.doc.name))) - raise Exception - - def validate_barcode(self): - if self.doc.barcode: - duplicate = webnotes.conn.sql("select name from tabItem where barcode = %s and name != %s", (self.doc.barcode, self.doc.name)) - if duplicate: - msgprint("Barcode: %s already used in item: %s" % (self.doc.barcode, cstr(duplicate[0][0])), raise_exception = 1) - - def validate(self): - if not cint(self.doc.fields.get("__islocal")): - fl = {'is_manufactured_item' :'Allow Bill of Materials', - 'is_sub_contracted_item':'Is Sub Contracted Item', - 'is_purchase_item' :'Is Purchase Item', - 'is_pro_applicable' :'Allow Production Order'} - for d in fl: - if cstr(self.doc.fields.get(d)) != 'Yes': - self.check_for_active_boms(fl[d]) - self.check_ref_rate_detail() - self.fill_customer_code() - self.check_item_tax() - self.validate_barcode() - self.check_non_asset_warehouse() - self.cant_change() - - if cstr(self.doc.is_manufactured_item) == "No": - self.doc.is_pro_applicable = "No" - - if self.doc.is_pro_applicable == 'Yes' and self.doc.is_stock_item == 'No': - msgprint("As Production Order can be made for this Item, then Is Stock Item Should be 'Yes' as we maintain it's stock. Refer Manufacturing and Inventory section.", raise_exception=1) - - if self.doc.has_serial_no == 'Yes' and self.doc.is_stock_item == 'No': - msgprint("'Has Serial No' can not be 'Yes' for non-stock item", raise_exception=1) - - if self.doc.name: - self.old_page_name = webnotes.conn.get_value('Item', self.doc.name, 'page_name') - - def check_non_asset_warehouse(self): - if self.doc.is_asset_item == "Yes": - existing_qty = webnotes.conn.sql("select t1.warehouse, t1.actual_qty from tabBin t1, tabWarehouse t2 where t1.item_code=%s and (t2.warehouse_type!='Fixed Asset' or t2.warehouse_type is null) and t1.warehouse=t2.name and t1.actual_qty > 0", self.doc.name) - for e in existing_qty: - msgprint("%s Units exist in Warehouse %s, which is not an Asset Warehouse." % (e[1],e[0])) - if existing_qty: - msgprint("Please transfer the above quantities to an asset warehouse before changing this item to an asset item.") - self.doc.is_asset_item = 'No' - raise Exception + if self.doc.slideshow: + from website.helpers.slideshow import get_slideshow + get_slideshow(self) def get_file_details(self, arg = ''): file = webnotes.conn.sql("select file_group, description from tabFile where name = %s", eval(arg)['file_name'], as_dict = 1) @@ -215,35 +244,17 @@ class DocType(DocListController): } return ret + def on_trash(self): + webnotes.conn.sql("""delete from tabBin where item_code=%s""", self.doc.item_code) + webnotes.conn.sql("""delete from `tabStock Ledger Entry` + where item_code=%s and is_cancelled='Yes' """, self.doc.item_code) - def check_if_sle_exists(self): - sle = webnotes.conn.sql("select name from `tabStock Ledger Entry` where item_code = %s and ifnull(is_cancelled, 'No') = 'No'", self.doc.name) - return sle and 'exists' or 'not exists' + if self.doc.page_name: + from webnotes.webutils import clear_cache + clear_cache(self.doc.page_name) def on_rename(self,newdn,olddn): webnotes.conn.sql("update tabItem set item_code = %s where name = %s", (newdn, olddn)) if self.doc.page_name: from webnotes.webutils import clear_cache - clear_cache(self.doc.page_name) - - def prepare_template_args(self): - from website.helpers.product import get_parent_item_groups - self.parent_groups = get_parent_item_groups(self.doc.item_group) + [{"name":self.doc.name}] - self.doc.title = self.doc.item_name - - if self.doc.slideshow: - from website.helpers.slideshow import get_slideshow - get_slideshow(self) - - def cant_change(self): - if not self.doc.fields.get("__islocal"): - vals = webnotes.conn.get_value("Item", self.doc.name, - ["has_serial_no", "is_stock_item", "valuation_method"], as_dict=True) - - if vals and ((self.doc.is_stock_item == "No" and vals.is_stock_item == "Yes") or - vals.has_serial_no != self.doc.has_serial_no or - vals.valuation_method != self.doc.valuation_method): - if self.check_if_sle_exists() == "exists": - webnotes.msgprint(_("As there are existing stock transactions for this \ - item, you can not change the values of 'Has Serial No', \ - 'Is Stock Item' and 'Valuation Method'"), raise_exception=1) + clear_cache(self.doc.page_name) \ No newline at end of file diff --git a/stock/doctype/item/item.txt b/stock/doctype/item/item.txt index e1c04a7083a..5461b3bda9b 100644 --- a/stock/doctype/item/item.txt +++ b/stock/doctype/item/item.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-03-28 10:35:28", + "creation": "2013-03-28 15:56:38", "docstatus": 0, - "modified": "2013-03-20 15:10:12", + "modified": "2013-04-23 11:44:39", "modified_by": "Administrator", "owner": "Administrator" }, @@ -34,6 +34,7 @@ "parent": "Item", "parentfield": "permissions", "parenttype": "DocType", + "permlevel": 0, "read": 1, "submit": 0 }, @@ -47,7 +48,8 @@ "fieldtype": "Section Break", "label": "Item", "no_copy": 0, - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "read_only": 0 }, { "description": "Item will be saved by this name in the data base.", @@ -58,6 +60,7 @@ "label": "Item Code", "oldfieldname": "item_code", "oldfieldtype": "Data", + "read_only": 0, "reqd": 1, "search_index": 0 }, @@ -70,6 +73,7 @@ "label": "Item Name", "oldfieldname": "item_name", "oldfieldtype": "Data", + "read_only": 0, "reqd": 1, "search_index": 1 }, @@ -83,6 +87,7 @@ "oldfieldname": "item_group", "oldfieldtype": "Link", "options": "Item Group", + "read_only": 0, "reqd": 1 }, { @@ -94,7 +99,8 @@ "oldfieldname": "stock_uom", "oldfieldtype": "Link", "options": "UOM", - "reqd": 0 + "read_only": 0, + "reqd": 1 }, { "doctype": "DocField", @@ -106,25 +112,29 @@ "oldfieldtype": "Link", "options": "Brand", "print_hide": 1, + "read_only": 0, "reqd": 0 }, { "doctype": "DocField", "fieldname": "barcode", "fieldtype": "Data", - "label": "Barcode" + "label": "Barcode", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "column_break0", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "image", "fieldtype": "Select", "label": "Image", - "options": "attach_files:" + "options": "attach_files:", + "read_only": 0 }, { "doctype": "DocField", @@ -132,7 +142,8 @@ "fieldtype": "Image", "in_list_view": 1, "label": "Image View", - "options": "image" + "options": "image", + "read_only": 0 }, { "doctype": "DocField", @@ -143,6 +154,7 @@ "label": "Description", "oldfieldname": "description", "oldfieldtype": "Text", + "read_only": 0, "reqd": 1, "search_index": 0 }, @@ -150,21 +162,24 @@ "doctype": "DocField", "fieldname": "description_html", "fieldtype": "Small Text", - "label": "Description HTML" + "label": "Description HTML", + "read_only": 0 }, { "description": "Generates HTML to include selected image in the description", "doctype": "DocField", "fieldname": "add_image", "fieldtype": "Button", - "label": "Generate Description HTML" + "label": "Generate Description HTML", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "inventory", "fieldtype": "Section Break", "label": "Inventory", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "read_only": 0 }, { "default": "Yes", @@ -176,6 +191,7 @@ "oldfieldname": "is_stock_item", "oldfieldtype": "Select", "options": "\nYes\nNo", + "read_only": 0, "reqd": 1 }, { @@ -187,7 +203,8 @@ "label": "Default Reserved Warehouse", "oldfieldname": "default_warehouse", "oldfieldtype": "Link", - "options": "Warehouse" + "options": "Warehouse", + "read_only": 0 }, { "depends_on": "eval:doc.is_stock_item==\"Yes\"", @@ -197,7 +214,8 @@ "fieldtype": "Float", "label": "Allowance Percent", "oldfieldname": "tolerance", - "oldfieldtype": "Currency" + "oldfieldtype": "Currency", + "read_only": 0 }, { "depends_on": "eval:doc.is_stock_item==\"Yes\"", @@ -205,7 +223,8 @@ "fieldname": "valuation_method", "fieldtype": "Select", "label": "Valuation Method", - "options": "\nFIFO\nMoving Average" + "options": "\nFIFO\nMoving Average", + "read_only": 0 }, { "default": "0.00", @@ -217,7 +236,8 @@ "hidden": 0, "label": "Minimum Order Qty", "oldfieldname": "min_order_qty", - "oldfieldtype": "Currency" + "oldfieldtype": "Currency", + "read_only": 0 }, { "depends_on": "eval:doc.is_stock_item==\"Yes\"", @@ -225,6 +245,7 @@ "fieldname": "column_break1", "fieldtype": "Column Break", "oldfieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -238,6 +259,7 @@ "oldfieldname": "is_asset_item", "oldfieldtype": "Select", "options": "\nYes\nNo", + "read_only": 0, "reqd": 1 }, { @@ -250,6 +272,7 @@ "oldfieldname": "has_batch_no", "oldfieldtype": "Select", "options": "\nYes\nNo", + "read_only": 0, "reqd": 1 }, { @@ -264,6 +287,7 @@ "oldfieldname": "has_serial_no", "oldfieldtype": "Select", "options": "\nYes\nNo", + "read_only": 0, "reqd": 1 }, { @@ -273,7 +297,8 @@ "fieldtype": "Data", "label": "Warranty Period (in days)", "oldfieldname": "warranty_period", - "oldfieldtype": "Data" + "oldfieldtype": "Data", + "read_only": 0 }, { "depends_on": "eval:doc.is_stock_item==\"Yes\"", @@ -282,7 +307,8 @@ "fieldtype": "Date", "label": "End of Life", "oldfieldname": "end_of_life", - "oldfieldtype": "Date" + "oldfieldtype": "Date", + "read_only": 0 }, { "depends_on": "eval:doc.is_stock_item==\"Yes\"", @@ -290,7 +316,8 @@ "doctype": "DocField", "fieldname": "net_weight", "fieldtype": "Float", - "label": "Net Weight" + "label": "Net Weight", + "read_only": 0 }, { "depends_on": "eval:doc.is_stock_item==\"Yes\"", @@ -298,14 +325,16 @@ "fieldname": "weight_uom", "fieldtype": "Link", "label": "Weight UOM", - "options": "UOM" + "options": "UOM", + "read_only": 0 }, { "description": "Auto-raise Material Request if quantity goes below re-order level in a warehouse", "doctype": "DocField", "fieldname": "reorder_section", "fieldtype": "Section Break", - "label": "Re-order" + "label": "Re-order", + "read_only": 0 }, { "depends_on": "eval:doc.is_stock_item==\"Yes\"", @@ -314,19 +343,22 @@ "fieldtype": "Float", "label": "Re-Order Level", "oldfieldname": "re_order_level", - "oldfieldtype": "Currency" + "oldfieldtype": "Currency", + "read_only": 0 }, { "depends_on": "eval:doc.is_stock_item==\"Yes\"", "doctype": "DocField", "fieldname": "re_order_qty", "fieldtype": "Float", - "label": "Re-Order Qty" + "label": "Re-Order Qty", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "column_break_31", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "read_only": 0 }, { "depends_on": "eval:doc.is_stock_item==\"Yes\"", @@ -334,27 +366,31 @@ "doctype": "DocField", "fieldname": "email_notify", "fieldtype": "Check", - "label": "Notify by Email on Re-order" + "label": "Notify by Email on Re-order", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "section_break_31", "fieldtype": "Section Break", - "options": "Simple" + "options": "Simple", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "item_reorder", "fieldtype": "Table", "label": "Warehouse-wise Item Reorder", - "options": "Item Reorder" + "options": "Item Reorder", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "purchase_details", "fieldtype": "Section Break", "label": "Purchase Details", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "read_only": 0 }, { "default": "Yes", @@ -366,6 +402,7 @@ "oldfieldname": "is_purchase_item", "oldfieldtype": "Select", "options": "\nYes\nNo", + "read_only": 0, "reqd": 1 }, { @@ -377,7 +414,8 @@ "label": "Lead Time Days", "no_copy": 1, "oldfieldname": "lead_time_days", - "oldfieldtype": "Int" + "oldfieldtype": "Int", + "read_only": 0 }, { "depends_on": "eval:doc.is_purchase_item==\"Yes\"", @@ -388,7 +426,8 @@ "label": "Default Expense Account", "oldfieldname": "purchase_account", "oldfieldtype": "Link", - "options": "Account" + "options": "Account", + "read_only": 0 }, { "depends_on": "eval:doc.is_purchase_item==\"Yes\"", @@ -399,7 +438,8 @@ "label": "Default Cost Center", "oldfieldname": "cost_center", "oldfieldtype": "Link", - "options": "Cost Center" + "options": "Cost Center", + "read_only": 0 }, { "depends_on": "eval:doc.is_purchase_item==\"Yes\"", @@ -419,7 +459,8 @@ "fieldtype": "Float", "label": "Standard Rate", "oldfieldname": "standard_rate", - "oldfieldtype": "Currency" + "oldfieldtype": "Currency", + "read_only": 0 }, { "depends_on": "eval:doc.is_purchase_item==\"Yes\"", @@ -427,6 +468,7 @@ "fieldname": "column_break2", "fieldtype": "Column Break", "oldfieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -438,21 +480,24 @@ "no_copy": 1, "oldfieldname": "uom_conversion_details", "oldfieldtype": "Table", - "options": "UOM Conversion Detail" + "options": "UOM Conversion Detail", + "read_only": 0 }, { "depends_on": "eval:doc.is_purchase_item==\"Yes\"", "doctype": "DocField", "fieldname": "manufacturer", "fieldtype": "Data", - "label": "Manufacturer" + "label": "Manufacturer", + "read_only": 0 }, { "depends_on": "eval:doc.is_purchase_item==\"Yes\"", "doctype": "DocField", "fieldname": "manufacturer_part_no", "fieldtype": "Data", - "label": "Manufacturer Part Number" + "label": "Manufacturer Part Number", + "read_only": 0 }, { "depends_on": "eval:doc.is_purchase_item==\"Yes\"", @@ -460,14 +505,16 @@ "fieldname": "item_supplier_details", "fieldtype": "Table", "label": "Item Supplier Details", - "options": "Item Supplier" + "options": "Item Supplier", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "sales_details", "fieldtype": "Section Break", "label": "Sales Details", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "read_only": 0 }, { "default": "Yes", @@ -480,6 +527,7 @@ "oldfieldname": "is_sales_item", "oldfieldtype": "Select", "options": "\nYes\nNo", + "read_only": 0, "reqd": 1 }, { @@ -494,6 +542,7 @@ "oldfieldname": "is_service_item", "oldfieldtype": "Select", "options": "\nYes\nNo", + "read_only": 0, "reqd": 1 }, { @@ -507,6 +556,7 @@ "oldfieldname": "is_sample_item", "oldfieldtype": "Select", "options": "\nYes\nNo", + "read_only": 0, "reqd": 1 }, { @@ -516,7 +566,8 @@ "fieldtype": "Float", "label": "Max Discount (%)", "oldfieldname": "max_discount", - "oldfieldtype": "Currency" + "oldfieldtype": "Currency", + "read_only": 0 }, { "depends_on": "eval:doc.is_sales_item==\"Yes\"", @@ -524,7 +575,8 @@ "fieldname": "default_income_account", "fieldtype": "Link", "label": "Default Income Account", - "options": "Account" + "options": "Account", + "read_only": 0 }, { "depends_on": "eval:doc.is_sales_item==\"Yes\"", @@ -532,7 +584,8 @@ "fieldname": "default_sales_cost_center", "fieldtype": "Link", "label": "Cost Center", - "options": "Cost Center" + "options": "Cost Center", + "read_only": 0 }, { "depends_on": "eval:doc.is_sales_item==\"Yes\"", @@ -542,7 +595,8 @@ "hidden": 1, "label": "Sales Rate", "oldfieldname": "sales_rate", - "oldfieldtype": "Currency" + "oldfieldtype": "Currency", + "read_only": 0 }, { "depends_on": "eval:doc.is_sales_item==\"Yes\"", @@ -550,6 +604,7 @@ "fieldname": "column_break3", "fieldtype": "Column Break", "oldfieldtype": "Column Break", + "read_only": 0, "width": "50%" }, { @@ -559,14 +614,16 @@ "fieldname": "item_customer_details", "fieldtype": "Table", "label": "Customer Codes", - "options": "Item Customer Detail" + "options": "Item Customer Detail", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "item_tax_section_break", "fieldtype": "Section Break", "label": "Item Tax", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "read_only": 0 }, { "doctype": "DocField", @@ -575,13 +632,15 @@ "label": "Item Tax1", "oldfieldname": "item_tax", "oldfieldtype": "Table", - "options": "Item Tax" + "options": "Item Tax", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "price_list_section", "fieldtype": "Section Break", - "label": "Price Lists and Rates" + "label": "Price Lists and Rates", + "read_only": 0 }, { "description": "Create a price list from Price List master and enter standard ref rates against each of them. On selection of a price list in Quotation, Sales Order or Delivery Note, corresponding ref rate will be fetched for this item.", @@ -591,14 +650,16 @@ "label": "Item Prices", "oldfieldname": "ref_rate_details", "oldfieldtype": "Table", - "options": "Item Price" + "options": "Item Price", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "inspection_criteria", "fieldtype": "Section Break", "label": "Inspection Criteria", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "read_only": 0 }, { "default": "No", @@ -610,6 +671,7 @@ "oldfieldname": "inspection_required", "oldfieldtype": "Select", "options": "\nYes\nNo", + "read_only": 0, "reqd": 1 }, { @@ -621,14 +683,16 @@ "label": "Item Quality Inspection Parameter", "oldfieldname": "item_specification_details", "oldfieldtype": "Table", - "options": "Item Quality Inspection Parameter" + "options": "Item Quality Inspection Parameter", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "manufacturing", "fieldtype": "Section Break", "label": "Manufacturing", - "oldfieldtype": "Section Break" + "oldfieldtype": "Section Break", + "read_only": 0 }, { "default": "No", @@ -640,6 +704,7 @@ "oldfieldname": "is_manufactured_item", "oldfieldtype": "Select", "options": "\nYes\nNo", + "read_only": 0, "reqd": 1 }, { @@ -665,6 +730,7 @@ "oldfieldname": "is_pro_applicable", "oldfieldtype": "Select", "options": "\nYes\nNo", + "read_only": 0, "reqd": 1 }, { @@ -677,6 +743,7 @@ "oldfieldname": "is_sub_contracted_item", "oldfieldtype": "Select", "options": "\nYes\nNo", + "read_only": 0, "reqd": 1 }, { @@ -687,19 +754,22 @@ "in_filter": 1, "label": "Customer Code", "no_copy": 1, - "print_hide": 1 + "print_hide": 1, + "read_only": 0 }, { "doctype": "DocField", "fieldname": "website_section", "fieldtype": "Section Break", - "label": "Website" + "label": "Website", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "show_in_website", "fieldtype": "Check", - "label": "Show in Website" + "label": "Show in Website", + "read_only": 0 }, { "depends_on": "show_in_website", @@ -717,6 +787,7 @@ "fieldname": "weightage", "fieldtype": "Int", "label": "Weightage", + "read_only": 0, "search_index": 1 }, { @@ -726,7 +797,8 @@ "fieldname": "slideshow", "fieldtype": "Link", "label": "Slideshow", - "options": "Website Slideshow" + "options": "Website Slideshow", + "read_only": 0 }, { "depends_on": "show_in_website", @@ -735,12 +807,14 @@ "fieldname": "website_image", "fieldtype": "Select", "label": "Image", - "options": "attach_files:" + "options": "attach_files:", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "cb72", - "fieldtype": "Column Break" + "fieldtype": "Column Break", + "read_only": 0 }, { "depends_on": "show_in_website", @@ -749,7 +823,8 @@ "fieldname": "website_price_list", "fieldtype": "Link", "label": "Website Price List", - "options": "Price List" + "options": "Price List", + "read_only": 0 }, { "depends_on": "show_in_website", @@ -758,7 +833,8 @@ "fieldname": "website_warehouse", "fieldtype": "Link", "label": "Website Warehouse", - "options": "Warehouse" + "options": "Warehouse", + "read_only": 0 }, { "depends_on": "show_in_website", @@ -767,19 +843,22 @@ "fieldname": "website_item_groups", "fieldtype": "Table", "label": "Website Item Groups", - "options": "Website Item Group" + "options": "Website Item Group", + "read_only": 0 }, { "depends_on": "show_in_website", "doctype": "DocField", "fieldname": "sb72", - "fieldtype": "Section Break" + "fieldtype": "Section Break", + "read_only": 0 }, { "doctype": "DocField", "fieldname": "copy_from_item_group", "fieldtype": "Button", - "label": "Copy From Item Group" + "label": "Copy From Item Group", + "read_only": 0 }, { "depends_on": "show_in_website", @@ -787,85 +866,39 @@ "fieldname": "item_website_specifications", "fieldtype": "Table", "label": "Item Website Specifications", - "options": "Item Website Specification" + "options": "Item Website Specification", + "read_only": 0 }, { "depends_on": "show_in_website", "doctype": "DocField", "fieldname": "web_long_description", "fieldtype": "Text Editor", - "label": "Website Description" - }, - { - "cancel": 0, - "create": 0, - "doctype": "DocPerm", - "permlevel": 1, - "report": 0, - "role": "Material Manager", - "write": 0 - }, - { - "cancel": 0, - "create": 0, - "doctype": "DocPerm", - "permlevel": 0, - "report": 1, - "role": "Material Manager", - "write": 0 - }, - { - "cancel": 0, - "create": 0, - "doctype": "DocPerm", - "permlevel": 1, - "report": 0, - "role": "Material User", - "write": 0 - }, - { - "cancel": 0, - "create": 0, - "doctype": "DocPerm", - "permlevel": 0, - "report": 1, - "role": "Material User", - "write": 0 + "label": "Website Description", + "read_only": 0 }, { "cancel": 1, "create": 1, "doctype": "DocPerm", - "permlevel": 0, - "report": 1, "role": "Material Master Manager", - "write": 1 + "write": 1, + "report": 1 }, { "cancel": 0, "create": 0, "doctype": "DocPerm", - "permlevel": 1, - "report": 0, - "role": "Material Master Manager", - "write": 0 - }, - { - "cancel": 1, - "create": 1, - "doctype": "DocPerm", - "permlevel": 0, - "report": 1, - "role": "System Manager", - "write": 1 + "role": "Material Manager", + "write": 0, + "report": 1 }, { "cancel": 0, "create": 0, "doctype": "DocPerm", - "permlevel": 1, - "report": 0, - "role": "System Manager", - "write": 0 + "role": "Material User", + "write": 0, + "report": 1 } ] \ No newline at end of file