diff --git a/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.txt b/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.txt index 5de944204c0..9aa70536610 100644 --- a/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.txt +++ b/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-10 16:34:09", "docstatus": 0, - "modified": "2013-06-20 16:49:12", + "modified": "2013-06-25 12:06:45", "modified_by": "Administrator", "owner": "Administrator" }, @@ -30,8 +30,7 @@ "parenttype": "DocType", "permlevel": 0, "read": 1, - "report": 1, - "submit": 0 + "report": 1 }, { "doctype": "DocType", @@ -101,21 +100,20 @@ "create": 0, "doctype": "DocPerm", "role": "Sales User", + "submit": 0, "write": 0 }, + { + "doctype": "DocPerm", + "role": "Accounts User" + }, { "amend": 0, "cancel": 1, "create": 1, "doctype": "DocPerm", "role": "Accounts Manager", - "write": 1 - }, - { - "cancel": 1, - "create": 1, - "doctype": "DocPerm", - "role": "System Manager", + "submit": 0, "write": 1 }, { @@ -124,6 +122,7 @@ "create": 1, "doctype": "DocPerm", "role": "Sales Master Manager", + "submit": 0, "write": 1 } ] \ No newline at end of file diff --git a/selling/report/sales_person_target_variance_(item_group_wise)/__init__.py b/accounts/doctype/shipping_rule/__init__.py similarity index 100% rename from selling/report/sales_person_target_variance_(item_group_wise)/__init__.py rename to accounts/doctype/shipping_rule/__init__.py diff --git a/accounts/doctype/shipping_rule/shipping_rule.py b/accounts/doctype/shipping_rule/shipping_rule.py new file mode 100644 index 00000000000..5ed4ed38e07 --- /dev/null +++ b/accounts/doctype/shipping_rule/shipping_rule.py @@ -0,0 +1,25 @@ +# For license information, please see license.txt + +from __future__ import unicode_literals +import webnotes +from webnotes import _, msgprint + +class DocType: + def __init__(self, d, dl): + self.doc, self.doclist = d, dl + + def validate(self): + self.validate_to_value_of_shipping_rule_conditions() + self.validate_overlapping_shipping_rule_conditions() + + + def validate_to_value_of_shipping_rule_conditions(self): + """check if more than two or more rows has To Value = 0""" + shipping_rule_conditions_with_0_to_value = self.doclist.get({ + "parentfield": "shipping_rule_conditions", "to_value": ["in", [0, None]]}) + if len(shipping_rule_conditions_with_0_to_value) >= 2: + msgprint(_('''There can only be one shipping rule with 0 or blank value for "To Value"'''), + raise_exception=True) + + def validate_overlapping_shipping_rule_conditions(self): + pass \ No newline at end of file diff --git a/accounts/doctype/shipping_rule/shipping_rule.txt b/accounts/doctype/shipping_rule/shipping_rule.txt new file mode 100644 index 00000000000..dd4fe8dfed2 --- /dev/null +++ b/accounts/doctype/shipping_rule/shipping_rule.txt @@ -0,0 +1,151 @@ +[ + { + "creation": "2013-06-25 11:48:03", + "docstatus": 0, + "modified": "2013-06-25 12:15:21", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "description": "Specify conditions to calculate shipping amount", + "doctype": "DocType", + "module": "Accounts", + "name": "__common__" + }, + { + "doctype": "DocField", + "name": "__common__", + "parent": "Shipping Rule", + "parentfield": "fields", + "parenttype": "DocType", + "permlevel": 0 + }, + { + "doctype": "DocPerm", + "name": "__common__", + "parent": "Shipping Rule", + "parentfield": "permissions", + "parenttype": "DocType", + "permlevel": 0, + "read": 1, + "report": 1 + }, + { + "doctype": "DocType", + "name": "Shipping Rule" + }, + { + "description": "example: Next Day Shipping", + "doctype": "DocField", + "fieldname": "shipping_rule_label", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Shipping Rule Label", + "reqd": 1 + }, + { + "doctype": "DocField", + "fieldname": "column_break_2", + "fieldtype": "Column Break" + }, + { + "default": "Amount", + "doctype": "DocField", + "fieldname": "calculate_based_on", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Calculate Based On", + "options": "Amount\nNet Weight", + "reqd": 1 + }, + { + "doctype": "DocField", + "fieldname": "rule_conditions_section", + "fieldtype": "Section Break", + "label": "Shipping Rule Conditions" + }, + { + "doctype": "DocField", + "fieldname": "shipping_rule_conditions", + "fieldtype": "Table", + "label": "Shipping Rule Conditions", + "options": "Shipping Rule Condition", + "reqd": 1 + }, + { + "doctype": "DocField", + "fieldname": "section_break_6", + "fieldtype": "Section Break" + }, + { + "description": "Specify a list of Territories, for which, this Shipping Rule is valid", + "doctype": "DocField", + "fieldname": "valid_for_territories", + "fieldtype": "Table", + "label": "Valid For Territories", + "options": "For Territory", + "reqd": 1 + }, + { + "doctype": "DocField", + "fieldname": "column_break_8", + "fieldtype": "Column Break" + }, + { + "doctype": "DocField", + "fieldname": "company", + "fieldtype": "Link", + "in_list_view": 0, + "label": "Company", + "options": "Company", + "reqd": 1 + }, + { + "doctype": "DocField", + "fieldname": "section_break_10", + "fieldtype": "Section Break" + }, + { + "doctype": "DocField", + "fieldname": "account", + "fieldtype": "Link", + "label": "Shipping Account", + "options": "Account", + "reqd": 1 + }, + { + "doctype": "DocField", + "fieldname": "column_break_12", + "fieldtype": "Column Break" + }, + { + "doctype": "DocField", + "fieldname": "cost_center", + "fieldtype": "Link", + "label": "Cost Center", + "options": "Cost Center", + "reqd": 1 + }, + { + "doctype": "DocPerm", + "role": "Accounts User" + }, + { + "doctype": "DocPerm", + "role": "Sales User" + }, + { + "cancel": 1, + "create": 1, + "doctype": "DocPerm", + "role": "Accounts Manager", + "write": 1 + }, + { + "cancel": 1, + "create": 1, + "doctype": "DocPerm", + "role": "Sales Master Manager", + "write": 1 + } +] \ No newline at end of file diff --git a/selling/report/territory_target_variance_(item_group_wise)/__init__.py b/accounts/doctype/shipping_rule_condition/__init__.py similarity index 100% rename from selling/report/territory_target_variance_(item_group_wise)/__init__.py rename to accounts/doctype/shipping_rule_condition/__init__.py diff --git a/accounts/doctype/shipping_rule_condition/shipping_rule_condition.py b/accounts/doctype/shipping_rule_condition/shipping_rule_condition.py new file mode 100644 index 00000000000..928aa9ff9f2 --- /dev/null +++ b/accounts/doctype/shipping_rule_condition/shipping_rule_condition.py @@ -0,0 +1,8 @@ +# For license information, please see license.txt + +from __future__ import unicode_literals +import webnotes + +class DocType: + def __init__(self, d, dl): + self.doc, self.doclist = d, dl \ No newline at end of file diff --git a/accounts/doctype/shipping_rule_condition/shipping_rule_condition.txt b/accounts/doctype/shipping_rule_condition/shipping_rule_condition.txt new file mode 100644 index 00000000000..2fe43db24d8 --- /dev/null +++ b/accounts/doctype/shipping_rule_condition/shipping_rule_condition.txt @@ -0,0 +1,50 @@ +[ + { + "creation": "2013-06-25 11:54:50", + "docstatus": 0, + "modified": "2013-06-25 11:58:04", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "description": "A condition for a Shipping Rule", + "doctype": "DocType", + "istable": 1, + "module": "Accounts", + "name": "__common__" + }, + { + "doctype": "DocField", + "name": "__common__", + "parent": "Shipping Rule Condition", + "parentfield": "fields", + "parenttype": "DocType", + "permlevel": 0 + }, + { + "doctype": "DocType", + "name": "Shipping Rule Condition" + }, + { + "doctype": "DocField", + "fieldname": "from_value", + "fieldtype": "Float", + "label": "From Value", + "reqd": 1 + }, + { + "doctype": "DocField", + "fieldname": "to_value", + "fieldtype": "Float", + "label": "To Value", + "reqd": 0 + }, + { + "doctype": "DocField", + "fieldname": "shipping_amount", + "fieldtype": "Currency", + "label": "Shipping Amount", + "options": "Company:company:default_currency", + "reqd": 1 + } +] \ No newline at end of file diff --git a/accounts/page/accounts_home/accounts_home.js b/accounts/page/accounts_home/accounts_home.js index a998818767f..f7e476af30c 100644 --- a/accounts/page/accounts_home/accounts_home.js +++ b/accounts/page/accounts_home/accounts_home.js @@ -100,6 +100,11 @@ wn.module_page["Accounts"] = [ "doctype":"Purchase Taxes and Charges Master", "description": wn._("Tax Template for Purchase") }, + { + "label": wn._("Shipping Rules"), + "doctype":"Shipping Rule", + "description": wn._("Rules to calculate shipping amount for a sale") + }, { "label": wn._("Point-of-Sale Setting"), "doctype":"POS Setting", diff --git a/accounts/page/general_ledger/general_ledger.js b/accounts/page/general_ledger/general_ledger.js index 9f025aa2b47..1f8618f20a7 100644 --- a/accounts/page/general_ledger/general_ledger.js +++ b/accounts/page/general_ledger/general_ledger.js @@ -232,7 +232,6 @@ erpnext.GeneralLedger = wn.views.GridReport.extend({ grouped_ledgers[item.account].totals.debit += item.debit; grouped_ledgers[item.account].totals.credit += item.credit; - grouped_ledgers[item.account].entries_group_by_voucher[item.voucher_no] .totals.debit += item.debit; grouped_ledgers[item.account].entries_group_by_voucher[item.voucher_no] @@ -248,8 +247,8 @@ erpnext.GeneralLedger = wn.views.GridReport.extend({ grouped_ledgers[item.account].entries.push(item); if(grouped_ledgers[item.account].entries_group_by_voucher[item.voucher_no].row){ - grouped_ledgers[item.account]. - entries_group_by_voucher[item.voucher_no].row = item; + grouped_ledgers[item.account].entries_group_by_voucher[item.voucher_no] + .row = jQuery.extend({}, item); } } } @@ -320,10 +319,11 @@ erpnext.GeneralLedger = wn.views.GridReport.extend({ var out = [] $.each(Object.keys(grouped_ledgers).sort(), function(i, account) { if(grouped_ledgers[account].entries.length) { - $.each(Object.keys(grouped_ledgers[account].entries_group_by_voucher).sort(), - function(j, voucher) { + $.each(Object.keys(grouped_ledgers[account].entries_group_by_voucher), + function(j, voucher) { voucher_dict = grouped_ledgers[account].entries_group_by_voucher[voucher]; - if(voucher_dict.totals.debit || voucher_dict.totals.credit) { + if(voucher_dict && + (voucher_dict.totals.debit || voucher_dict.totals.credit)) { voucher_dict.row.debit = voucher_dict.totals.debit; voucher_dict.row.credit = voucher_dict.totals.credit; voucher_dict.row.id = "entry_grouped_by_" + voucher diff --git a/accounts/report/budget_variance_report/budget_variance_report.py b/accounts/report/budget_variance_report/budget_variance_report.py index 99e303bd204..42bc6639edb 100644 --- a/accounts/report/budget_variance_report/budget_variance_report.py +++ b/accounts/report/budget_variance_report/budget_variance_report.py @@ -16,18 +16,21 @@ from __future__ import unicode_literals import webnotes -import calendar from webnotes import _, msgprint 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 def execute(filters=None): if not filters: filters = {} columns = get_columns(filters) - period_month_ranges = get_period_month_ranges(filters) + period_month_ranges = get_period_month_ranges(filters["period"], filters["fiscal_year"]) cam_map = get_costcenter_account_month_map(filters) + precision = webnotes.conn.get_value("Global Defaults", None, "float_precision") or 2 + data = [] for cost_center, cost_center_items in cam_map.items(): @@ -39,7 +42,7 @@ def execute(filters=None): for month in relevant_months: month_data = monthwise_data.get(month, {}) for i, fieldname in enumerate(["target", "actual", "variance"]): - value = flt(month_data.get(fieldname)) + value = flt(month_data.get(fieldname), precision) period_data[i] += value totals[i] += value period_data[2] = period_data[0] - period_data[1] @@ -61,7 +64,7 @@ def get_columns(filters): group_months = False if filters["period"] == "Monthly" else True - for from_date, to_date in get_period_date_ranges(filters): + 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"))) @@ -70,41 +73,6 @@ def get_columns(filters): return columns + ["Total Target::80", "Total Actual::80", "Total Variance::80"] -def get_period_date_ranges(filters): - from dateutil.relativedelta import relativedelta - - year_start_date, year_end_date = get_year_start_end_date(filters) - - increment = { - "Monthly": 1, - "Quarterly": 3, - "Half-Yearly": 6, - "Yearly": 12 - }.get(filters["period"]) - - period_date_ranges = [] - for i in xrange(1, 13, increment): - period_end_date = year_start_date + relativedelta(months=increment, - days=-1) - period_date_ranges.append([year_start_date, period_end_date]) - year_start_date = period_end_date + relativedelta(days=1) - - return period_date_ranges - -def get_period_month_ranges(filters): - from dateutil.relativedelta import relativedelta - period_month_ranges = [] - - for start_date, end_date in get_period_date_ranges(filters): - months_in_this_period = [] - while start_date <= end_date: - months_in_this_period.append(start_date.strftime("%B")) - start_date += relativedelta(months=1) - period_month_ranges.append(months_in_this_period) - - return period_month_ranges - - #Get cost center & target details def get_costcenter_target_details(filters): return webnotes.conn.sql("""select cc.name, cc.distribution_id, @@ -122,7 +90,7 @@ def get_target_distribution_details(filters): 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""" % ('%s'), (filters.get("fiscal_year")), as_dict=1): + bd.fiscal_year=%s""", (filters["fiscal_year"]), as_dict=1): target_details.setdefault(d.month, d) return target_details @@ -147,22 +115,16 @@ def get_costcenter_account_month_map(filters): for month in tdd: cam_map.setdefault(ccd.name, {}).setdefault(ccd.account, {})\ .setdefault(month, webnotes._dict({ - "target": 0.0, "actual": 0.0, "variance": 0.0 + "target": 0.0, "actual": 0.0 })) tav_dict = cam_map[ccd.name][ccd.account][month] - tav_dict.target = ccd.budget_allocated*(tdd[month]["percentage_allocation"]/100) + tav_dict.target = flt(ccd.budget_allocated) * \ + (tdd[month]["percentage_allocation"]/100) for ad in actual_details: if ad.month_name == month and ad.account == ccd.account \ and ad.cost_center == ccd.name: tav_dict.actual += ad.debit - ad.credit - return cam_map - -def get_year_start_end_date(filters): - return webnotes.conn.sql("""select year_start_date, - subdate(adddate(year_start_date, interval 1 year), interval 1 day) - as year_end_date - from `tabFiscal Year` - where name=%s""", filters["fiscal_year"])[0] \ No newline at end of file + return cam_map \ No newline at end of file diff --git a/accounts/report/purchase_register/purchase_register.py b/accounts/report/purchase_register/purchase_register.py index 548b5613440..d6233a41e0d 100644 --- a/accounts/report/purchase_register/purchase_register.py +++ b/accounts/report/purchase_register/purchase_register.py @@ -38,11 +38,12 @@ def execute(filters=None): data = [] for inv in invoice_list: # invoice details - purchase_order = ", ".join(invoice_po_pr_map.get(inv.name, {}).get("purchase_order", [])) - purchase_receipt = ", ".join(invoice_po_pr_map.get(inv.name, {}).get("purchase_receipt", [])) + purchase_order = list(set(invoice_po_pr_map.get(inv.name, {}).get("purchase_order", []))) + purchase_receipt = list(set(invoice_po_pr_map.get(inv.name, {}).get("purchase_receipt", []))) + row = [inv.name, inv.posting_date, inv.supplier, inv.credit_to, account_map.get(inv.credit_to), inv.project_name, inv.bill_no, inv.bill_date, - inv.remarks, purchase_order, purchase_receipt] + inv.remarks, ", ".join(purchase_order), ", ".join(purchase_receipt)] # map expense values for expense_acc in expense_accounts: @@ -55,8 +56,9 @@ def execute(filters=None): for tax_acc in tax_accounts: row.append(invoice_tax_map.get(inv.name, {}).get(tax_acc)) - # total tax, grand total - row += [inv.total_tax, inv.grand_total] + # total tax, grand total, outstanding amount & rounded total + row += [inv.other_charges_total, inv.grand_total, flt(inv.grand_total, 2), \ + inv.outstanding_amount] data.append(row) return columns, data @@ -85,7 +87,8 @@ def get_columns(invoice_list): columns = columns + [(account + ":Currency:120") for account in expense_accounts] + \ ["Net Total:Currency:120"] + [(account + ":Currency:120") for account in tax_accounts] + \ - ["Total Tax:Currency:120"] + ["Grand Total:Currency:120"] + ["Total Tax:Currency:120"] + ["Grand Total:Currency:120"] + \ + ["Rounded Total:Currency:120"] + ["Outstanding Amount:Currency:120"] return columns, expense_accounts, tax_accounts @@ -102,9 +105,11 @@ def get_conditions(filters): def get_invoices(filters): conditions = get_conditions(filters) - return webnotes.conn.sql("""select name, posting_date, credit_to, project_name, supplier, - bill_no, bill_date, remarks, net_total, total_tax, grand_total - from `tabPurchase Invoice` where docstatus = 1 %s + return webnotes.conn.sql("""select pi.name, pi.posting_date, pi.credit_to, + pii.project_name, pi.supplier, pi.bill_no, pi.bill_date, pi.remarks, pi.net_total, + pi.total_tax, pi.grand_total, pi.outstanding_amount + from `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pii + where pii.parent = pi.name and pi.docstatus = 1 %s order by posting_date desc, name desc""" % conditions, filters, as_dict=1) diff --git a/accounts/report/sales_register/sales_register.py b/accounts/report/sales_register/sales_register.py index 99057f9a2eb..3eebc33e9ca 100644 --- a/accounts/report/sales_register/sales_register.py +++ b/accounts/report/sales_register/sales_register.py @@ -39,12 +39,12 @@ def execute(filters=None): data = [] for inv in invoice_list: # invoice details - sales_order = ", ".join(invoice_so_dn_map.get(inv.name, {}).get("sales_order", [])) - delivery_note = ", ".join(invoice_so_dn_map.get(inv.name, {}).get("delivery_note", [])) + sales_order = list(set(invoice_so_dn_map.get(inv.name, {}).get("sales_order", []))) + delivery_note = list(set(invoice_so_dn_map.get(inv.name, {}).get("delivery_note", []))) row = [inv.name, inv.posting_date, inv.customer, inv.debit_to, account_map.get(inv.debit_to), customer_map.get(inv.customer), inv.project_name, - inv.remarks, sales_order, delivery_note] + inv.remarks, ", ".join(sales_order), ", ".join(delivery_note)] # map income values for income_acc in income_accounts: @@ -57,8 +57,8 @@ def execute(filters=None): for tax_acc in tax_accounts: row.append(invoice_tax_map.get(inv.name, {}).get(tax_acc)) - # total tax, grand total - row += [inv.other_charges_total, inv.grand_total] + # total tax, grand total, outstanding amount & rounded total + row += [inv.other_charges_total, inv.grand_total, inv.rounded_total, inv.outstanding_amount] data.append(row) @@ -88,7 +88,8 @@ def get_columns(invoice_list): columns = columns + [(account + ":Currency:120") for account in income_accounts] + \ ["Net Total:Currency:120"] + [(account + ":Currency:120") for account in tax_accounts] + \ - ["Total Tax:Currency:120"] + ["Grand Total:Currency:120"] + ["Total Tax:Currency:120"] + ["Grand Total:Currency:120"] + \ + ["Rounded Total:Currency:120"] + ["Outstanding Amount:Currency:120"] return columns, income_accounts, tax_accounts @@ -106,7 +107,8 @@ def get_conditions(filters): def get_invoices(filters): conditions = get_conditions(filters) return webnotes.conn.sql("""select name, posting_date, debit_to, project_name, customer, - remarks, net_total, other_charges_total, grand_total from `tabSales Invoice` + remarks, net_total, other_charges_total, grand_total, rounded_total, + outstanding_amount from `tabSales Invoice` where docstatus = 1 %s order by posting_date desc, name desc""" % conditions, filters, as_dict=1) diff --git a/patches/june_2013/p01_update_bom_exploded_items.py b/patches/june_2013/p01_update_bom_exploded_items.py index eff0931e4d9..f53eb5bc68b 100644 --- a/patches/june_2013/p01_update_bom_exploded_items.py +++ b/patches/june_2013/p01_update_bom_exploded_items.py @@ -23,7 +23,7 @@ def execute(): if bom[0] not in updated_bom: try: bom_obj = webnotes.get_obj("BOM", bom[0], with_children=1) - updated_bom = bom_obj.update_cost_and_exploded_items(updated_bom) + updated_bom += bom_obj.update_cost_and_exploded_items(bom[0]) webnotes.conn.commit() except: pass \ No newline at end of file diff --git a/public/js/stock_analytics.js b/public/js/stock_analytics.js index c3ed1cb232f..91384f61ed9 100644 --- a/public/js/stock_analytics.js +++ b/public/js/stock_analytics.js @@ -162,6 +162,8 @@ erpnext.StockAnalytics = erpnext.StockGridReport.extend({ } else { break; } + + me.round_item_values(item); } } }, diff --git a/stock/doctype/sales_bom/__init__.py b/selling/doctype/sales_bom/__init__.py similarity index 100% rename from stock/doctype/sales_bom/__init__.py rename to selling/doctype/sales_bom/__init__.py diff --git a/stock/doctype/sales_bom/sales_bom.js b/selling/doctype/sales_bom/sales_bom.js similarity index 100% rename from stock/doctype/sales_bom/sales_bom.js rename to selling/doctype/sales_bom/sales_bom.js diff --git a/stock/doctype/sales_bom/sales_bom.py b/selling/doctype/sales_bom/sales_bom.py similarity index 100% rename from stock/doctype/sales_bom/sales_bom.py rename to selling/doctype/sales_bom/sales_bom.py diff --git a/stock/doctype/sales_bom/sales_bom.txt b/selling/doctype/sales_bom/sales_bom.txt similarity index 94% rename from stock/doctype/sales_bom/sales_bom.txt rename to selling/doctype/sales_bom/sales_bom.txt index 031f2559196..bf8fa479c22 100644 --- a/stock/doctype/sales_bom/sales_bom.txt +++ b/selling/doctype/sales_bom/sales_bom.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-01-10 16:34:29", + "creation": "2013-06-20 11:53:21", "docstatus": 0, - "modified": "2013-01-22 14:57:23", + "modified": "2013-06-25 16:43:18", "modified_by": "Administrator", "owner": "Administrator" }, @@ -11,7 +11,7 @@ "doctype": "DocType", "document_type": "Master", "is_submittable": 0, - "module": "Stock", + "module": "Selling", "name": "__common__" }, { @@ -23,7 +23,6 @@ "permlevel": 0 }, { - "amend": 0, "doctype": "DocPerm", "name": "__common__", "parent": "Sales BOM", @@ -74,6 +73,7 @@ "reqd": 1 }, { + "amend": 1, "cancel": 1, "create": 1, "doctype": "DocPerm", @@ -81,6 +81,7 @@ "write": 1 }, { + "amend": 0, "cancel": 0, "create": 0, "doctype": "DocPerm", @@ -88,6 +89,7 @@ "write": 0 }, { + "amend": 0, "cancel": 1, "create": 1, "doctype": "DocPerm", diff --git a/stock/doctype/sales_bom/test_sales_bom.py b/selling/doctype/sales_bom/test_sales_bom.py similarity index 100% rename from stock/doctype/sales_bom/test_sales_bom.py rename to selling/doctype/sales_bom/test_sales_bom.py diff --git a/stock/doctype/sales_bom_item/__init__.py b/selling/doctype/sales_bom_item/__init__.py similarity index 100% rename from stock/doctype/sales_bom_item/__init__.py rename to selling/doctype/sales_bom_item/__init__.py diff --git a/stock/doctype/sales_bom_item/sales_bom_item.py b/selling/doctype/sales_bom_item/sales_bom_item.py similarity index 100% rename from stock/doctype/sales_bom_item/sales_bom_item.py rename to selling/doctype/sales_bom_item/sales_bom_item.py diff --git a/stock/doctype/sales_bom_item/sales_bom_item.txt b/selling/doctype/sales_bom_item/sales_bom_item.txt similarity index 93% rename from stock/doctype/sales_bom_item/sales_bom_item.txt rename to selling/doctype/sales_bom_item/sales_bom_item.txt index 98285af1048..f7906b72d8b 100644 --- a/stock/doctype/sales_bom_item/sales_bom_item.txt +++ b/selling/doctype/sales_bom_item/sales_bom_item.txt @@ -1,15 +1,15 @@ [ { - "creation": "2013-02-22 01:28:03", + "creation": "2013-05-23 16:55:51", "docstatus": 0, - "modified": "2013-03-07 07:03:30", + "modified": "2013-06-26 13:45:41", "modified_by": "Administrator", "owner": "Administrator" }, { "doctype": "DocType", "istable": 1, - "module": "Stock", + "module": "Selling", "name": "__common__" }, { diff --git a/selling/doctype/sms_center/sms_center.py b/selling/doctype/sms_center/sms_center.py index c5db7383f72..7d50e712326 100644 --- a/selling/doctype/sms_center/sms_center.py +++ b/selling/doctype/sms_center/sms_center.py @@ -24,7 +24,7 @@ from webnotes.model.code import get_obj from webnotes import msgprint sql = webnotes.conn.sql - + # ---------- class DocType: @@ -45,17 +45,16 @@ class DocType: elif self.doc.send_to == 'All Lead (Open)': rec = sql("select lead_name, mobile_no from tabLead where ifnull(mobile_no,'')!='' and docstatus != 2 and status = 'Open'") elif self.doc.send_to == 'All Employee (Active)': - where_clause = self.doc.department and " and t1.department = '%s'" % self.doc.department or "" - where_clause += self.doc.branch and " and t1.branch = '%s'" % self.doc.branch or "" - rec = sql("select t1.employee_name, t2.cell_number from `tabEmployee` t1, `tabEmployee Profile` t2 where t2.employee = t1.name and t1.status = 'Active' and t1.docstatus != 2 and ifnull(t2.cell_number,'')!='' %s" % where_clause) + where_clause = self.doc.department and " and department = '%s'" % self.doc.department or "" + where_clause += self.doc.branch and " and branch = '%s'" % self.doc.branch or "" + rec = sql("select employee_name, cell_number from `tabEmployee` where status = 'Active' and docstatus < 2 and ifnull(cell_number,'')!='' %s" % where_clause) elif self.doc.send_to == 'All Sales Person': rec = sql("select sales_person_name, mobile_no from `tabSales Person` where docstatus != 2 and ifnull(mobile_no,'')!=''") - rec_list = '' for d in rec: rec_list += d[0] + ' - ' + d[1] + '\n' self.doc.receiver_list = rec_list - + webnotes.errprint(rec_list) def get_receiver_nos(self): receiver_nos = [] for d in self.doc.receiver_list.split('\n'): diff --git a/selling/page/selling_home/selling_home.js b/selling/page/selling_home/selling_home.js index ef419c5ed19..388fa42f847 100644 --- a/selling/page/selling_home/selling_home.js +++ b/selling/page/selling_home/selling_home.js @@ -69,6 +69,11 @@ wn.module_page["Selling"] = [ description: wn._("Sales taxes template."), doctype:"Sales Taxes and Charges Master" }, + { + label: wn._("Shipping Rules"), + description: wn._("Rules to calculate shipping amount for a sale"), + doctype:"Shipping Rule" + }, { label: wn._("Price List"), description: wn._("Mupltiple Item prices."), @@ -168,13 +173,11 @@ wn.module_page["Selling"] = [ }, { "label":wn._("Territory Target Variance (Item Group-Wise)"), - route: "query-report/Territory Target Variance (Item Group-Wise)", - doctype: "Sales Order" + route: "query-report/Territory Target Variance Item Group-Wise" }, { "label":wn._("Sales Person Target Variance (Item Group-Wise)"), - route: "query-report/Sales Person Target Variance (Item Group-Wise)", - doctype: "Sales Order" + route: "query-report/Sales Person Target Variance Item Group-Wise" }, { "label":wn._("Customers Not Buying Since Long Time"), @@ -191,6 +194,10 @@ wn.module_page["Selling"] = [ route: "query-report/Sales Order Trends", doctype: "Sales Order" }, + { + "label":wn._("Available Stock for Packing Items"), + route: "query-report/Available Stock for Packing Items", + }, { "label":wn._("Pending SO Items For Purchase Request"), route: "query-report/Pending SO Items For Purchase Request" diff --git a/selling/report/available_stock_for_packing_items/__init__.py b/selling/report/available_stock_for_packing_items/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.py b/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.py new file mode 100644 index 00000000000..171c3bb8d9a --- /dev/null +++ b/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.py @@ -0,0 +1,92 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from __future__ import unicode_literals +import webnotes +from webnotes.utils import flt + +def execute(filters=None): + if not filters: filters = {} + + columns = get_columns() + iwq_map = get_item_warehouse_quantity_map() + item_map = get_item_details() + + data = [] + for sbom, warehouse in iwq_map.items(): + total = 0 + total_qty = 0 + + for wh, item_qty in warehouse.items(): + total += 1 + row = [sbom, item_map.get(sbom).item_name, item_map.get(sbom).description, + item_map.get(sbom).stock_uom, wh] + available_qty = min(item_qty.values()) + total_qty += flt(available_qty) + row += [available_qty] + + if available_qty: + data.append(row) + if (total == len(warehouse)): + row = ["", "", "Total", "", "", total_qty] + data.append(row) + + return columns, data + +def get_columns(): + columns = ["Item Code:Link/Item:100", "Item Name::100", "Description::120", \ + "UOM:Link/UOM:80", "Warehouse:Link/Warehouse:100", "Quantity::100"] + + return columns + +def get_sales_bom_items(): + sbom_item_map = {} + for sbom in webnotes.conn.sql("""select parent, item_code, qty from `tabSales BOM Item` + where docstatus < 2""", as_dict=1): + sbom_item_map.setdefault(sbom.parent, {}).setdefault(sbom.item_code, sbom.qty) + + return sbom_item_map + +def get_item_details(): + item_map = {} + for item in webnotes.conn.sql("""select name, item_name, description, stock_uom + from `tabItem`""", as_dict=1): + item_map.setdefault(item.name, item) + + return item_map + +def get_item_warehouse_quantity(): + iwq_map = {} + bin = webnotes.conn.sql("""select item_code, warehouse, actual_qty from `tabBin` + where actual_qty > 0""") + for item, wh, qty in bin: + iwq_map.setdefault(item, {}).setdefault(wh, qty) + + return iwq_map + +def get_item_warehouse_quantity_map(): + sbom_map = {} + iwq_map = get_item_warehouse_quantity() + sbom_item_map = get_sales_bom_items() + + for sbom, sbom_items in sbom_item_map.items(): + for item, child_qty in sbom_items.items(): + for wh, qty in iwq_map.get(item, {}).items(): + avail_qty = flt(qty) / flt(child_qty) + sbom_map.setdefault(sbom, {}).setdefault(wh, {}) \ + .setdefault(item, avail_qty) + + return sbom_map \ No newline at end of file diff --git a/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.txt b/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.txt new file mode 100644 index 00000000000..5cf413393f4 --- /dev/null +++ b/selling/report/available_stock_for_packing_items/available_stock_for_packing_items.txt @@ -0,0 +1,21 @@ +[ + { + "creation": "2013-06-21 13:40:05", + "docstatus": 0, + "modified": "2013-06-21 15:06:40", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Sales BOM", + "report_name": "Available Stock for Packing Items", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Available Stock for Packing Items" + } +] \ No newline at end of file diff --git a/selling/report/sales_person_target_variance_item_group_wise/__init__.py b/selling/report/sales_person_target_variance_item_group_wise/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).js b/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.js similarity index 86% rename from selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).js rename to selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.js index 09f0d55aedc..c7a5d668c48 100644 --- a/selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).js +++ b/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.js @@ -1,4 +1,4 @@ -wn.query_reports["Sales Person Target Variance (Item Group-Wise)"] = { +wn.query_reports["Sales Person Target Variance Item Group-Wise"] = { "filters": [ { fieldname: "fiscal_year", 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 similarity index 66% rename from selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).py rename to selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.py index 8f5931d826b..ae3819c2cb1 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 @@ -16,18 +16,21 @@ from __future__ import unicode_literals import webnotes -import calendar from webnotes import _, msgprint 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 def execute(filters=None): if not filters: filters = {} columns = get_columns(filters) - period_month_ranges = get_period_month_ranges(filters) + 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(): @@ -39,7 +42,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)) + value = flt(month_data.get(fieldname), precision) period_data[i] += value totals[i] += value period_data[2] = period_data[0] - period_data[1] @@ -61,7 +64,7 @@ def get_columns(filters): group_months = False if filters["period"] == "Monthly" else True - for from_date, to_date in get_period_date_ranges(filters): + 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"))) @@ -70,49 +73,14 @@ def get_columns(filters): return columns + ["Total Target::80", "Total Achieved::80", "Total Variance::80"] -def get_period_date_ranges(filters): - from dateutil.relativedelta import relativedelta - - year_start_date, year_end_date = get_year_start_end_date(filters) - - increment = { - "Monthly": 1, - "Quarterly": 3, - "Half-Yearly": 6, - "Yearly": 12 - }.get(filters["period"]) - - period_date_ranges = [] - for i in xrange(1, 13, increment): - period_end_date = year_start_date + relativedelta(months=increment, - days=-1) - period_date_ranges.append([year_start_date, period_end_date]) - year_start_date = period_end_date + relativedelta(days=1) - - return period_date_ranges - -def get_period_month_ranges(filters): - from dateutil.relativedelta import relativedelta - period_month_ranges = [] - - for start_date, end_date in get_period_date_ranges(filters): - months_in_this_period = [] - while start_date <= end_date: - months_in_this_period.append(start_date.strftime("%B")) - start_date += relativedelta(months=1) - period_month_ranges.append(months_in_this_period) - - return period_month_ranges - - #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""" % - ('%s'), (filters.get("fiscal_year")), as_dict=1) + ifnull(sp.distribution_id, '')!='' order by sp.name""", + (filters["fiscal_year"]), as_dict=1) #Get target distribution details of item group def get_target_distribution_details(filters): @@ -121,14 +89,14 @@ def get_target_distribution_details(filters): 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 """ % ('%s'), (filters.get("fiscal_year")), as_dict=1): + bd.fiscal_year=%s""", (filters["fiscal_year"]), as_dict=1): target_details.setdefault(d.month, d) return target_details #Get achieved details from sales order def get_achieved_details(filters): - start_date, end_date = get_year_start_end_date(filters) + start_date, end_date = get_fiscal_year(fiscal_year = filters["fiscal_year"])[1:] return webnotes.conn.sql("""select soi.item_code, soi.qty, soi.amount, so.transaction_date, st.sales_person, MONTHNAME(so.transaction_date) as month_name @@ -149,35 +117,27 @@ def get_salesperson_item_month_map(filters): for month in tdd: sim_map.setdefault(sd.name, {}).setdefault(sd.item_group, {})\ .setdefault(month, webnotes._dict({ - "target": 0.0, "achieved": 0.0, "variance": 0.0 + "target": 0.0, "achieved": 0.0 })) tav_dict = sim_map[sd.name][sd.item_group][month] for ad in achieved_details: if (filters["target_on"] == "Quantity"): - tav_dict.target = sd.target_qty*(tdd[month]["percentage_allocation"]/100) - if ad.month_name == month and ''.join(get_item_group(ad.item_code)) == sd.item_group \ + tav_dict.target = flt(sd.target_qty) * \ + (tdd[month]["percentage_allocation"]/100) + 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 = sd.target_amount*(tdd[month]["percentage_allocation"]/100) - if ad.month_name == month and ''.join(get_item_group(ad.item_code)) == sd.item_group \ + tav_dict.target = flt(sd.target_amount) * \ + (tdd[month]["percentage_allocation"]/100) + 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 return sim_map -def get_year_start_end_date(filters): - return webnotes.conn.sql("""select year_start_date, - subdate(adddate(year_start_date, interval 1 year), interval 1 day) - as year_end_date - from `tabFiscal Year` - where name=%s""", filters["fiscal_year"])[0] - def get_item_group(item_name): - """Get Item Group of an item""" - - return webnotes.conn.sql_list("select item_group from `tabItem` where name=%s""" % - ('%s'), (item_name)) \ No newline at end of file + return webnotes.conn.get_value("Item", item_name, "item_group") \ 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).txt b/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.txt similarity index 56% rename from selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).txt rename to selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.txt index 955cdec4775..e587c2c0840 100644 --- a/selling/report/sales_person_target_variance_(item_group_wise)/sales_person_target_variance_(item_group_wise).txt +++ b/selling/report/sales_person_target_variance_item_group_wise/sales_person_target_variance_item_group_wise.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-06-18 12:09:40", + "creation": "2013-06-21 12:14:15", "docstatus": 0, - "modified": "2013-06-18 12:09:40", + "modified": "2013-06-21 12:14:15", "modified_by": "Administrator", "owner": "Administrator" }, @@ -11,11 +11,11 @@ "is_standard": "Yes", "name": "__common__", "ref_doctype": "Sales Order", - "report_name": "Sales Person Target Variance (Item Group-Wise)", + "report_name": "Sales Person Target Variance Item Group-Wise", "report_type": "Script Report" }, { "doctype": "Report", - "name": "Sales Person Target Variance (Item Group-Wise)" + "name": "Sales Person Target Variance Item Group-Wise" } ] \ No newline at end of file diff --git a/selling/report/territory_target_variance_item_group_wise/__init__.py b/selling/report/territory_target_variance_item_group_wise/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).js b/selling/report/territory_target_variance_item_group_wise/territory_target_variance_item_group_wise.js similarity index 86% rename from selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).js rename to selling/report/territory_target_variance_item_group_wise/territory_target_variance_item_group_wise.js index 58718a4e0b2..146b17d02b8 100644 --- a/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).js +++ b/selling/report/territory_target_variance_item_group_wise/territory_target_variance_item_group_wise.js @@ -1,4 +1,4 @@ -wn.query_reports["Territory Target Variance (Item Group-Wise)"] = { +wn.query_reports["Territory Target Variance Item Group-Wise"] = { "filters": [ { fieldname: "fiscal_year", 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 similarity index 77% rename from selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).py rename to selling/report/territory_target_variance_item_group_wise/territory_target_variance_item_group_wise.py index 022d19ecf64..109acbdbe85 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 @@ -16,19 +16,21 @@ from __future__ import unicode_literals import webnotes -import calendar from webnotes import _, msgprint 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 def execute(filters=None): if not filters: filters = {} columns = get_columns(filters) - period_month_ranges = get_period_month_ranges(filters) + period_month_ranges = get_period_month_ranges(filters["period"], filters["fiscal_year"]) tim_map = get_territory_item_month_map(filters) + precision = webnotes.conn.get_value("Global Defaults", None, "float_precision") or 2 + data = [] for territory, territory_items in tim_map.items(): @@ -40,7 +42,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)) + value = flt(month_data.get(fieldname), precision) period_data[i] += value totals[i] += value period_data[2] = period_data[0] - period_data[1] @@ -61,7 +63,7 @@ def get_columns(filters): group_months = False if filters["period"] == "Monthly" else True - for from_date, to_date in get_period_date_ranges(filters): + 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"))) @@ -70,41 +72,6 @@ def get_columns(filters): return columns + ["Total Target::80", "Total Achieved::80", "Total Variance::80"] -def get_period_date_ranges(filters): - from dateutil.relativedelta import relativedelta - year_start_date, year_end_date = get_fiscal_year(fiscal_year = filters["fiscal_year"])[1:] - - - increment = { - "Monthly": 1, - "Quarterly": 3, - "Half-Yearly": 6, - "Yearly": 12 - }.get(filters["period"]) - - period_date_ranges = [] - for i in xrange(1, 13, increment): - period_end_date = year_start_date + relativedelta(months=increment, - days=-1) - period_date_ranges.append([year_start_date, period_end_date]) - year_start_date = period_end_date + relativedelta(days=1) - - return period_date_ranges - -def get_period_month_ranges(filters): - from dateutil.relativedelta import relativedelta - period_month_ranges = [] - - for start_date, end_date in get_period_date_ranges(filters): - months_in_this_period = [] - while start_date <= end_date: - months_in_this_period.append(start_date.strftime("%B")) - start_date += relativedelta(months=1) - period_month_ranges.append(months_in_this_period) - - return period_month_ranges - - #Get territory & item group details def get_territory_details(filters): return webnotes.conn.sql("""select t.name, td.item_group, td.target_qty, @@ -112,7 +79,7 @@ def get_territory_details(filters): 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""", - filters.get("fiscal_year"), as_dict=1) + (filters["fiscal_year"]), as_dict=1) #Get target distribution details of item group def get_target_distribution_details(filters): @@ -121,7 +88,7 @@ def get_target_distribution_details(filters): 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""" % ('%s'), (filters.get("fiscal_year")), as_dict=1): + bd.fiscal_year=%s""", (filters["fiscal_year"]), as_dict=1): target_details.setdefault(d.month, d) return target_details @@ -155,7 +122,8 @@ def get_territory_item_month_map(filters): 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(td.target_qty) * \ + (tdd[month]["percentage_allocation"]/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 diff --git a/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).txt b/selling/report/territory_target_variance_item_group_wise/territory_target_variance_item_group_wise.txt similarity index 57% rename from selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).txt rename to selling/report/territory_target_variance_item_group_wise/territory_target_variance_item_group_wise.txt index 7fff64a861f..6e16b64d4e2 100644 --- a/selling/report/territory_target_variance_(item_group_wise)/territory_target_variance_(item_group_wise).txt +++ b/selling/report/territory_target_variance_item_group_wise/territory_target_variance_item_group_wise.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-06-07 15:13:13", + "creation": "2013-06-21 12:15:00", "docstatus": 0, - "modified": "2013-06-07 15:13:13", + "modified": "2013-06-21 12:15:00", "modified_by": "Administrator", "owner": "Administrator" }, @@ -11,11 +11,11 @@ "is_standard": "Yes", "name": "__common__", "ref_doctype": "Sales Order", - "report_name": "Territory Target Variance (Item Group-Wise)", + "report_name": "Territory Target Variance Item Group-Wise", "report_type": "Script Report" }, { "doctype": "Report", - "name": "Territory Target Variance (Item Group-Wise)" + "name": "Territory Target Variance Item Group-Wise" } ] \ No newline at end of file diff --git a/setup/doctype/price_list/price_list.txt b/setup/doctype/price_list/price_list.txt index 9bc18dc0621..5113a3e0808 100644 --- a/setup/doctype/price_list/price_list.txt +++ b/setup/doctype/price_list/price_list.txt @@ -2,7 +2,7 @@ { "creation": "2013-01-25 11:35:09", "docstatus": 0, - "modified": "2013-06-20 12:53:10", + "modified": "2013-06-25 12:05:12", "modified_by": "Administrator", "owner": "Administrator" }, @@ -116,13 +116,6 @@ "label": "How to upload", "options": "
Use the Data Import Tool to upload, update Item Prices in bulk:\n
    \n
  1. Go to Data Import Tool.\n
  2. Select \"Item\"\n
  3. Check on \"With Data\"\n
  4. Download \"Item Price\" from Child Tables.\n
  5. Update the prices required and add new rows if required.\n
  6. Check on \"Overwrite\"\n
  7. Upload the modified sheet.\n
