diff --git a/accounts/report/budget_variance_report/budget_variance_report.py b/accounts/report/budget_variance_report/budget_variance_report.py index 158ff3a818..015e2c01b3 100644 --- a/accounts/report/budget_variance_report/budget_variance_report.py +++ b/accounts/report/budget_variance_report/budget_variance_report.py @@ -47,18 +47,20 @@ def get_columns(filters): msgprint(_("Please specify") + ": " + label, raise_exception=True) - columns = ["Cost Center:Link/Cost Center:100", "Account:Link/Account:100"] + columns = ["Cost Center:Link/Cost Center:120", "Account:Link/Account:120"] group_months = False if filters["period"] == "Monthly" else True for from_date, to_date in get_period_date_ranges(filters["period"], filters["fiscal_year"]): for label in ["Target (%s)", "Actual (%s)", "Variance (%s)"]: if group_months: - columns.append(label % (from_date.strftime("%b") + " - " + to_date.strftime("%b"))) + label = label % (from_date.strftime("%b") + " - " + to_date.strftime("%b")) else: - columns.append(label % from_date.strftime("%b")) + label = label % from_date.strftime("%b") + + columns.append(label+":Float:120") - return columns + ["Total Target::80", "Total Actual::80", "Total Variance::80"] + return columns + ["Total Target::120", "Total Actual::120", "Total Variance::120"] #Get cost center & target details def get_costcenter_target_details(filters): @@ -66,19 +68,17 @@ def get_costcenter_target_details(filters): cc.parent_cost_center, bd.account, bd.budget_allocated from `tabCost Center` cc, `tabBudget Detail` bd where bd.parent=cc.name and bd.fiscal_year=%s and - cc.company=%s and ifnull(cc.distribution_id, '')!='' - order by cc.name""" % ('%s', '%s'), + cc.company=%s order by cc.name""" % ('%s', '%s'), (filters.get("fiscal_year"), filters.get("company")), as_dict=1) #Get target distribution details of accounts of cost center def get_target_distribution_details(filters): target_details = {} - for d in webnotes.conn.sql("""select bdd.month, bdd.percentage_allocation \ - from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd, \ - `tabCost Center` cc where bdd.parent=bd.name and cc.distribution_id=bd.name and \ - bd.fiscal_year=%s""", (filters["fiscal_year"]), as_dict=1): - target_details.setdefault(d.month, d) + for d in webnotes.conn.sql("""select bd.name, bdd.month, bdd.percentage_allocation \ + from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd + where bdd.parent=bd.name and bd.fiscal_year=%s""", (filters["fiscal_year"]), as_dict=1): + target_details.setdefault(d.name, {}).setdefault(d.month, d.percentage_allocation) return target_details @@ -99,15 +99,19 @@ def get_costcenter_account_month_map(filters): cam_map = {} for ccd in costcenter_target_details: - for month in tdd: + for month_id in range(1, 13): + month = datetime.date(2013, month_id, 1).strftime('%B') + cam_map.setdefault(ccd.name, {}).setdefault(ccd.account, {})\ - .setdefault(month, webnotes._dict({ - "target": 0.0, "actual": 0.0 - })) + .setdefault(month, webnotes._dict({ + "target": 0.0, "actual": 0.0 + })) tav_dict = cam_map[ccd.name][ccd.account][month] - tav_dict.target = flt(ccd.budget_allocated) * \ - (tdd[month]["percentage_allocation"]/100) + month_percentage = ccd.distribution_id and \ + tdd.get(ccd.distribution_id, {}).get(month, 0) or 100.0/12 + + tav_dict.target = flt(flt(ccd.budget_allocated) * month_percentage /100) for ad in actual_details: if ad.month_name == month and ad.account == ccd.account \ diff --git a/hr/doctype/leave_application/leave_application.py b/hr/doctype/leave_application/leave_application.py index 14c8b1f212..8a2df1e9c4 100755 --- a/hr/doctype/leave_application/leave_application.py +++ b/hr/doctype/leave_application/leave_application.py @@ -115,7 +115,8 @@ class DocType(DocListController): self.doc.leave_balance = get_leave_balance(self.doc.employee, self.doc.leave_type, self.doc.fiscal_year)["leave_balance"] - if self.doc.leave_balance - self.doc.total_leave_days < 0: + if self.doc.status != "Rejected" \ + and self.doc.leave_balance - self.doc.total_leave_days < 0: #check if this leave type allow the remaining balance to be in negative. If yes then warn the user and continue to save else warn the user and don't save. msgprint("There is not enough leave balance for Leave Type: %s" % \ (self.doc.leave_type,), diff --git a/manufacturing/doctype/production_order/production_order.js b/manufacturing/doctype/production_order/production_order.js index 012c27980d..f680776a56 100644 --- a/manufacturing/doctype/production_order/production_order.js +++ b/manufacturing/doctype/production_order/production_order.js @@ -61,30 +61,25 @@ cur_frm.cscript['Unstop Production Order'] = function() { } cur_frm.cscript['Transfer Raw Materials'] = function() { - var doc = cur_frm.doc; - cur_frm.cscript.make_se(doc, 'Material Transfer'); + cur_frm.cscript.make_se('Material Transfer'); } cur_frm.cscript['Update Finished Goods'] = function() { - var doc = cur_frm.doc; - cur_frm.cscript.make_se(doc, 'Manufacture/Repack'); + cur_frm.cscript.make_se('Manufacture/Repack'); } -cur_frm.cscript.make_se = function(doc, purpose) { - var se = wn.model.get_new_doc("Stock Entry"); - se.purpose = purpose; - se.production_order = doc.name; - if(purpose==="Material Transfer") { - se.to_warehouse = doc.wip_warehouse; - } else { - se.from_warehouse = doc.wip_warehouse; - se.to_warehouse = doc.fg_warehouse; - } - se.company = doc.company; - se.fg_completed_qty = doc.qty - doc.produced_qty; - se.bom_no = doc.bom_no; - se.use_multi_level_bom = doc.use_multi_level_bom; - loaddoc('Stock Entry', se.name); +cur_frm.cscript.make_se = function(purpose) { + wn.call({ + method:"manufacturing.doctype.production_order.production_order.make_stock_entry", + args: { + "production_order_id": cur_frm.doc.name, + "purpose": purpose + }, + callback: function(r) { + var doclist = wn.model.sync(r.message); + wn.set_route("Form", doclist[0].doctype, doclist[0].name); + } + }) } cur_frm.fields_dict['production_item'].get_query = function(doc) { diff --git a/manufacturing/doctype/production_order/production_order.py b/manufacturing/doctype/production_order/production_order.py index 2f311808a3..90a74e9110 100644 --- a/manufacturing/doctype/production_order/production_order.py +++ b/manufacturing/doctype/production_order/production_order.py @@ -137,4 +137,23 @@ def get_item_details(item): if bom: res.bom_no = bom[0][0] - return res \ No newline at end of file + return res + +@webnotes.whitelist() +def make_stock_entry(production_order_id, purpose): + production_order = webnotes.bean("Production Order", production_order_id) + + stock_entry = webnotes.new_bean("Stock Entry") + stock_entry.doc.purpose = purpose + stock_entry.doc.production_order = production_order_id + stock_entry.doc.company = production_order.doc.company + stock_entry.doc.bom_no = production_order.doc.bom_no + stock_entry.doc.fg_completed_qty = flt(production_order.doc.qty) - flt(production_order.doc.produced_qty) + + if purpose=="Material Transfer": + stock_entry.doc.to_warehouse = production_order.doc.wip_warehouse + else: + stock_entry.doc.from_warehouse = production_order.doc.wip_warehouse + stock_entry.doc.to_warehouse = production_order.doc.fg_warehouse + + return [d.fields for d in stock_entry.doclist] diff --git a/manufacturing/page/manufacturing_home/manufacturing_home.js b/manufacturing/page/manufacturing_home/manufacturing_home.js index b29bbbbeed..a2a4eaa261 100644 --- a/manufacturing/page/manufacturing_home/manufacturing_home.js +++ b/manufacturing/page/manufacturing_home/manufacturing_home.js @@ -64,11 +64,26 @@ wn.module_page["Manufacturing"] = [ right: true, icon: "icon-list", items: [ + { + "label":wn._("Open Production Orders"), + route: "query-report/Open Production Orders", + doctype:"Production Order" + }, + { + "label":wn._("Production Orders in Progress"), + route: "query-report/Production Orders in Progress", + doctype:"Production Order" + }, { "label":wn._("Issued Items Against Production Order"), route: "query-report/Issued Items Against Production Order", doctype:"Production Order" }, + { + "label":wn._("Completed Production Orders"), + route: "query-report/Completed Production Orders", + doctype:"Production Order" + }, ] } ] diff --git a/manufacturing/report/completed_production_orders/__init__.py b/manufacturing/report/completed_production_orders/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/manufacturing/report/completed_production_orders/completed_production_orders.txt b/manufacturing/report/completed_production_orders/completed_production_orders.txt new file mode 100644 index 0000000000..facda7e903 --- /dev/null +++ b/manufacturing/report/completed_production_orders/completed_production_orders.txt @@ -0,0 +1,22 @@ +[ + { + "creation": "2013-08-12 12:44:27", + "docstatus": 0, + "modified": "2013-08-12 12:44:27", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "query": "SELECT\n `tabProduction Order`.name as \"Production Order:Link/Production Order:200\",\n `tabProduction Order`.creation as \"Date:Date:120\",\n `tabProduction Order`.production_item as \"Item:Link/Item:150\",\n `tabProduction Order`.qty as \"To Produce:Int:100\",\n `tabProduction Order`.produced_qty as \"Produced:Int:100\"\nFROM\n `tabProduction Order`\nWHERE\n `tabProduction Order`.docstatus=1\n AND ifnull(`tabProduction Order`.produced_qty,0) = `tabProduction Order`.qty", + "ref_doctype": "Production Order", + "report_name": "Completed Production Orders", + "report_type": "Query Report" + }, + { + "doctype": "Report", + "name": "Completed Production Orders" + } +] \ No newline at end of file diff --git a/manufacturing/report/open_production_orders/__init__.py b/manufacturing/report/open_production_orders/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/manufacturing/report/open_production_orders/open_production_orders.txt b/manufacturing/report/open_production_orders/open_production_orders.txt new file mode 100644 index 0000000000..f92bdd32d3 --- /dev/null +++ b/manufacturing/report/open_production_orders/open_production_orders.txt @@ -0,0 +1,22 @@ +[ + { + "creation": "2013-08-12 12:32:30", + "docstatus": 0, + "modified": "2013-08-12 12:42:29", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "query": "SELECT\n `tabProduction Order`.name as \"Production Order:Link/Production Order:200\",\n `tabProduction Order`.creation as \"Date:Date:120\",\n `tabProduction Order`.production_item as \"Item:Link/Item:150\",\n `tabProduction Order`.qty as \"To Produce:Int:100\",\n `tabProduction Order`.produced_qty as \"Produced:Int:100\"\nFROM\n `tabProduction Order`\nWHERE\n `tabProduction Order`.docstatus=1\n AND ifnull(`tabProduction Order`.produced_qty,0) < `tabProduction Order`.qty\n AND NOT EXISTS (SELECT name from `tabStock Entry` where production_order =`tabProduction Order`.name) ", + "ref_doctype": "Production Order", + "report_name": "Open Production Orders", + "report_type": "Query Report" + }, + { + "doctype": "Report", + "name": "Open Production Orders" + } +] \ No newline at end of file diff --git a/manufacturing/report/production_orders_in_progress/__init__.py b/manufacturing/report/production_orders_in_progress/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/manufacturing/report/production_orders_in_progress/production_orders_in_progress.txt b/manufacturing/report/production_orders_in_progress/production_orders_in_progress.txt new file mode 100644 index 0000000000..3d3493f8a1 --- /dev/null +++ b/manufacturing/report/production_orders_in_progress/production_orders_in_progress.txt @@ -0,0 +1,22 @@ +[ + { + "creation": "2013-08-12 12:43:47", + "docstatus": 0, + "modified": "2013-08-12 12:43:47", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "query": "SELECT\n `tabProduction Order`.name as \"Production Order:Link/Production Order:200\",\n `tabProduction Order`.creation as \"Date:Date:120\",\n `tabProduction Order`.production_item as \"Item:Link/Item:150\",\n `tabProduction Order`.qty as \"To Produce:Int:100\",\n `tabProduction Order`.produced_qty as \"Produced:Int:100\"\nFROM\n `tabProduction Order`\nWHERE\n `tabProduction Order`.docstatus=1\n AND ifnull(`tabProduction Order`.produced_qty,0) < `tabProduction Order`.qty\n AND EXISTS (SELECT name from `tabStock Entry` where production_order =`tabProduction Order`.name) ", + "ref_doctype": "Production Order", + "report_name": "Production Orders in Progress", + "report_type": "Query Report" + }, + { + "doctype": "Report", + "name": "Production Orders in Progress" + } +] \ No newline at end of file diff --git a/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.py b/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.py index 96c147fd64..6fdafe083d 100644 --- a/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.py +++ b/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.py @@ -8,6 +8,7 @@ from webnotes.utils import flt import time from accounts.utils import get_fiscal_year from controllers.trends import get_period_date_ranges, get_period_month_ranges +from webnotes.model.meta import get_field_precision def execute(filters=None): if not filters: filters = {} @@ -16,10 +17,7 @@ def execute(filters=None): period_month_ranges = get_period_month_ranges(filters["period"], filters["fiscal_year"]) sim_map = get_salesperson_item_month_map(filters) - precision = webnotes.conn.get_value("Global Defaults", None, "float_precision") or 2 - data = [] - for salesperson, salesperson_items in sim_map.items(): for item_group, monthwise_data in salesperson_items.items(): row = [salesperson, item_group] @@ -29,7 +27,7 @@ def execute(filters=None): for month in relevant_months: month_data = monthwise_data.get(month, {}) for i, fieldname in enumerate(["target", "achieved", "variance"]): - value = flt(month_data.get(fieldname), precision) + value = flt(month_data.get(fieldname)) period_data[i] += value totals[i] += value period_data[2] = period_data[0] - period_data[1] @@ -47,37 +45,37 @@ def get_columns(filters): msgprint(_("Please specify") + ": " + label, raise_exception=True) - columns = ["Sales Person:Link/Sales Person:80", "Item Group:Link/Item Group:80"] + columns = ["Sales Person:Link/Sales Person:120", "Item Group:Link/Item Group:120"] group_months = False if filters["period"] == "Monthly" else True for from_date, to_date in get_period_date_ranges(filters["period"], filters["fiscal_year"]): for label in ["Target (%s)", "Achieved (%s)", "Variance (%s)"]: if group_months: - columns.append(label % (from_date.strftime("%b") + " - " + to_date.strftime("%b"))) + label = label % (from_date.strftime("%b") + " - " + to_date.strftime("%b")) else: - columns.append(label % from_date.strftime("%b")) + label = label % from_date.strftime("%b") + + columns.append(label+":Float:120") - return columns + ["Total Target::80", "Total Achieved::80", "Total Variance::80"] + return columns + ["Total Target::120", "Total Achieved::120", "Total Variance::120"] #Get sales person & item group details def get_salesperson_details(filters): return webnotes.conn.sql("""select sp.name, td.item_group, td.target_qty, td.target_amount, sp.distribution_id from `tabSales Person` sp, `tabTarget Detail` td - where td.parent=sp.name and td.fiscal_year=%s and - ifnull(sp.distribution_id, '')!='' order by sp.name""", + where td.parent=sp.name and td.fiscal_year=%s order by sp.name""", (filters["fiscal_year"]), as_dict=1) #Get target distribution details of item group def get_target_distribution_details(filters): target_details = {} - for d in webnotes.conn.sql("""select bdd.month, bdd.percentage_allocation \ - from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd, \ - `tabTerritory` t where bdd.parent=bd.name and t.distribution_id=bd.name and \ - bd.fiscal_year=%s""", (filters["fiscal_year"]), as_dict=1): - target_details.setdefault(d.month, d) + for d in webnotes.conn.sql("""select bd.name, bdd.month, bdd.percentage_allocation + from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd + where bdd.parent=bd.name and bd.fiscal_year=%s""", (filters["fiscal_year"]), as_dict=1): + target_details.setdefault(d.name, {}).setdefault(d.month, d.percentage_allocation) return target_details @@ -94,32 +92,33 @@ def get_achieved_details(filters): (start_date, end_date), as_dict=1) def get_salesperson_item_month_map(filters): + import datetime salesperson_details = get_salesperson_details(filters) tdd = get_target_distribution_details(filters) achieved_details = get_achieved_details(filters) sim_map = {} - for sd in salesperson_details: - for month in tdd: + for month_id in range(1, 13): + month = datetime.date(2013, month_id, 1).strftime('%B') sim_map.setdefault(sd.name, {}).setdefault(sd.item_group, {})\ - .setdefault(month, webnotes._dict({ - "target": 0.0, "achieved": 0.0 - })) + .setdefault(month, webnotes._dict({ + "target": 0.0, "achieved": 0.0 + })) tav_dict = sim_map[sd.name][sd.item_group][month] - + month_percentage = sd.distribution_id and \ + tdd.get(sd.distribution_id, {}).get(month, 0) or 100.0/12 + for ad in achieved_details: if (filters["target_on"] == "Quantity"): - tav_dict.target = flt(sd.target_qty) * \ - (tdd[month]["percentage_allocation"]/100) + tav_dict.target = flt(flt(sd.target_qty) * month_percentage/100, 2) if ad.month_name == month and get_item_group(ad.item_code) == sd.item_group \ and ad.sales_person == sd.name: tav_dict.achieved += ad.qty if (filters["target_on"] == "Amount"): - tav_dict.target = flt(sd.target_amount) * \ - (tdd[month]["percentage_allocation"]/100) + tav_dict.target = flt(flt(sd.target_amount) * month_percentage/100, 2) if ad.month_name == month and get_item_group(ad.item_code) == sd.item_group \ and ad.sales_person == sd.name: tav_dict.achieved += ad.amount diff --git a/selling/report/territory_target_variance_item_group_wise/territory_target_variance_item_group_wise.py b/selling/report/territory_target_variance_item_group_wise/territory_target_variance_item_group_wise.py index 4a8cc7c888..829f7818e3 100644 --- a/selling/report/territory_target_variance_item_group_wise/territory_target_variance_item_group_wise.py +++ b/selling/report/territory_target_variance_item_group_wise/territory_target_variance_item_group_wise.py @@ -46,37 +46,36 @@ def get_columns(filters): label = (" ".join(fieldname.split("_"))).title() msgprint(_("Please specify") + ": " + label, raise_exception=True) - columns = ["Territory:Link/Territory:80", "Item Group:Link/Item Group:80"] + columns = ["Territory:Link/Territory:120", "Item Group:Link/Item Group:120"] group_months = False if filters["period"] == "Monthly" else True for from_date, to_date in get_period_date_ranges(filters["period"], filters["fiscal_year"]): for label in ["Target (%s)", "Achieved (%s)", "Variance (%s)"]: if group_months: - columns.append(label % (from_date.strftime("%b") + " - " + to_date.strftime("%b"))) + label = label % (from_date.strftime("%b") + " - " + to_date.strftime("%b")) else: - columns.append(label % from_date.strftime("%b")) + label = label % from_date.strftime("%b") + columns.append(label+":Float:120") - return columns + ["Total Target::80", "Total Achieved::80", "Total Variance::80"] + return columns + ["Total Target::120", "Total Achieved::120", "Total Variance::120"] #Get territory & item group details def get_territory_details(filters): return webnotes.conn.sql("""select t.name, td.item_group, td.target_qty, td.target_amount, t.distribution_id from `tabTerritory` t, `tabTarget Detail` td - where td.parent=t.name and td.fiscal_year=%s and - ifnull(t.distribution_id, '')!='' order by t.name""", + where td.parent=t.name and td.fiscal_year=%s order by t.name""", (filters["fiscal_year"]), as_dict=1) #Get target distribution details of item group def get_target_distribution_details(filters): target_details = {} - for d in webnotes.conn.sql("""select bdd.month, bdd.percentage_allocation \ - from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd, \ - `tabTerritory` t where bdd.parent=bd.name and t.distribution_id=bd.name and \ - bd.fiscal_year=%s""", (filters["fiscal_year"]), as_dict=1): - target_details.setdefault(d.month, d) + for d in webnotes.conn.sql("""select bd.name, bdd.month, bdd.percentage_allocation + from `tabBudget Distribution Detail` bdd, `tabBudget Distribution` bd + where bdd.parent=bd.name and bd.fiscal_year=%s""", (filters["fiscal_year"]), as_dict=1): + target_details.setdefault(d.name, {}).setdefault(d.month, d.percentage_allocation) return target_details @@ -99,25 +98,27 @@ def get_territory_item_month_map(filters): tim_map = {} for td in territory_details: - for month in tdd: + for month_id in range(1, 13): + month = datetime.date(2013, month_id, 1).strftime('%B') + tim_map.setdefault(td.name, {}).setdefault(td.item_group, {})\ - .setdefault(month, webnotes._dict({ - "target": 0.0, "achieved": 0.0 - })) + .setdefault(month, webnotes._dict({ + "target": 0.0, "achieved": 0.0 + })) tav_dict = tim_map[td.name][td.item_group][month] + month_percentage = td.distribution_id and \ + tdd.get(td.distribution_id, {}).get(month, 0) or 100.0/12 for ad in achieved_details: if (filters["target_on"] == "Quantity"): - tav_dict.target = flt(td.target_qty) * \ - (tdd[month]["percentage_allocation"]/100) + tav_dict.target = flt(flt(td.target_qty) * month_percentage /100) if ad.month_name == month and get_item_group(ad.item_code) == td.item_group \ and ad.territory == td.name: tav_dict.achieved += ad.qty if (filters["target_on"] == "Amount"): - tav_dict.target = flt(td.target_amount) * \ - (tdd[month]["percentage_allocation"]/100) + tav_dict.target = flt(flt(td.target_amount) * month_percentage / 100) if ad.month_name == month and get_item_group(ad.item_code) == td.item_group \ and ad.territory == td.name: tav_dict.achieved += ad.amount diff --git a/stock/doctype/stock_entry/stock_entry.js b/stock/doctype/stock_entry/stock_entry.js index 4fa6c6c55a..53998f83e8 100644 --- a/stock/doctype/stock_entry/stock_entry.js +++ b/stock/doctype/stock_entry/stock_entry.js @@ -4,34 +4,7 @@ wn.require("public/app/js/controllers/stock_controller.js"); wn.provide("erpnext.stock"); -erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ - onload: function() { - this.set_default_account(); - }, - - set_default_account: function() { - var me = this; - - if (cint(wn.defaults.get_default("auto_inventory_accounting")) && !this.frm.doc.expense_adjustment_account) { - if (this.frm.doc.purpose == "Sales Return") - account_for = "stock_in_hand_account"; - else if (this.frm.doc.purpose == "Purchase Return") - account_for = "stock_received_but_not_billed"; - else account_for = "stock_adjustment_account"; - - return this.frm.call({ - method: "accounts.utils.get_company_default", - args: { - "fieldname": account_for, - "company": this.frm.doc.company - }, - callback: function(r) { - if (!r.exc) me.frm.set_value("expense_adjustment_account", r.message); - } - }); - } - }, - +erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ setup: function() { var me = this; @@ -80,11 +53,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ }, onload_post_render: function() { - if(this.frm.doc.__islocal && (this.frm.doc.production_order || this.frm.doc.bom_no) - && !getchildren('Stock Entry Detail', this.frm.doc.name, 'mtn_details').length) { - // if production order / bom is mentioned, get items - this.get_items(); - } + this.set_default_account(); }, refresh: function() { @@ -115,6 +84,33 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ after_cancel: function() { this.clean_up(); }, + + set_default_account: function() { + var me = this; + + if (cint(wn.defaults.get_default("auto_inventory_accounting")) && !this.frm.doc.expense_adjustment_account) { + var account_for = "stock_adjustment_account"; + if (this.frm.doc.purpose == "Sales Return") + account_for = "stock_in_hand_account"; + else if (this.frm.doc.purpose == "Purchase Return") + account_for = "stock_received_but_not_billed"; + + return this.frm.call({ + method: "accounts.utils.get_company_default", + args: { + "fieldname": account_for, + "company": this.frm.doc.company + }, + callback: function(r) { + if (!r.exc) me.frm.set_value("expense_adjustment_account", r.message); + + me.get_items(); + } + }); + } else { + me.get_items(); + } + }, clean_up: function() { // Clear Production Order record from locals, because it is updated via Stock Entry @@ -126,13 +122,17 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ }, get_items: function() { - return this.frm.call({ - doc: this.frm.doc, - method: "get_items", - callback: function(r) { - if(!r.exc) refresh_field("mtn_details"); - } - }); + if(this.frm.doc.__islocal && (this.frm.doc.production_order || this.frm.doc.bom_no) + && !getchildren('Stock Entry Detail', this.frm.doc.name, 'mtn_details').length) { + // if production order / bom is mentioned, get items + return this.frm.call({ + doc: this.frm.doc, + method: "get_items", + callback: function(r) { + if(!r.exc) refresh_field("mtn_details"); + } + }); + } }, qty: function(doc, cdt, cdn) { @@ -212,7 +212,6 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ }); loaddoc("Journal Voucher", jv_name); } - } }); } diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index 66d1dbf7c2..b702316d9b 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -19,6 +19,7 @@ sql = webnotes.conn.sql class NotUpdateStockError(webnotes.ValidationError): pass class StockOverReturnError(webnotes.ValidationError): pass +class IncorrectValuationRateError(webnotes.ValidationError): pass from controllers.stock_controller import StockController @@ -245,7 +246,7 @@ class DocType(StockController): def validate_incoming_rate(self): for d in getlist(self.doclist, 'mtn_details'): if d.t_warehouse: - self.validate_value("incoming_rate", ">", 0, d) + self.validate_value("incoming_rate", ">", 0, d, raise_exception=IncorrectValuationRateError) def validate_bom(self): for d in getlist(self.doclist, 'mtn_details'): diff --git a/stock/stock_ledger.py b/stock/stock_ledger.py index 4dcca6708e..f0619c7384 100644 --- a/stock/stock_ledger.py +++ b/stock/stock_ledger.py @@ -8,6 +8,7 @@ from stock.utils import get_valuation_method import json # future reposting +class NegativeStockError(webnotes.ValidationError): pass _exceptions = [] def update_entries_after(args, verbose=1): @@ -253,9 +254,9 @@ def _raise_exceptions(args, verbose=1): _exceptions[0]["voucher_type"], _exceptions[0]["voucher_no"], abs(deficiency)) if verbose: - msgprint(msg, raise_exception=1) + msgprint(msg, raise_exception=NegativeStockError) else: - raise webnotes.ValidationError, msg + raise NegativeStockError, msg def get_previous_sle(args, for_update=False): """ diff --git a/stock/utils.py b/stock/utils.py index 96eeef644e..848783b2c6 100644 --- a/stock/utils.py +++ b/stock/utils.py @@ -69,7 +69,7 @@ def get_incoming_rate(args): if valuation_method == 'FIFO': if not previous_sle: return 0.0 - previous_stock_queue = json.loads(previous_sle.get('stock_queue', '[]')) + previous_stock_queue = json.loads(previous_sle.get('stock_queue', '[]') or '[]') in_rate = previous_stock_queue and \ get_fifo_rate(previous_stock_queue, args.get("qty") or 0) or 0 elif valuation_method == 'Moving Average': @@ -184,8 +184,8 @@ def _get_buying_amount(voucher_type, voucher_no, item_row, stock_ledger_entries) def reorder_item(): """ Reorder item if stock reaches reorder level""" if not hasattr(webnotes, "auto_indent"): - webnotes.auto_indent = webnotes.conn.get_value('Stock Settings', None, 'auto_indent') - + webnotes.auto_indent = cint(webnotes.conn.get_value('Stock Settings', None, 'auto_indent')) + if webnotes.auto_indent: material_requests = {} bin_list = webnotes.conn.sql("""select item_code, warehouse, projected_qty @@ -280,8 +280,8 @@ def create_material_request(material_requests): if mr_list: if not hasattr(webnotes, "reorder_email_notify"): - webnotes.reorder_email_notify = webnotes.conn.get_value('Stock Settings', None, - 'reorder_email_notify') + webnotes.reorder_email_notify = cint(webnotes.conn.get_value('Stock Settings', None, + 'reorder_email_notify')) if(webnotes.reorder_email_notify): send_email_notification(mr_list) @@ -307,7 +307,6 @@ def send_email_notification(mr_list): msg += "