From 2c45899a0203064677efb5e3866ceb247dd17676 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 15 Apr 2014 14:36:12 +0530 Subject: [PATCH] fixed strings for translation --- .../journal_voucher/journal_voucher.py | 2 +- erpnext/selling/doctype/customer/customer.py | 6 +- .../doctype/stock_ledger/stock_ledger.py | 19 +- .../stock_ledger_entry/stock_ledger_entry.py | 16 +- .../stock_uom_replace_utility.py | 94 ++-- erpnext/stock/doctype/warehouse/warehouse.py | 72 +-- .../batch_wise_balance_history.py | 29 +- .../itemwise_recommended_reorder_level.py | 23 +- .../warehouse_wise_stock_balance.py | 29 +- .../doctype/customer_issue/customer_issue.py | 42 +- .../maintenance_visit/maintenance_visit.json | 485 +++++++++--------- .../maintenance_visit/maintenance_visit.py | 41 +- .../support/doctype/newsletter/newsletter.py | 60 +-- .../support_email_settings.py | 15 +- erpnext/utilities/__init__.py | 12 +- erpnext/utilities/doctype/address/address.py | 32 +- erpnext/utilities/doctype/note/note.py | 14 +- .../doctype/rename_tool/rename_tool.py | 24 +- .../doctype/sms_control/sms_control.py | 17 +- erpnext/utilities/transaction_base.py | 46 +- 20 files changed, 516 insertions(+), 562 deletions(-) diff --git a/erpnext/accounts/doctype/journal_voucher/journal_voucher.py b/erpnext/accounts/doctype/journal_voucher/journal_voucher.py index f54a5508c5..5c3e2a39b9 100644 --- a/erpnext/accounts/doctype/journal_voucher/journal_voucher.py +++ b/erpnext/accounts/doctype/journal_voucher/journal_voucher.py @@ -114,7 +114,7 @@ class JournalVoucher(AccountsController): if self.cheque_no: if self.cheque_date: r.append(_('Reference #{0} dated {1}').format(self.cheque_no, formatdate(self.cheque_date))) - else : + else: msgprint(_("Please enter Reference date"), raise_exception=1) for d in self.get('entries'): diff --git a/erpnext/selling/doctype/customer/customer.py b/erpnext/selling/doctype/customer/customer.py index 361f4fa4ff..b0cb540485 100644 --- a/erpnext/selling/doctype/customer/customer.py +++ b/erpnext/selling/doctype/customer/customer.py @@ -86,9 +86,7 @@ class Customer(TransactionBase): def validate_name_with_customer_group(self): if frappe.db.exists("Customer Group", self.name): - frappe.msgprint("An Customer Group exists with same name (%s), \ - please change the Customer name or rename the Customer Group" % - self.name, raise_exception=1) + frappe.throw("A Customer Group exists with same name please change the Customer name or rename the Customer Group") def delete_customer_address(self): addresses = frappe.db.sql("""select name, lead from `tabAddress` @@ -140,7 +138,7 @@ class Customer(TransactionBase): @frappe.whitelist() def get_dashboard_info(customer): if not frappe.has_permission("Customer", "read", customer): - frappe.msgprint("No Permission", raise_exception=True) + frappe.msgprint(_("Not permitted"), raise_exception=True) out = {} for doctype in ["Opportunity", "Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]: diff --git a/erpnext/stock/doctype/stock_ledger/stock_ledger.py b/erpnext/stock/doctype/stock_ledger/stock_ledger.py index fca9cb0b70..f566e05719 100644 --- a/erpnext/stock/doctype/stock_ledger/stock_ledger.py +++ b/erpnext/stock/doctype/stock_ledger/stock_ledger.py @@ -4,38 +4,33 @@ from __future__ import unicode_literals import frappe -from frappe.utils import add_days, cstr, flt, nowdate, cint, now - -from frappe import session, msgprint -from erpnext.stock.utils import get_valid_serial_nos - - +from frappe.utils import flt, now from frappe.model.document import Document class StockLedger(Document): - + def update_stock(self, values, is_amended = 'No'): for v in values: sle_id = '' - + # reverse quantities for cancel if v.get('is_cancelled') == 'Yes': v['actual_qty'] = -flt(v['actual_qty']) # cancel matching entry frappe.db.sql("""update `tabStock Ledger Entry` set is_cancelled='Yes', modified=%s, modified_by=%s - where voucher_no=%s and voucher_type=%s""", + where voucher_no=%s and voucher_type=%s""", (now(), frappe.session.user, v['voucher_no'], v['voucher_type'])) if v.get("actual_qty"): sle_id = self.make_entry(v) - + args = v.copy() args.update({ "sle_id": sle_id, "is_amended": is_amended }) - + frappe.get_doc('Warehouse', v["warehouse"]).update_bin(args) @@ -45,7 +40,7 @@ class StockLedger(Document): sle.ignore_permissions = 1 sle.insert() return sle.name - + def repost(self): """ Repost everything! diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index 17d683f988..2336f2211d 100644 --- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -4,15 +4,14 @@ from __future__ import unicode_literals import frappe -from frappe import msgprint -from frappe.utils import flt, getdate, add_days +from frappe import _ +from frappe.utils import flt, getdate, add_days, formatdate from frappe.model.controller import DocListController from datetime import date class StockFreezeError(frappe.ValidationError): pass class StockLedgerEntry(DocListController): - def validate(self): from erpnext.stock.utils import validate_warehouse_company self.validate_mandatory() @@ -55,11 +54,7 @@ class StockLedgerEntry(DocListController): mandatory = ['warehouse','posting_date','voucher_type','voucher_no','actual_qty','company'] for k in mandatory: if not self.get(k): - msgprint("Stock Ledger Entry: '%s' is mandatory" % k, raise_exception = 1) - elif k == 'warehouse': - if not frappe.db.exists("Warehouse", self.get(k)): - msgprint("Warehouse: '%s' does not exist in the system. Please check." % - self.get(k), raise_exception = 1) + frappe.throw(_("{0} is required").format(k)) def validate_item(self): item_det = frappe.db.sql("""select name, has_batch_no, docstatus, @@ -89,15 +84,14 @@ class StockLedgerEntry(DocListController): if stock_frozen_upto: stock_auth_role = frappe.db.get_value('Stock Settings', None,'stock_auth_role') if getdate(self.posting_date) <= getdate(stock_frozen_upto) and not stock_auth_role in frappe.user.get_roles(): - msgprint("You are not authorized to do / modify back dated stock entries before %s" % getdate(stock_frozen_upto).strftime('%d-%m-%Y'), raise_exception=StockFreezeError) + frappe.throw(_("Entries before {0} are frozen").format(formatdate(stock_frozen_upto)), StockFreezeError) stock_frozen_upto_days = int(frappe.db.get_value('Stock Settings', None, 'stock_frozen_upto_days') or 0) if stock_frozen_upto_days: stock_auth_role = frappe.db.get_value('Stock Settings', None,'stock_auth_role') older_than_x_days_ago = (add_days(getdate(self.posting_date), stock_frozen_upto_days) <= date.today()) if older_than_x_days_ago and not stock_auth_role in frappe.user.get_roles(): - msgprint("You are not authorized to do / modify back dated stock entries older than %d days ago" %stock_frozen_upto_days, raise_exception=StockFreezeError) - + frappe.throw(_("Not allowed to update entries older than {0}").format(stock_frozen_upto_days), StockFreezeError) def scrub_posting_time(self): if not self.posting_time or self.posting_time == '00:0': diff --git a/erpnext/stock/doctype/stock_uom_replace_utility/stock_uom_replace_utility.py b/erpnext/stock/doctype/stock_uom_replace_utility/stock_uom_replace_utility.py index 80354ec9fa..a14c21e865 100644 --- a/erpnext/stock/doctype/stock_uom_replace_utility/stock_uom_replace_utility.py +++ b/erpnext/stock/doctype/stock_uom_replace_utility/stock_uom_replace_utility.py @@ -4,7 +4,7 @@ from __future__ import unicode_literals import frappe from frappe.utils import cstr, flt, cint -from frappe import msgprint, _ +from frappe import _ from frappe.model.document import Document @@ -12,71 +12,66 @@ from frappe.model.document import Document class StockUOMReplaceUtility(Document): def validate_mandatory(self): if not cstr(self.item_code): - msgprint("Please Enter an Item.") - raise Exception - + frappe.throw(_("Item is required")) + if not cstr(self.new_stock_uom): - msgprint("Please Enter New Stock UOM.") - raise Exception + frappe.throw(_("New Stock UOM is required")) if cstr(self.current_stock_uom) == cstr(self.new_stock_uom): - msgprint("Current Stock UOM and Stock UOM are same.") - raise Exception - + frappe.throw(_("New Stock UOM must be different from current stock UOM")) + # check conversion factor if not flt(self.conversion_factor): - msgprint("Please Enter Conversion Factor.") - raise Exception - + frappe.throw(_("Conversion Factor is required")) + stock_uom = frappe.db.get_value("Item", self.item_code, "stock_uom") if cstr(self.new_stock_uom) == cstr(stock_uom): - msgprint("Item Master is already updated with New Stock UOM " + cstr(self.new_stock_uom)) - raise Exception - + frappe.throw(_("Item is updated")) + def update_item_master(self): item_doc = frappe.get_doc("Item", self.item_code) item_doc.stock_uom = self.new_stock_uom item_doc.save() - - msgprint(_("Default UOM updated in item ") + self.item_code) - + + frappe.msgprint(_("Stock UOM updatd for Item {0}").format(self.item_code)) + def update_bin(self): # update bin if flt(self.conversion_factor) != flt(1): - frappe.db.sql("""update `tabBin` - set stock_uom = %s, - indented_qty = ifnull(indented_qty,0) * %s, - ordered_qty = ifnull(ordered_qty,0) * %s, - reserved_qty = ifnull(reserved_qty,0) * %s, - planned_qty = ifnull(planned_qty,0) * %s, - projected_qty = actual_qty + ordered_qty + indented_qty + - planned_qty - reserved_qty - where item_code = %s""", (self.new_stock_uom, self.conversion_factor, - self.conversion_factor, self.conversion_factor, + frappe.db.sql("""update `tabBin` + set stock_uom = %s, + indented_qty = ifnull(indented_qty,0) * %s, + ordered_qty = ifnull(ordered_qty,0) * %s, + reserved_qty = ifnull(reserved_qty,0) * %s, + planned_qty = ifnull(planned_qty,0) * %s, + projected_qty = actual_qty + ordered_qty + indented_qty + + planned_qty - reserved_qty + where item_code = %s""", (self.new_stock_uom, self.conversion_factor, + self.conversion_factor, self.conversion_factor, self.conversion_factor, self.item_code)) else: - frappe.db.sql("update `tabBin` set stock_uom = %s where item_code = %s", + frappe.db.sql("update `tabBin` set stock_uom = %s where item_code = %s", (self.new_stock_uom, self.item_code) ) # acknowledge user - msgprint(" All Bins Updated Successfully.") - + frappe.msgprint(_("Stock balances updated")) + def update_stock_ledger_entry(self): # update stock ledger entry from erpnext.stock.stock_ledger import update_entries_after - + if flt(self.conversion_factor) != flt(1): - frappe.db.sql("""update `tabStock Ledger Entry` - set stock_uom = %s, actual_qty = ifnull(actual_qty,0) * %s - where item_code = %s""", + frappe.db.sql("""update `tabStock Ledger Entry` + set stock_uom = %s, actual_qty = ifnull(actual_qty,0) * %s + where item_code = %s""", (self.new_stock_uom, self.conversion_factor, self.item_code)) else: - frappe.db.sql("""update `tabStock Ledger Entry` set stock_uom=%s + frappe.db.sql("""update `tabStock Ledger Entry` set stock_uom=%s where item_code=%s""", (self.new_stock_uom, self.item_code)) - + # acknowledge user - msgprint("Stock Ledger Entries Updated Successfully.") - + frappe.msgprint(_("Stock Ledger entries balances updated")) + # update item valuation if flt(self.conversion_factor) != flt(1): wh = frappe.db.sql("select name from `tabWarehouse`") @@ -84,34 +79,31 @@ class StockUOMReplaceUtility(Document): update_entries_after({"item_code": self.item_code, "warehouse": w[0]}) # acknowledge user - msgprint("Item Valuation Updated Successfully.") + frappe.msgprint(_("Item valuation updated")) - # Update Stock UOM + # Update Stock UOM def update_stock_uom(self): self.validate_mandatory() self.validate_uom_integer_type() - + self.update_stock_ledger_entry() - + self.update_bin() - + self.update_item_master() - + def validate_uom_integer_type(self): current_is_integer = frappe.db.get_value("UOM", self.current_stock_uom, "must_be_whole_number") new_is_integer = frappe.db.get_value("UOM", self.new_stock_uom, "must_be_whole_number") - - if current_is_integer and not new_is_integer: - frappe.msgprint("New UOM must be of type Whole Number", raise_exception=True) if not current_is_integer and new_is_integer: - frappe.msgprint("New UOM must NOT be of type Whole Number", raise_exception=True) + frappe.throw(_("New UOM must NOT be of type Whole Number")) if current_is_integer and new_is_integer and cint(self.conversion_factor)!=self.conversion_factor: - frappe.msgprint("Conversion Factor cannot be fraction", raise_exception=True) + frappe.throw(_("Conversion factor cannot be in fractions")) @frappe.whitelist() def get_stock_uom(item_code): return { 'current_stock_uom': cstr(frappe.db.get_value('Item', item_code, 'stock_uom')) } - + diff --git a/erpnext/stock/doctype/warehouse/warehouse.py b/erpnext/stock/doctype/warehouse/warehouse.py index 3b159fc710..9bb710958b 100644 --- a/erpnext/stock/doctype/warehouse/warehouse.py +++ b/erpnext/stock/doctype/warehouse/warehouse.py @@ -9,7 +9,7 @@ from frappe import throw, msgprint, _ from frappe.model.document import Document class Warehouse(Document): - + def autoname(self): suffix = " - " + frappe.db.get_value("Company", self.company, "abbr") if not self.warehouse_name.endswith(suffix): @@ -18,78 +18,78 @@ class Warehouse(Document): def validate(self): if self.email_id and not validate_email_add(self.email_id): throw(_("Please enter valid Email Id")) - + self.update_parent_account() - + def update_parent_account(self): - if not getattr(self, "__islocal", None) and (self.create_account_under != + if not getattr(self, "__islocal", None) and (self.create_account_under != frappe.db.get_value("Warehouse", self.name, "create_account_under")): - warehouse_account = frappe.db.get_value("Account", - {"account_type": "Warehouse", "company": self.company, + warehouse_account = frappe.db.get_value("Account", + {"account_type": "Warehouse", "company": self.company, "master_name": self.name}, ["name", "parent_account"]) if warehouse_account and warehouse_account[1] != self.create_account_under: acc_doc = frappe.get_doc("Account", warehouse_account[0]) acc_doc.parent_account = self.create_account_under acc_doc.save() - + def on_update(self): self.create_account_head() - + def create_account_head(self): if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")): - if not frappe.db.get_value("Account", {"account_type": "Warehouse", - "master_name": self.name}) and not frappe.db.get_value("Account", + if not frappe.db.get_value("Account", {"account_type": "Warehouse", + "master_name": self.name}) and not frappe.db.get_value("Account", {"account_name": self.warehouse_name}): if self.get("__islocal") or not frappe.db.get_value( "Stock Ledger Entry", {"warehouse": self.name}): self.validate_parent_account() ac_doc = frappe.get_doc({ "doctype": "Account", - 'account_name': self.warehouse_name, - 'parent_account': self.create_account_under, - 'group_or_ledger':'Ledger', - 'company':self.company, + 'account_name': self.warehouse_name, + 'parent_account': self.create_account_under, + 'group_or_ledger':'Ledger', + 'company':self.company, "account_type": "Warehouse", "master_name": self.name, "freeze_account": "No" }) ac_doc.ignore_permissions = True ac_doc.insert() - - msgprint(_("Account Head") + ": " + ac_doc.name + _(" created")) - + + msgprint(_("Account head {0} created")) + def validate_parent_account(self): if not self.create_account_under: - parent_account = frappe.db.get_value("Account", + parent_account = frappe.db.get_value("Account", {"account_name": "Stock Assets", "company": self.company}) if parent_account: self.create_account_under = parent_account else: frappe.throw(_("Please enter account group under which account \ for warehouse ") + self.name +_(" will be created")) - + def on_trash(self): # delete bin - bins = frappe.db.sql("select * from `tabBin` where warehouse = %s", + bins = frappe.db.sql("select * from `tabBin` where warehouse = %s", self.name, as_dict=1) for d in bins: if d['actual_qty'] or d['reserved_qty'] or d['ordered_qty'] or \ d['indented_qty'] or d['projected_qty'] or d['planned_qty']: - throw("""Warehouse: %s can not be deleted as qty exists for item: %s""" + throw("""Warehouse: %s can not be deleted as qty exists for item: %s""" % (self.name, d['item_code'])) else: frappe.db.sql("delete from `tabBin` where name = %s", d['name']) - - warehouse_account = frappe.db.get_value("Account", + + warehouse_account = frappe.db.get_value("Account", {"account_type": "Warehouse", "master_name": self.name}) if warehouse_account: frappe.delete_doc("Account", warehouse_account) - - if frappe.db.sql("""select name from `tabStock Ledger Entry` + + if frappe.db.sql("""select name from `tabStock Ledger Entry` where warehouse = %s""", self.name): - throw(_("""Warehouse can not be deleted as stock ledger entry + throw(_("""Warehouse can not be deleted as stock ledger entry exists for this warehouse.""")) - + def before_rename(self, olddn, newdn, merge=False): # Add company abbr if not provided from erpnext.setup.doctype.company.company import get_name_with_abbr @@ -98,12 +98,12 @@ class Warehouse(Document): if merge: if not frappe.db.exists("Warehouse", new_warehouse): frappe.throw(_("Warehouse ") + new_warehouse +_(" does not exists")) - + if self.company != frappe.db.get_value("Warehouse", new_warehouse, "company"): frappe.throw(_("Both Warehouse must belong to same Company")) - + frappe.db.sql("delete from `tabBin` where warehouse=%s", olddn) - + from erpnext.accounts.utils import rename_account_for rename_account_for("Warehouse", olddn, newdn, merge, self.company) @@ -112,18 +112,18 @@ class Warehouse(Document): def after_rename(self, olddn, newdn, merge=False): if merge: self.recalculate_bin_qty(newdn) - + def recalculate_bin_qty(self, newdn): from erpnext.utilities.repost_stock import repost_stock frappe.db.auto_commit_on_many_writes = 1 frappe.db.set_default("allow_negative_stock", 1) - + for item in frappe.db.sql("""select distinct item_code from ( select name as item_code from `tabItem` where ifnull(is_stock_item, 'Yes')='Yes' - union + union select distinct item_code from tabBin) a"""): repost_stock(item[0], newdn) - - frappe.db.set_default("allow_negative_stock", + + frappe.db.set_default("allow_negative_stock", frappe.db.get_value("Stock Settings", None, "allow_negative_stock")) - frappe.db.auto_commit_on_many_writes = 0 \ No newline at end of file + frappe.db.auto_commit_on_many_writes = 0 diff --git a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py index c88fd11e2a..1de86be8e0 100644 --- a/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py +++ b/erpnext/stock/report/batch_wise_balance_history/batch_wise_balance_history.py @@ -3,31 +3,32 @@ from __future__ import unicode_literals import frappe +from frappe import _ from frappe.utils import flt def execute(filters=None): if not filters: filters = {} - + columns = get_columns(filters) item_map = get_item_details(filters) iwb_map = get_item_warehouse_batch_map(filters) - + data = [] for item in sorted(iwb_map): for wh in sorted(iwb_map[item]): for batch in sorted(iwb_map[item][wh]): qty_dict = iwb_map[item][wh][batch] - data.append([item, item_map[item]["item_name"], - item_map[item]["description"], wh, batch, - qty_dict.opening_qty, qty_dict.in_qty, + data.append([item, item_map[item]["item_name"], + item_map[item]["description"], wh, batch, + qty_dict.opening_qty, qty_dict.in_qty, qty_dict.out_qty, qty_dict.bal_qty ]) - + return columns, data def get_columns(filters): """return columns based on filters""" - + columns = ["Item:Link/Item:100"] + ["Item Name::150"] + ["Description::150"] + \ ["Warehouse:Link/Warehouse:100"] + ["Batch:Link/Batch:100"] + ["Opening Qty::90"] + \ ["In Qty::80"] + ["Out Qty::80"] + ["Balance Qty::90"] @@ -37,21 +38,21 @@ def get_columns(filters): def get_conditions(filters): conditions = "" if not filters.get("from_date"): - frappe.msgprint("Please enter From Date", raise_exception=1) + frappe.throw(_("'From Date' is required")) if filters.get("to_date"): conditions += " and posting_date <= '%s'" % filters["to_date"] else: - frappe.msgprint("Please enter To Date", raise_exception=1) - + frappe.throw(_("'To Date' is required")) + return conditions #get all details def get_stock_ledger_entries(filters): conditions = get_conditions(filters) - return frappe.db.sql("""select item_code, batch_no, warehouse, - posting_date, actual_qty - from `tabStock Ledger Entry` + return frappe.db.sql("""select item_code, batch_no, warehouse, + posting_date, actual_qty + from `tabStock Ledger Entry` where docstatus < 2 %s order by item_code, warehouse""" % conditions, as_dict=1) @@ -82,4 +83,4 @@ def get_item_details(filters): for d in frappe.db.sql("select name, item_name, description from tabItem", as_dict=1): item_map.setdefault(d.name, d) - return item_map \ No newline at end of file + return item_map diff --git a/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py b/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py index 839a70fb35..9b4bb061a1 100644 --- a/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py +++ b/erpnext/stock/report/itemwise_recommended_reorder_level/itemwise_recommended_reorder_level.py @@ -2,6 +2,7 @@ # License: GNU General Public License v3. See license.txt import frappe +from frappe import _ from frappe.utils import getdate, flt def execute(filters=None): @@ -13,7 +14,7 @@ def execute(filters=None): avg_daily_outgoing = 0 diff = ((getdate(filters.get("to_date")) - getdate(filters.get("from_date"))).days)+1 if diff <= 0: - frappe.msgprint("To Date should not be less than eual to From Date",raise_exception=1) + frappe.throw(_("'From Date' must be after 'To Date'")) columns = get_columns() items = get_item_info() @@ -27,8 +28,8 @@ def execute(filters=None): avg_daily_outgoing = flt(total_outgoing/diff, float_preceision) reorder_level = (avg_daily_outgoing * flt(item.lead_time_days)) + flt(item.min_order_qty) - data.append([item.name, item.item_name, item.description, item.min_order_qty, item.lead_time_days, - consumed_item_map.get(item.name, 0), delivered_item_map.get(item.name,0), total_outgoing, + data.append([item.name, item.item_name, item.description, item.min_order_qty, item.lead_time_days, + consumed_item_map.get(item.name, 0), delivered_item_map.get(item.name,0), total_outgoing, avg_daily_outgoing, reorder_level]) return columns , data @@ -36,7 +37,7 @@ def execute(filters=None): def get_columns(): return[ "Item:Link/Item:120", "Item name:Data:120", "Description::160", - "Minimum Inventory Level:Float:160", "Lead Time Days:Float:120", "Consumed:Float:120", + "Minimum Inventory Level:Float:160", "Lead Time Days:Float:120", "Consumed:Float:120", "Delivered:Float:120", "Total Outgoing:Float:120", "Avg Daily Outgoing:Float:160", "Reorder Level:Float:120" ] @@ -47,10 +48,10 @@ def get_item_info(): def get_consumed_items(condition): - cn_items = frappe.db.sql("""select se_item.item_code, + cn_items = frappe.db.sql("""select se_item.item_code, sum(se_item.actual_qty) as 'consume_qty' from `tabStock Entry` se, `tabStock Entry Detail` se_item - where se.name = se_item.parent and se.docstatus = 1 + where se.name = se_item.parent and se.docstatus = 1 and ifnull(se_item.t_warehouse, '') = '' %s group by se_item.item_code""" % (condition), as_dict=1) @@ -64,13 +65,13 @@ def get_delivered_items(condition): dn_items = frappe.db.sql("""select dn_item.item_code, sum(dn_item.qty) as dn_qty from `tabDelivery Note` dn, `tabDelivery Note Item` dn_item - where dn.name = dn_item.parent and dn.docstatus = 1 %s + where dn.name = dn_item.parent and dn.docstatus = 1 %s group by dn_item.item_code""" % (condition), as_dict=1) si_items = frappe.db.sql("""select si_item.item_name, sum(si_item.qty) as si_qty from `tabSales Invoice` si, `tabSales Invoice Item` si_item - where si.name = si_item.parent and si.docstatus = 1 and - ifnull(si.update_stock, 0) = 1 and ifnull(si.is_pos, 0) = 1 %s + where si.name = si_item.parent and si.docstatus = 1 and + ifnull(si.update_stock, 0) = 1 and ifnull(si.is_pos, 0) = 1 %s group by si_item.item_name""" % (condition), as_dict=1) dn_item_map = {} @@ -87,5 +88,5 @@ def get_condition(filters): if filters.get("from_date") and filters.get("to_date"): conditions += " and posting_date between '%s' and '%s'" % (filters["from_date"],filters["to_date"]) else: - frappe.msgprint("Please set date in from date field",raise_exception=1) - return conditions \ No newline at end of file + frappe.throw(_("From and To dates required")) + return conditions diff --git a/erpnext/stock/report/warehouse_wise_stock_balance/warehouse_wise_stock_balance.py b/erpnext/stock/report/warehouse_wise_stock_balance/warehouse_wise_stock_balance.py index eb7df86ee2..16fe3be472 100644 --- a/erpnext/stock/report/warehouse_wise_stock_balance/warehouse_wise_stock_balance.py +++ b/erpnext/stock/report/warehouse_wise_stock_balance/warehouse_wise_stock_balance.py @@ -3,31 +3,32 @@ from __future__ import unicode_literals import frappe +from frappe import _ from frappe.utils import flt def execute(filters=None): if not filters: filters = {} - + columns = get_columns(filters) item_map = get_item_details(filters) iwb_map = get_item_warehouse_map(filters) - + data = [] for company in sorted(iwb_map): for item in sorted(iwb_map[company]): for wh in sorted(iwb_map[company][item]): qty_dict = iwb_map[company][item][wh] - data.append([item, item_map[item]["item_name"], - item_map[item]["description"], wh, - qty_dict.opening_qty, qty_dict.in_qty, + data.append([item, item_map[item]["item_name"], + item_map[item]["description"], wh, + qty_dict.opening_qty, qty_dict.in_qty, qty_dict.out_qty, qty_dict.bal_qty, company ]) - + return columns, data def get_columns(filters): """return columns based on filters""" - + columns = ["Item:Link/Item:100", "Item Name::150", "Description::150", \ "Warehouse:Link/Warehouse:100", "Opening Qty:Float:90", \ "In Qty:Float:80", "Out Qty:Float:80", "Balance Qty:Float:90", "Company:Link/Company:100"] @@ -37,21 +38,21 @@ def get_columns(filters): def get_conditions(filters): conditions = "" if not filters.get("from_date"): - frappe.msgprint("Please enter From Date", raise_exception=1) + frappe.throw(_("'From Date' is required")) if filters.get("to_date"): conditions += " and posting_date <= '%s'" % filters["to_date"] else: - frappe.msgprint("Please enter To Date", raise_exception=1) - + frappe.throw(_("'To Date' is required")) + return conditions #get all details def get_stock_ledger_entries(filters): conditions = get_conditions(filters) - return frappe.db.sql("""select item_code, warehouse, - posting_date, actual_qty, company - from `tabStock Ledger Entry` + return frappe.db.sql("""select item_code, warehouse, + posting_date, actual_qty, company + from `tabStock Ledger Entry` where docstatus < 2 %s order by item_code, warehouse""" % conditions, as_dict=1) @@ -82,4 +83,4 @@ def get_item_details(filters): for d in frappe.db.sql("select name, item_name, description from tabItem", as_dict=1): item_map.setdefault(d.name, d) - return item_map \ No newline at end of file + return item_map diff --git a/erpnext/support/doctype/customer_issue/customer_issue.py b/erpnext/support/doctype/customer_issue/customer_issue.py index 7c6e1b256c..290e74e263 100644 --- a/erpnext/support/doctype/customer_issue/customer_issue.py +++ b/erpnext/support/doctype/customer_issue/customer_issue.py @@ -4,34 +4,32 @@ from __future__ import unicode_literals import frappe -from frappe import session, msgprint +from frappe import session, _ from frappe.utils import today - + from erpnext.utilities.transaction_base import TransactionBase class CustomerIssue(TransactionBase): - + def validate(self): if session['user'] != 'Guest' and not self.customer: - msgprint("Please select Customer from whom issue is raised", - raise_exception=True) - + frappe.throw(_("Customer is required")) + if self.status=="Closed" and \ frappe.db.get_value("Customer Issue", self.name, "status")!="Closed": self.resolution_date = today() self.resolved_by = frappe.session.user - + def on_cancel(self): - lst = frappe.db.sql("""select t1.name - from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 - where t2.parent = t1.name and t2.prevdoc_docname = %s and t1.docstatus!=2""", + lst = frappe.db.sql("""select t1.name + from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 + where t2.parent = t1.name and t2.prevdoc_docname = %s and t1.docstatus!=2""", (self.name)) if lst: lst1 = ','.join([x[0] for x in lst]) - msgprint("Maintenance Visit No. "+lst1+" already created against this customer issue. So can not be Cancelled") - raise Exception + frappe.throw(_("Cancel Material Visit {0} before cancelling this Customer Issue").format(lst1)) else: frappe.db.set(self, 'status', 'Cancelled') @@ -41,22 +39,22 @@ class CustomerIssue(TransactionBase): @frappe.whitelist() def make_maintenance_visit(source_name, target_doc=None): from frappe.model.mapper import get_mapped_doc - - visit = frappe.db.sql("""select t1.name - from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 - where t2.parent=t1.name and t2.prevdoc_docname=%s + + visit = frappe.db.sql("""select t1.name + from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 + where t2.parent=t1.name and t2.prevdoc_docname=%s and t1.docstatus=1 and t1.completion_status='Fully Completed'""", source_name) - + if not visit: doclist = get_mapped_doc("Customer Issue", source_name, { "Customer Issue": { - "doctype": "Maintenance Visit", + "doctype": "Maintenance Visit", "field_map": { - "complaint": "description", - "doctype": "prevdoc_doctype", + "complaint": "description", + "doctype": "prevdoc_doctype", "name": "prevdoc_docname" } } }, target_doc) - - return doclist \ No newline at end of file + + return doclist diff --git a/erpnext/support/doctype/maintenance_visit/maintenance_visit.json b/erpnext/support/doctype/maintenance_visit/maintenance_visit.json index 7d93bba6c9..64833e6cb8 100644 --- a/erpnext/support/doctype/maintenance_visit/maintenance_visit.json +++ b/erpnext/support/doctype/maintenance_visit/maintenance_visit.json @@ -1,302 +1,303 @@ { - "autoname": "MV.#####", - "creation": "2013-01-10 16:34:31.000000", - "docstatus": 0, - "doctype": "DocType", + "autoname": "MV.#####", + "creation": "2013-01-10 16:34:31.000000", + "docstatus": 0, + "doctype": "DocType", "fields": [ { - "fieldname": "customer_details", - "fieldtype": "Section Break", - "label": "Customer Details", - "oldfieldtype": "Section Break", - "options": "icon-user", + "fieldname": "customer_details", + "fieldtype": "Section Break", + "label": "Customer Details", + "oldfieldtype": "Section Break", + "options": "icon-user", "permlevel": 0 - }, + }, { - "fieldname": "column_break0", - "fieldtype": "Column Break", - "oldfieldtype": "Column Break", + "fieldname": "column_break0", + "fieldtype": "Column Break", + "oldfieldtype": "Column Break", "permlevel": 0 - }, + }, { - "fieldname": "customer", - "fieldtype": "Link", - "in_filter": 1, - "label": "Customer", - "oldfieldname": "customer", - "oldfieldtype": "Link", - "options": "Customer", - "permlevel": 0, - "print_hide": 1, - "reqd": 1, + "fieldname": "customer", + "fieldtype": "Link", + "in_filter": 1, + "label": "Customer", + "oldfieldname": "customer", + "oldfieldtype": "Link", + "options": "Customer", + "permlevel": 0, + "print_hide": 1, + "reqd": 1, "search_index": 0 - }, + }, { - "fieldname": "customer_name", - "fieldtype": "Data", - "hidden": 1, - "in_list_view": 1, - "label": "Customer Name", - "permlevel": 0, + "fieldname": "customer_name", + "fieldtype": "Data", + "hidden": 1, + "in_list_view": 1, + "label": "Customer Name", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "address_display", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Address", - "permlevel": 0, + "fieldname": "address_display", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Address", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "contact_display", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Contact", - "permlevel": 0, + "fieldname": "contact_display", + "fieldtype": "Small Text", + "hidden": 1, + "label": "Contact", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "contact_mobile", - "fieldtype": "Data", - "hidden": 1, - "label": "Mobile No", - "permlevel": 0, + "fieldname": "contact_mobile", + "fieldtype": "Data", + "hidden": 1, + "label": "Mobile No", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "contact_email", - "fieldtype": "Data", - "hidden": 1, - "label": "Contact Email", - "permlevel": 0, + "fieldname": "contact_email", + "fieldtype": "Data", + "hidden": 1, + "label": "Contact Email", + "permlevel": 0, "read_only": 1 - }, + }, { - "fieldname": "column_break1", - "fieldtype": "Column Break", - "oldfieldtype": "Column Break", - "permlevel": 0, + "fieldname": "column_break1", + "fieldtype": "Column Break", + "oldfieldtype": "Column Break", + "permlevel": 0, "width": "50%" - }, + }, { - "default": "Today", - "fieldname": "mntc_date", - "fieldtype": "Date", - "label": "Maintenance Date", - "no_copy": 1, - "oldfieldname": "mntc_date", - "oldfieldtype": "Date", - "permlevel": 0, + "default": "Today", + "fieldname": "mntc_date", + "fieldtype": "Date", + "label": "Maintenance Date", + "no_copy": 1, + "oldfieldname": "mntc_date", + "oldfieldtype": "Date", + "permlevel": 0, "reqd": 1 - }, + }, { - "fieldname": "mntc_time", - "fieldtype": "Time", - "label": "Maintenance Time", - "no_copy": 1, - "oldfieldname": "mntc_time", - "oldfieldtype": "Time", + "fieldname": "mntc_time", + "fieldtype": "Time", + "label": "Maintenance Time", + "no_copy": 1, + "oldfieldname": "mntc_time", + "oldfieldtype": "Time", "permlevel": 0 - }, + }, { - "fieldname": "maintenance_details", - "fieldtype": "Section Break", - "label": "Maintenance Details", - "oldfieldtype": "Section Break", - "options": "icon-wrench", + "fieldname": "maintenance_details", + "fieldtype": "Section Break", + "label": "Maintenance Details", + "oldfieldtype": "Section Break", + "options": "icon-wrench", "permlevel": 0 - }, + }, { - "fieldname": "completion_status", - "fieldtype": "Select", - "in_list_view": 1, - "label": "Completion Status", - "oldfieldname": "completion_status", - "oldfieldtype": "Select", - "options": "\nPartially Completed\nFully Completed", - "permlevel": 0, + "fieldname": "completion_status", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Completion Status", + "oldfieldname": "completion_status", + "oldfieldtype": "Select", + "options": "\nPartially Completed\nFully Completed", + "permlevel": 0, "reqd": 1 - }, + }, { - "fieldname": "column_break_14", - "fieldtype": "Column Break", + "fieldname": "column_break_14", + "fieldtype": "Column Break", "permlevel": 0 - }, + }, { - "default": "Unscheduled", - "fieldname": "maintenance_type", - "fieldtype": "Select", - "in_filter": 1, - "in_list_view": 1, - "label": "Maintenance Type", - "oldfieldname": "maintenance_type", - "oldfieldtype": "Select", - "options": "\nScheduled\nUnscheduled\nBreakdown", - "permlevel": 0, - "reqd": 1, + "default": "Unscheduled", + "fieldname": "maintenance_type", + "fieldtype": "Select", + "in_filter": 1, + "in_list_view": 1, + "label": "Maintenance Type", + "oldfieldname": "maintenance_type", + "oldfieldtype": "Select", + "options": "\nScheduled\nUnscheduled\nBreakdown", + "permlevel": 0, + "reqd": 1, "search_index": 0 - }, + }, { - "fieldname": "section_break0", - "fieldtype": "Section Break", - "oldfieldtype": "Section Break", - "options": "icon-wrench", + "fieldname": "section_break0", + "fieldtype": "Section Break", + "oldfieldtype": "Section Break", + "options": "icon-wrench", "permlevel": 0 - }, + }, { - "fieldname": "maintenance_visit_details", - "fieldtype": "Table", - "label": "Maintenance Visit Purpose", - "oldfieldname": "maintenance_visit_details", - "oldfieldtype": "Table", - "options": "Maintenance Visit Purpose", - "permlevel": 0 - }, - { - "fieldname": "more_info", - "fieldtype": "Section Break", - "label": "More Info", - "oldfieldtype": "Section Break", - "options": "icon-file-text", - "permlevel": 0 - }, - { - "fieldname": "customer_feedback", - "fieldtype": "Small Text", - "label": "Customer Feedback", - "oldfieldname": "customer_feedback", - "oldfieldtype": "Small Text", - "permlevel": 0 - }, - { - "fieldname": "col_break3", - "fieldtype": "Column Break", - "permlevel": 0 - }, - { - "default": "Draft", - "fieldname": "status", - "fieldtype": "Data", - "label": "Status", - "no_copy": 1, - "oldfieldname": "status", - "oldfieldtype": "Data", - "options": "\nDraft\nCancelled\nSubmitted", - "permlevel": 0, - "read_only": 1, + "fieldname": "maintenance_visit_details", + "fieldtype": "Table", + "label": "Maintenance Visit Purpose", + "oldfieldname": "maintenance_visit_details", + "oldfieldtype": "Table", + "options": "Maintenance Visit Purpose", + "permlevel": 0, "reqd": 1 - }, + }, { - "fieldname": "amended_from", - "fieldtype": "Data", - "ignore_restrictions": 1, - "label": "Amended From", - "no_copy": 1, - "oldfieldname": "amended_from", - "oldfieldtype": "Data", - "permlevel": 0, - "print_hide": 1, - "read_only": 1, + "fieldname": "more_info", + "fieldtype": "Section Break", + "label": "More Info", + "oldfieldtype": "Section Break", + "options": "icon-file-text", + "permlevel": 0 + }, + { + "fieldname": "customer_feedback", + "fieldtype": "Small Text", + "label": "Customer Feedback", + "oldfieldname": "customer_feedback", + "oldfieldtype": "Small Text", + "permlevel": 0 + }, + { + "fieldname": "col_break3", + "fieldtype": "Column Break", + "permlevel": 0 + }, + { + "default": "Draft", + "fieldname": "status", + "fieldtype": "Data", + "label": "Status", + "no_copy": 1, + "oldfieldname": "status", + "oldfieldtype": "Data", + "options": "\nDraft\nCancelled\nSubmitted", + "permlevel": 0, + "read_only": 1, + "reqd": 1 + }, + { + "fieldname": "amended_from", + "fieldtype": "Data", + "ignore_restrictions": 1, + "label": "Amended From", + "no_copy": 1, + "oldfieldname": "amended_from", + "oldfieldtype": "Data", + "permlevel": 0, + "print_hide": 1, + "read_only": 1, "width": "150px" - }, + }, { - "fieldname": "company", - "fieldtype": "Select", - "in_filter": 1, - "label": "Company", - "oldfieldname": "company", - "oldfieldtype": "Select", - "options": "link:Company", - "permlevel": 0, - "print_hide": 1, - "reqd": 1, + "fieldname": "company", + "fieldtype": "Select", + "in_filter": 1, + "label": "Company", + "oldfieldname": "company", + "oldfieldtype": "Select", + "options": "link:Company", + "permlevel": 0, + "print_hide": 1, + "reqd": 1, "search_index": 0 - }, + }, { - "fieldname": "fiscal_year", - "fieldtype": "Select", - "in_filter": 1, - "label": "Fiscal Year", - "oldfieldname": "fiscal_year", - "oldfieldtype": "Select", - "options": "link:Fiscal Year", - "permlevel": 0, - "print_hide": 1, - "reqd": 1, + "fieldname": "fiscal_year", + "fieldtype": "Select", + "in_filter": 1, + "label": "Fiscal Year", + "oldfieldname": "fiscal_year", + "oldfieldtype": "Select", + "options": "link:Fiscal Year", + "permlevel": 0, + "print_hide": 1, + "reqd": 1, "search_index": 0 - }, + }, { - "depends_on": "customer", - "fieldname": "contact_info_section", - "fieldtype": "Section Break", - "label": "Contact Info", - "options": "icon-bullhorn", + "depends_on": "customer", + "fieldname": "contact_info_section", + "fieldtype": "Section Break", + "label": "Contact Info", + "options": "icon-bullhorn", "permlevel": 0 - }, + }, { - "fieldname": "customer_address", - "fieldtype": "Link", - "label": "Customer Address", - "options": "Address", - "permlevel": 0, + "fieldname": "customer_address", + "fieldtype": "Link", + "label": "Customer Address", + "options": "Address", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "contact_person", - "fieldtype": "Link", - "label": "Contact Person", - "options": "Contact", - "permlevel": 0, + "fieldname": "contact_person", + "fieldtype": "Link", + "label": "Contact Person", + "options": "Contact", + "permlevel": 0, "print_hide": 1 - }, + }, { - "fieldname": "col_break4", - "fieldtype": "Column Break", + "fieldname": "col_break4", + "fieldtype": "Column Break", "permlevel": 0 - }, + }, { - "description": "Add / Edit", - "fieldname": "territory", - "fieldtype": "Link", - "label": "Territory", - "options": "Territory", - "permlevel": 0, + "description": "Add / Edit", + "fieldname": "territory", + "fieldtype": "Link", + "label": "Territory", + "options": "Territory", + "permlevel": 0, "print_hide": 1 - }, + }, { - "description": "Add / Edit", - "fieldname": "customer_group", - "fieldtype": "Link", - "label": "Customer Group", - "options": "Customer Group", - "permlevel": 0, + "description": "Add / Edit", + "fieldname": "customer_group", + "fieldtype": "Link", + "label": "Customer Group", + "options": "Customer Group", + "permlevel": 0, "print_hide": 1 } - ], - "icon": "icon-file-text", - "idx": 1, - "is_submittable": 1, - "modified": "2014-01-20 17:48:57.000000", - "modified_by": "Administrator", - "module": "Support", - "name": "Maintenance Visit", - "owner": "ashwini@webnotestech.com", + ], + "icon": "icon-file-text", + "idx": 1, + "is_submittable": 1, + "modified": "2014-01-20 17:48:57.000001", + "modified_by": "Administrator", + "module": "Support", + "name": "Maintenance Visit", + "owner": "ashwini@webnotestech.com", "permissions": [ { - "amend": 1, - "cancel": 1, - "create": 1, - "delete": 1, - "email": 1, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Maintenance User", - "submit": 1, + "amend": 1, + "cancel": 1, + "create": 1, + "delete": 1, + "email": 1, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Maintenance User", + "submit": 1, "write": 1 } - ], + ], "search_fields": "status,maintenance_type,customer,customer_name, address,mntc_date,company,fiscal_year" -} \ No newline at end of file +} diff --git a/erpnext/support/doctype/maintenance_visit/maintenance_visit.py b/erpnext/support/doctype/maintenance_visit/maintenance_visit.py index b11d6562c2..625aa048ea 100644 --- a/erpnext/support/doctype/maintenance_visit/maintenance_visit.py +++ b/erpnext/support/doctype/maintenance_visit/maintenance_visit.py @@ -3,33 +3,24 @@ from __future__ import unicode_literals import frappe - -from frappe.utils import cstr - -from frappe import msgprint - - +from frappe import _ from erpnext.utilities.transaction_base import TransactionBase class MaintenanceVisit(TransactionBase): - + def get_item_details(self, item_code): return frappe.db.get_value("Item", item_code, ["item_name", "description"], as_dict=1) - + def validate_serial_no(self): for d in self.get('maintenance_visit_details'): if d.serial_no and not frappe.db.exists("Serial No", d.serial_no): frappe.throw("Serial No: "+ d.serial_no + " not exists in the system") - - def validate(self): - if not self.get('maintenance_visit_details'): - msgprint("Please enter maintenance details") - raise Exception + def validate(self): self.validate_serial_no() - + def update_customer_issue(self, flag): for d in self.get('maintenance_visit_details'): if d.prevdoc_docname and d.prevdoc_doctype == 'Customer Issue' : @@ -43,7 +34,7 @@ class MaintenanceVisit(TransactionBase): status = 'Work In Progress' else: nm = frappe.db.sql("select t1.name, t1.mntc_date, t2.service_person, t2.work_done from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent = t1.name and t1.completion_status = 'Partially Completed' and t2.prevdoc_docname = %s and t1.name!=%s and t1.docstatus = 1 order by t1.name desc limit 1", (d.prevdoc_docname, self.name)) - + if nm: status = 'Work In Progress' mntc_date = nm and nm[0][1] or '' @@ -54,9 +45,9 @@ class MaintenanceVisit(TransactionBase): mntc_date = '' service_person = '' work_done = '' - + frappe.db.sql("update `tabCustomer Issue` set resolution_date=%s, resolved_by=%s, resolution_details=%s, status=%s where name =%s",(mntc_date,service_person,work_done,status,d.prevdoc_docname)) - + def check_if_last_visit(self): """check if last maintenance visit against same sales order/ customer issue""" @@ -65,25 +56,25 @@ class MaintenanceVisit(TransactionBase): if d.prevdoc_docname: check_for_docname = d.prevdoc_docname check_for_doctype = d.prevdoc_doctype - + if check_for_docname: check = frappe.db.sql("select t1.name from `tabMaintenance Visit` t1, `tabMaintenance Visit Purpose` t2 where t2.parent = t1.name and t1.name!=%s and t2.prevdoc_docname=%s and t1.docstatus = 1 and (t1.mntc_date > %s or (t1.mntc_date = %s and t1.mntc_time > %s))", (self.name, check_for_docname, self.mntc_date, self.mntc_date, self.mntc_time)) - + if check: check_lst = [x[0] for x in check] check_lst =','.join(check_lst) - msgprint("To cancel this, you need to cancel Maintenance Visit(s) "+cstr(check_lst)+" created after this maintenance visit against same "+check_for_doctype) + frappe.throw(_("Cancel Material Visits {0} before cancelling this Maintenance Visit").format(check_lst)) raise Exception else: self.update_customer_issue(0) - + def on_submit(self): - self.update_customer_issue(1) + self.update_customer_issue(1) frappe.db.set(self, 'status', 'Submitted') - + def on_cancel(self): - self.check_if_last_visit() + self.check_if_last_visit() frappe.db.set(self, 'status', 'Cancelled') def on_update(self): - pass \ No newline at end of file + pass diff --git a/erpnext/support/doctype/newsletter/newsletter.py b/erpnext/support/doctype/newsletter/newsletter.py index 2dce58a440..42f9f09c4f 100644 --- a/erpnext/support/doctype/newsletter/newsletter.py +++ b/erpnext/support/doctype/newsletter/newsletter.py @@ -6,7 +6,7 @@ from __future__ import unicode_literals import frappe import frappe.utils from frappe.utils import cstr -from frappe import msgprint, throw, _ +from frappe import throw, _ from frappe.model.document import Document class Newsletter(Document): @@ -20,10 +20,7 @@ class Newsletter(Document): self.recipients = self.test_email_id.split(",") self.send_to_doctype = "Lead" self.send_bulk() - msgprint("{send} {email}".format**{ - "send": _("Scheduled to send to"), - "email": self.test_email_id - }) + frappe.msgprint(_("Scheduled to send to {0}").format(self.test_email_id)) def send_emails(self): """send emails to leads and customers""" @@ -32,27 +29,23 @@ class Newsletter(Document): self.recipients = self.get_recipients() self.send_bulk() - - msgprint("{send} {recipients} {doctype}(s)".format(**{ - "send": _("Scheduled to send to"), - "recipients": len(self.recipients), - "doctype": self.send_to_doctype - })) + + frappe.msgprint(_("Scheduled to send to {0} recipients").format(len(self.recipients))) frappe.db.set(self, "email_sent", 1) - + def get_recipients(self): self.email_field = None if self.send_to_type=="Contact": self.send_to_doctype = "Contact" - if self.contact_type == "Customer": - return frappe.db.sql_list("""select email_id from tabContact + if self.contact_type == "Customer": + return frappe.db.sql_list("""select email_id from tabContact where ifnull(email_id, '') != '' and ifnull(customer, '') != ''""") - elif self.contact_type == "Supplier": - return frappe.db.sql_list("""select email_id from tabContact + elif self.contact_type == "Supplier": + return frappe.db.sql_list("""select email_id from tabContact where ifnull(email_id, '') != '' and ifnull(supplier, '') != ''""") - + elif self.send_to_type=="Lead": self.send_to_doctype = "Lead" conditions = [] @@ -63,37 +56,37 @@ class Newsletter(Document): if conditions: conditions = "".join(conditions) - - return frappe.db.sql_list("""select email_id from tabLead + + return frappe.db.sql_list("""select email_id from tabLead where ifnull(email_id, '') != '' %s""" % (conditions or "")) elif self.send_to_type=="Employee": self.send_to_doctype = "Employee" self.email_field = "company_email" - return frappe.db.sql_list("""select - if(ifnull(company_email, '')!='', company_email, personal_email) as email_id + return frappe.db.sql_list("""select + if(ifnull(company_email, '')!='', company_email, personal_email) as email_id from `tabEmployee` where status='Active'""") elif self.email_list: email_list = [cstr(email).strip() for email in self.email_list.split(",")] for email in email_list: create_lead(email) - + self.send_to_doctype = "Lead" return email_list - + def send_bulk(self): self.validate_send() sender = self.send_from or frappe.utils.get_formatted_email(self.owner) - + from frappe.utils.email_lib.bulk import send - + if not frappe.flags.in_test: frappe.db.auto_commit_on_many_writes = True - send(recipients = self.recipients, sender = sender, + send(recipients = self.recipients, sender = sender, subject = self.subject, message = self.message, doctype = self.send_to_doctype, email_field = self.email_field or "email_id", ref_doctype = self.doctype, ref_docname = self.name) @@ -103,19 +96,18 @@ class Newsletter(Document): def validate_send(self): if self.get("__islocal"): - throw(_("Please save the Newsletter before sending.")) + throw(_("Please save the Newsletter before sending")) from frappe import conf if (conf.get("status") or None) == "Trial": - throw(_("Sending newsletters is not allowed for Trial users, \ - to prevent abuse of this feature.")) + throw(_("Newsletters is not allowed for Trial users")) @frappe.whitelist() def get_lead_options(): return { - "sources": ["All"] + filter(None, + "sources": ["All"] + filter(None, frappe.db.sql_list("""select distinct source from tabLead""")), - "statuses": ["All"] + filter(None, + "statuses": ["All"] + filter(None, frappe.db.sql_list("""select distinct status from tabLead""")) } @@ -125,10 +117,10 @@ def create_lead(email_id): from email.utils import parseaddr from frappe.model.naming import get_default_naming_series real_name, email_id = parseaddr(email_id) - + if frappe.db.get_value("Lead", {"email_id": email_id}): return - + lead = frappe.get_doc({ "doctype": "Lead", "email_id": email_id, @@ -138,4 +130,4 @@ def create_lead(email_id): "company": frappe.db.get_default("company"), "source": "Email" }) - lead.insert() \ No newline at end of file + lead.insert() diff --git a/erpnext/support/doctype/support_email_settings/support_email_settings.py b/erpnext/support/doctype/support_email_settings/support_email_settings.py index 1efa628a1b..592c1a90a8 100644 --- a/erpnext/support/doctype/support_email_settings/support_email_settings.py +++ b/erpnext/support/doctype/support_email_settings/support_email_settings.py @@ -5,24 +5,24 @@ from __future__ import unicode_literals import frappe - +from frappe import _ from frappe.model.document import Document from frappe.utils.email_lib.receive import POP3Mailbox import _socket, poplib class SupportEmailSettings(Document): - + def validate(self): """ Checks support ticket email settings """ - if self.sync_support_mails and self.mail_server: + if self.sync_support_mails and self.mail_server: inc_email = frappe.get_doc('Incoming Email Settings') # inc_email.encode() inc_email.host = self.mail_server inc_email.use_ssl = self.use_ssl try: - err_msg = 'User Name or Support Password missing. Please enter and try again.' + err_msg = _('User Name or Support Password missing. Please enter and try again.') if not (self.mail_login and self.mail_password): raise AttributeError, err_msg inc_email.username = self.mail_login @@ -32,14 +32,13 @@ class SupportEmailSettings(Document): raise pop_mb = POP3Mailbox(inc_email) - + try: pop_mb.connect() except _socket.error, e: # Invalid mail server -- due to refusing connection - frappe.msgprint('Invalid POP3 Mail Server. Please rectify and try again.') + frappe.msgprint(_('Invalid Mail Server. Please rectify and try again.')) raise except poplib.error_proto, e: - frappe.msgprint('Invalid User Name or Support Password. Please rectify and try again.') + frappe.msgprint(_('Invalid User Name or Support Password. Please rectify and try again.')) raise - \ No newline at end of file diff --git a/erpnext/utilities/__init__.py b/erpnext/utilities/__init__.py index e3a1e7f151..e96ae83c8a 100644 --- a/erpnext/utilities/__init__.py +++ b/erpnext/utilities/__init__.py @@ -1,27 +1,27 @@ # 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 frappe -from frappe import _, msgprint +from frappe import _ from frappe.utils import cint, comma_or def validate_status(status, options): if status not in options: - msgprint(_("Status must be one of ") + comma_or(options), raise_exception=True) + frappe.throw(_("Status must be one of {0}").format(comma_or(options))) def build_filter_conditions(filters): conditions, filter_values = [], [] @@ -30,4 +30,4 @@ def build_filter_conditions(filters): filter_values.append(filters[key]) conditions = conditions and " and " + " and ".join(conditions) or "" - return conditions, filter_values \ No newline at end of file + return conditions, filter_values diff --git a/erpnext/utilities/doctype/address/address.py b/erpnext/utilities/doctype/address/address.py index 04d54f2378..055857487b 100644 --- a/erpnext/utilities/doctype/address/address.py +++ b/erpnext/utilities/doctype/address/address.py @@ -4,8 +4,8 @@ from __future__ import unicode_literals import frappe -from frappe import msgprint, throw, _ -from frappe.utils import cstr, cint +from frappe import throw, _ +from frappe.utils import cstr from frappe.model.document import Document @@ -20,30 +20,30 @@ class Address(Document): self.name = cstr(self.address_title).strip() + "-" + cstr(self.address_type).strip() else: throw(_("Address Title is mandatory.")) - + def validate(self): self.validate_primary_address() self.validate_shipping_address() - + def validate_primary_address(self): """Validate that there can only be one primary address for particular customer, supplier""" if self.is_primary_address == 1: self._unset_other("is_primary_address") - + elif self.is_shipping_address != 1: for fieldname in ["customer", "supplier", "sales_partner", "lead"]: if self.get(fieldname): if not frappe.db.sql("""select name from `tabAddress` where is_primary_address=1 - and `%s`=%s and name!=%s""" % (fieldname, "%s", "%s"), + and `%s`=%s and name!=%s""" % (fieldname, "%s", "%s"), (self.get(fieldname), self.name)): self.is_primary_address = 1 break - + def validate_shipping_address(self): """Validate that there can only be one shipping address for particular customer, supplier""" if self.is_shipping_address == 1: self._unset_other("is_shipping_address") - + def _unset_other(self, is_address_type): for fieldname in ["customer", "supplier", "sales_partner", "lead"]: if self.get(fieldname): @@ -55,21 +55,21 @@ class Address(Document): def get_address_display(address_dict): if not isinstance(address_dict, dict): address_dict = frappe.db.get_value("Address", address_dict, "*", as_dict=True) or {} - + meta = frappe.get_meta("Address") - sequence = (("", "address_line1"), - ("\n", "address_line2"), + sequence = (("", "address_line1"), + ("\n", "address_line2"), ("\n", "city"), - ("\n", "state"), - ("\n" + meta.get_label("pincode") + ": ", "pincode"), + ("\n", "state"), + ("\n" + meta.get_label("pincode") + ": ", "pincode"), ("\n", "country"), - ("\n" + meta.get_label("phone") + ": ", "phone"), + ("\n" + meta.get_label("phone") + ": ", "phone"), ("\n" + meta.get_label("fax") + ": ", "fax")) - + display = "" for separator, fieldname in sequence: if address_dict.get(fieldname): display += separator + address_dict.get(fieldname) - + return display.strip() diff --git a/erpnext/utilities/doctype/note/note.py b/erpnext/utilities/doctype/note/note.py index f0c7f0e922..280adf41d0 100644 --- a/erpnext/utilities/doctype/note/note.py +++ b/erpnext/utilities/doctype/note/note.py @@ -5,24 +5,24 @@ from __future__ import unicode_literals import frappe - +from frappe import _ from frappe.model.document import Document class Note(Document): - + def autoname(self): # replace forbidden characters import re self.name = re.sub("[%'\"#*?`]", "", self.title.strip()) - + def onload(self): if not self.public and frappe.session.user != self.owner: if frappe.session.user not in [d.user for d in self.get("share_with")]: - frappe.msgprint("You are not authorized to read this record.", raise_exception=True) - + frappe.throw(_("Not permitted"), frappe.PermissionError) + def validate(self): if not self.get("__islocal"): if frappe.session.user != self.owner: - if frappe.session.user not in frappe.db.sql_list("""select user from `tabNote User` + if frappe.session.user not in frappe.db.sql_list("""select user from `tabNote User` where parent=%s and permission='Edit'""", self.name): - frappe.msgprint("You are not authorized to edit this record.", raise_exception=True) + frappe.throw(_("Not permitted"), frappe.PermissionError) diff --git a/erpnext/utilities/doctype/rename_tool/rename_tool.py b/erpnext/utilities/doctype/rename_tool/rename_tool.py index 42c69f624c..07d44c3b6a 100644 --- a/erpnext/utilities/doctype/rename_tool/rename_tool.py +++ b/erpnext/utilities/doctype/rename_tool/rename_tool.py @@ -11,34 +11,32 @@ from frappe.model.document import Document class RenameTool(Document): pass - + @frappe.whitelist() def get_doctypes(): return frappe.db.sql_list("""select name from tabDocType where ifnull(allow_rename,0)=1 and module!='Core' order by name""") - + @frappe.whitelist() def upload(select_doctype=None, rows=None): from frappe.utils.datautils import read_csv_content_from_uploaded_file - from frappe.modules import scrub from frappe.model.rename_doc import rename_doc if not select_doctype: select_doctype = frappe.form_dict.select_doctype - + if not frappe.has_permission(select_doctype, "write"): raise frappe.PermissionError if not rows: rows = read_csv_content_from_uploaded_file() if not rows: - frappe.msgprint(_("Please select a valid csv file with data.")) - raise Exception - - if len(rows) > 500: - frappe.msgprint(_("Max 500 rows only.")) - raise Exception - + frappe.throw(_("Please select a valid csv file with data")) + + max_rows = 500 + if len(rows) > max_rows: + frappe.throw(_("Maximum {0} rows allowed").format(max_rows)) + rename_log = [] for row in rows: # if row has some content @@ -53,5 +51,5 @@ def upload(select_doctype=None, rows=None): rename_log.append("" + \ _("Failed: ") + row[0] + " -> " + row[1] + "") rename_log.append("" + repr(e) + "") - - return rename_log \ No newline at end of file + + return rename_log diff --git a/erpnext/utilities/doctype/sms_control/sms_control.py b/erpnext/utilities/doctype/sms_control/sms_control.py index ba858c6dd3..e599eeaa91 100644 --- a/erpnext/utilities/doctype/sms_control/sms_control.py +++ b/erpnext/utilities/doctype/sms_control/sms_control.py @@ -19,7 +19,7 @@ class SMSControl(Document): invalid_char_list = [' ', '+', '-', '(', ')'] for x in invalid_char_list: d = d.replace(x, '') - + validated_receiver_list.append(d) if not validated_receiver_list: @@ -34,21 +34,18 @@ class SMSControl(Document): 'ERPNXT' if len(sender_name) > 6 and \ frappe.db.get_default("country") == "India": - throw(_(""" - As per TRAI rule, sender name must be exactly 6 characters. + throw("""As per TRAI rule, sender name must be exactly 6 characters. Kindly change sender name in Setup --> Global Defaults. - - Note: Hyphen, space, numeric digit, special characters are not allowed. - """)) + Note: Hyphen, space, numeric digit, special characters are not allowed.""") return sender_name - + def get_contact_number(self, arg): "returns mobile number of the contact" args = json.loads(arg) - number = frappe.db.sql("""select mobile_no, phone from tabContact where name=%s and %s=%s""" % + number = frappe.db.sql("""select mobile_no, phone from tabContact where name=%s and %s=%s""" % ('%s', args['key'], '%s'), (args['contact_name'], args['value'])) return number and (number[0][0] or number[0][1]) or '' - + def send_form_sms(self, arg): "called from client side" args = json.loads(arg) @@ -72,7 +69,7 @@ class SMSControl(Document): args = {ss.message_parameter : arg.get('message')} for d in ss.get("static_parameter_details"): args[d.parameter] = d.value - + resp = [] for d in arg.get('receiver_list'): args[ss.receiver_parameter] = d diff --git a/erpnext/utilities/transaction_base.py b/erpnext/utilities/transaction_base.py index 1934f4c95f..f680bcb948 100644 --- a/erpnext/utilities/transaction_base.py +++ b/erpnext/utilities/transaction_base.py @@ -15,26 +15,26 @@ class TransactionBase(StatusUpdater): if int(frappe.db.get_value("Notification Control", None, dt) or 0): self.set("__notification_message", frappe.db.get_value("Notification Control", None, dt + "_message")) - + def validate_posting_time(self): if not self.posting_time: self.posting_time = now_datetime().strftime('%H:%M:%S') - + def add_calendar_event(self, opts, force=False): if self.contact_by != cstr(self._prev.contact_by) or \ self.contact_date != cstr(self._prev.contact_date) or force: - + self.delete_events() self._add_calendar_event(opts) - + def delete_events(self): - frappe.delete_doc("Event", frappe.db.sql_list("""select name from `tabEvent` - where ref_type=%s and ref_name=%s""", (self.doctype, self.name)), + frappe.delete_doc("Event", frappe.db.sql_list("""select name from `tabEvent` + where ref_type=%s and ref_name=%s""", (self.doctype, self.name)), ignore_permissions=True) - + def _add_calendar_event(self, opts): opts = frappe._dict(opts) - + if self.contact_date: event_doclist = frappe.get_doc({ "doctype": "Event", @@ -46,18 +46,18 @@ class TransactionBase(StatusUpdater): "ref_type": self.doctype, "ref_name": self.name }) - + if frappe.db.exists("User", self.contact_by): event_doclist.append("event_individuals", { "doctype": "Event User", "person": self.contact_by }) - + event_doclist.insert() - + def validate_uom_is_integer(self, uom_field, qty_fields): validate_uom_is_integer(self, uom_field, qty_fields) - + def validate_with_previous_doc(self, source_dt, ref): for key, val in ref.items(): is_child = val.get("is_child_table") @@ -71,27 +71,26 @@ class TransactionBase(StatusUpdater): if ref_dn not in item_ref_dn: item_ref_dn.append(ref_dn) elif not val.get("allow_duplicate_prev_row_id"): - frappe.msgprint(_("Row ") + cstr(d.idx + 1) + - _(": Duplicate row from same ") + key, raise_exception=1) + frappe.throw(_("Duplicate row {0} with same {1}").format(d.idx, key)) elif ref_dn: ref_doc.setdefault(key, []) if ref_dn not in ref_doc[key]: ref_doc[key].append(ref_dn) if ref_doc: self.compare_values(ref_doc, val["compare_fields"]) - + def compare_values(self, ref_doc, fields, doc=None): for ref_doctype, ref_dn_list in ref_doc.items(): for ref_docname in ref_dn_list: - prevdoc_values = frappe.db.get_value(ref_doctype, ref_docname, + prevdoc_values = frappe.db.get_value(ref_doctype, ref_docname, [d[0] for d in fields], as_dict=1) for field, condition in fields: if prevdoc_values[field] is not None: self.validate_value(field, condition, prevdoc_values[field], doc) - + def delete_events(ref_type, ref_name): - frappe.delete_doc("Event", frappe.db.sql_list("""select name from `tabEvent` + frappe.delete_doc("Event", frappe.db.sql_list("""select name from `tabEvent` where ref_type=%s and ref_name=%s""", (ref_type, ref_name)), for_reload=True) class UOMMustBeIntegerError(frappe.ValidationError): pass @@ -99,11 +98,11 @@ class UOMMustBeIntegerError(frappe.ValidationError): pass def validate_uom_is_integer(doc, uom_field, qty_fields): if isinstance(qty_fields, basestring): qty_fields = [qty_fields] - + distinct_uoms = list(set([d.get(uom_field) for d in doc.get_all_children()])) - integer_uoms = filter(lambda uom: frappe.db.get_value("UOM", uom, + integer_uoms = filter(lambda uom: frappe.db.get_value("UOM", uom, "must_be_whole_number") or None, distinct_uoms) - + if not integer_uoms: return @@ -112,7 +111,4 @@ def validate_uom_is_integer(doc, uom_field, qty_fields): for f in qty_fields: if d.get(f): if cint(d.get(f))!=d.get(f): - frappe.msgprint(_("For UOM") + " '" + d.get(uom_field) \ - + "': " + _("Quantity cannot be a fraction.") \ - + " " + _("In Row") + ": " + str(d.idx), - raise_exception=UOMMustBeIntegerError) + frappe.throw(_("Quantity cannot be a fraction in row {0}").format(d.idx), UOMMustBeIntegerError)