\n" }, - { - "cancel": 0, - "create": 0, - "doctype": "DocPerm", - "role": "Sales Manager", - "write": 0 - }, { "cancel": 0, "create": 0, diff --git a/stock/page/stock_balance/stock_balance.js b/stock/page/stock_balance/stock_balance.js index 4467b98712a..4abd533b433 100644 --- a/stock/page/stock_balance/stock_balance.js +++ b/stock/page/stock_balance/stock_balance.js @@ -119,7 +119,7 @@ erpnext.StockBalance = erpnext.StockAnalytics.extend({ var qty_diff = sl.qty; var value_diff = me.get_value_diff(wh, sl, is_fifo); - + if(sl_posting_date < from_date) { item.opening_qty += qty_diff; item.opening_value += value_diff; @@ -146,6 +146,8 @@ erpnext.StockBalance = erpnext.StockAnalytics.extend({ } else { break; } + + me.round_item_values(item); } } diff --git a/stock/report/item_prices/item_prices.py b/stock/report/item_prices/item_prices.py index 3bdb7465105..fb69086252d 100644 --- a/stock/report/item_prices/item_prices.py +++ b/stock/report/item_prices/item_prices.py @@ -24,16 +24,22 @@ def execute(filters=None): columns = get_columns(filters) item_map = get_item_details() pl = get_price_list() + last_purchase_rate = get_last_purchase_rate() bom_rate = get_item_bom_rate() val_rate_map = get_valuation_rate() + + precision = webnotes.conn.get_value("Global Defaults", None, "float_precision") or 2 data = [] for item in sorted(item_map): data.append([item, item_map[item]["item_name"], item_map[item]["description"], item_map[item]["stock_uom"], - flt(item_map[item]["last_purchase_rate"]), val_rate_map.get(item, 0), - pl.get(item, {}).get("selling"), pl.get(item, {}).get("buying"), - bom_rate.get(item, 0), flt(item_map[item]["standard_rate"]) + flt(last_purchase_rate.get(item, 0), precision), + flt(val_rate_map.get(item, 0), precision), + pl.get(item, {}).get("selling"), + pl.get(item, {}).get("buying"), + flt(bom_rate.get(item, 0), precision), + flt(item_map[item]["standard_rate"], precision) ]) return columns, data @@ -53,7 +59,7 @@ def get_item_details(): item_map = {} for i in webnotes.conn.sql("select name, item_name, description, \ - stock_uom, standard_rate, last_purchase_rate from tabItem \ + stock_uom, standard_rate from tabItem \ order by item_code", as_dict=1): item_map.setdefault(i.name, i) @@ -84,25 +90,61 @@ def get_price_list(): return item_rate_map +def get_last_purchase_rate(): + + item_last_purchase_rate_map = {} + + query = """select * from (select + result.item_code, + result.purchase_rate + from ( + (select + po_item.item_code, + po_item.item_name, + po.transaction_date as posting_date, + po_item.purchase_ref_rate, + po_item.discount_rate, + po_item.purchase_rate + from `tabPurchase Order` po, `tabPurchase Order Item` po_item + where po.name = po_item.parent and po.docstatus = 1) + union + (select + pr_item.item_code, + pr_item.item_name, + pr.posting_date, + pr_item.purchase_ref_rate, + pr_item.discount_rate, + pr_item.purchase_rate + from `tabPurchase Receipt` pr, `tabPurchase Receipt Item` pr_item + where pr.name = pr_item.parent and pr.docstatus = 1) + ) result + order by result.item_code asc, result.posting_date desc) result_wrapper + group by item_code""" + + for d in webnotes.conn.sql(query, as_dict=1): + item_last_purchase_rate_map.setdefault(d.item_code, d.purchase_rate) + + return item_last_purchase_rate_map + def get_item_bom_rate(): """Get BOM rate of an item from BOM""" - bom_map = {} + item_bom_map = {} for b in webnotes.conn.sql("""select item, (total_cost/quantity) as bom_rate from `tabBOM` where is_active=1 and is_default=1""", as_dict=1): - bom_map.setdefault(b.item, flt(b.bom_rate)) + item_bom_map.setdefault(b.item, flt(b.bom_rate)) - return bom_map + return item_bom_map def get_valuation_rate(): """Get an average valuation rate of an item from all warehouses""" - val_rate_map = {} + item_val_rate_map = {} for d in webnotes.conn.sql("""select item_code, sum(actual_qty*valuation_rate)/sum(actual_qty) as val_rate from tabBin where actual_qty > 0 group by item_code""", as_dict=1): - val_rate_map.setdefault(d.item_code, d.val_rate) + item_val_rate_map.setdefault(d.item_code, d.val_rate) - return val_rate_map \ No newline at end of file + return item_val_rate_map