diff --git a/accounts/doctype/bank_reconciliation/bank_reconciliation.py b/accounts/doctype/bank_reconciliation/bank_reconciliation.py index 980af5844f8..f19df48306e 100644 --- a/accounts/doctype/bank_reconciliation/bank_reconciliation.py +++ b/accounts/doctype/bank_reconciliation/bank_reconciliation.py @@ -66,6 +66,6 @@ class DocType: vouchers.append(d.voucher_id) if vouchers: - msgprint("Clearance Date updated in %s" % vouchers) + msgprint("Clearance Date updated in %s" % ", ".join(vouchers)) else: msgprint("Clearance Date not mentioned") \ No newline at end of file diff --git a/accounts/doctype/journal_voucher/journal_voucher.py b/accounts/doctype/journal_voucher/journal_voucher.py index 9b1ca7a105b..f7d4035a58e 100644 --- a/accounts/doctype/journal_voucher/journal_voucher.py +++ b/accounts/doctype/journal_voucher/journal_voucher.py @@ -43,6 +43,8 @@ class DocType(AccountsController): if not self.doc.is_opening: self.doc.is_opening='No' + self.doc.clearance_date = None + self.validate_debit_credit() self.validate_cheque_info() self.validate_entries_for_advance() diff --git a/accounts/doctype/pos_setting/pos_setting.txt b/accounts/doctype/pos_setting/pos_setting.txt index 4e30b57593b..80cb1ecdc9c 100755 --- a/accounts/doctype/pos_setting/pos_setting.txt +++ b/accounts/doctype/pos_setting/pos_setting.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-03-26 11:03:07", + "creation": "2013-04-30 12:58:25", "docstatus": 0, - "modified": "2013-03-26 12:48:18", + "modified": "2013-05-03 14:36:24", "modified_by": "Administrator", "owner": "Administrator" }, @@ -40,6 +40,7 @@ "doctype": "DocField", "fieldname": "user", "fieldtype": "Link", + "in_list_view": 1, "label": "User", "oldfieldname": "user", "oldfieldtype": "Link", @@ -99,6 +100,7 @@ "doctype": "DocField", "fieldname": "company", "fieldtype": "Link", + "in_list_view": 1, "label": "Company", "oldfieldname": "company", "oldfieldtype": "Link", @@ -210,12 +212,6 @@ "oldfieldtype": "Select", "options": "link:Print Heading" }, - { - "create": 1, - "doctype": "DocPerm", - "role": "System Manager", - "write": 1 - }, { "create": 1, "doctype": "DocPerm", diff --git a/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.txt b/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.txt index 576730779ae..619aed1954c 100644 --- a/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.txt +++ b/accounts/doctype/purchase_taxes_and_charges/purchase_taxes_and_charges.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-03-26 06:51:12", + "creation": "2013-04-19 11:00:06", "docstatus": 0, - "modified": "2013-04-17 14:05:19", + "modified": "2013-05-07 11:23:56", "modified_by": "Administrator", "owner": "Administrator" }, @@ -35,6 +35,7 @@ "oldfieldname": "category", "oldfieldtype": "Select", "options": "Valuation and Total\nValuation\nTotal", + "read_only": 0, "reqd": 1 }, { @@ -45,6 +46,7 @@ "oldfieldname": "charge_type", "oldfieldtype": "Select", "options": "\nActual\nOn Net Total\nOn Previous Row Amount\nOn Previous Row Total", + "read_only": 0, "reqd": 1 }, { @@ -55,6 +57,7 @@ "oldfieldname": "account_head", "oldfieldtype": "Link", "options": "Account", + "read_only": 0, "reqd": 1 }, { @@ -65,7 +68,8 @@ "label": "Cost Center", "oldfieldname": "cost_center", "oldfieldtype": "Link", - "options": "Cost Center" + "options": "Cost Center", + "read_only": 0 }, { "doctype": "DocField", @@ -75,17 +79,18 @@ "oldfieldname": "description", "oldfieldtype": "Small Text", "print_width": "300px", + "read_only": 0, "reqd": 1, "width": "300px" }, { "doctype": "DocField", "fieldname": "rate", - "fieldtype": "Currency", + "fieldtype": "Float", "label": "Rate", "oldfieldname": "rate", "oldfieldtype": "Currency", - "options": "Company:company:default_currency", + "read_only": 0, "reqd": 0 }, { @@ -96,6 +101,7 @@ "oldfieldname": "tax_amount", "oldfieldtype": "Currency", "options": "Company:company:default_currency", + "read_only": 0, "reqd": 0 }, { @@ -115,7 +121,8 @@ "hidden": 0, "label": "Enter Row", "oldfieldname": "row_id", - "oldfieldtype": "Data" + "oldfieldtype": "Data", + "read_only": 0 }, { "default": "Add", @@ -126,6 +133,7 @@ "oldfieldname": "add_deduct_tax", "oldfieldtype": "Select", "options": "Add\nDeduct", + "read_only": 0, "reqd": 1 }, { @@ -149,6 +157,7 @@ "oldfieldname": "parenttype", "oldfieldtype": "Data", "print_hide": 1, + "read_only": 0, "search_index": 0 }, { @@ -163,6 +172,7 @@ "oldfieldtype": "Currency", "options": "Company:company:default_currency", "print_hide": 1, + "read_only": 0, "report_hide": 1 }, { @@ -177,6 +187,7 @@ "oldfieldtype": "Currency", "options": "Company:company:default_currency", "print_hide": 1, + "read_only": 0, "report_hide": 1 } ] \ No newline at end of file diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py index f44a787de95..87f73c19ab6 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.py +++ b/accounts/doctype/sales_invoice/sales_invoice.py @@ -45,7 +45,7 @@ class DocType(SellingController): def validate(self): super(DocType, self).validate() - + self.fetch_missing_values() self.validate_posting_time() self.so_dn_required() self.validate_proj_cust() @@ -137,7 +137,27 @@ class DocType(SellingController): def on_update_after_submit(self): self.validate_recurring_invoice() self.convert_to_recurring() - + + def fetch_missing_values(self): + # fetch contact and address details for customer, if they are not mentioned + if not (self.doc.contact_person and self.doc.customer_address): + for fieldname, val in self.get_default_address_and_contact("customer").items(): + if not self.doc.fields.get(fieldname) and self.meta.get_field(fieldname): + self.doc.fields[fieldname] = val + + # fetch missing item values + for item in self.doclist.get({"parentfield": "entries"}): + if item.fields.get("item_code"): + ret = get_obj('Sales Common').get_item_details(item.fields, self) + for fieldname, value in ret.items(): + if self.meta.get_field(fieldname, parentfield="entries") and \ + not item.fields.get(fieldname): + item.fields[fieldname] = value + + # fetch pos details, if they are not fetched + if cint(self.doc.is_pos): + self.set_pos_fields(for_validate=True) + def update_time_log_batch(self, sales_invoice): for d in self.doclist.get({"doctype":"Sales Invoice Item"}): if d.time_log_batch: @@ -153,60 +173,42 @@ class DocType(SellingController): webnotes.msgprint(_("Time Log Batch status must be 'Submitted'") + ":" + d.time_log_batch, raise_exception=True) - def set_pos_fields(self): + def set_pos_fields(self, for_validate=False): """Set retail related fields from pos settings""" - pos = self.pos_details - - if pos: - val = webnotes.conn.sql("""select name from `tabAccount` - where name = %s and docstatus != 2""", - (cstr(self.doc.customer) + " - " + self.get_company_abbr())) - - val = val and val[0][0] or '' - if not val: val = pos[0]['customer_account'] or '' + if cint(self.doc.is_pos) != 1: + return + + if self.pos_settings: + pos = self.pos_settings[0] + + self.doc.conversion_rate = flt(pos.conversion_rate) if not self.doc.debit_to: - webnotes.conn.set(self.doc,'debit_to',val) - - lst = ['territory', 'naming_series', 'currency', 'charge', 'letter_head', 'tc_name', - 'price_list_name', 'company', 'select_print_heading', 'cash_bank_account'] + self.doc.debit_to = self.doc.customer and webnotes.conn.get_value("Account", { + "name": self.doc.customer + " - " + self.get_company_abbr(), + "docstatus": ["!=", 2] + }) or pos.customer_account - for i in lst: - self.doc.fields[i] = pos[0][i] or '' + for fieldname in ('territory', 'naming_series', 'currency', 'charge', 'letter_head', 'tc_name', + 'price_list_name', 'company', 'select_print_heading', 'cash_bank_account'): + if (not for_validate) or (for_validate and not self.doc.fields.get(fieldname)): + self.doc.fields[fieldname] = pos.get(fieldname) - self.set_pos_item_values() - - self.doc.conversion_rate = flt(pos[0]['conversion_rate']) or 0 + # set pos values in items + for doc in self.doclist.get({"parentfield": "entries"}): + if doc.fields.get('item_code'): + for fieldname, val in self.apply_pos_settings(doc.fields).items(): + if (not for_validate) or (for_validate and not self.doc.fields.get(fieldname)): + doc.fields[fieldname] = val - #fetch terms - if self.doc.tc_name: + # fetch terms + if self.doc.tc_name and not self.doc.terms: self.get_tc_details() - #fetch charges - if self.doc.charge: + # fetch charges + if self.doc.charge and not len(self.doclist.get({"parentfield": "other_charges"})): self.get_other_charges() - - def set_pos_item_values(self): - """Set default values related to pos for previously created sales invoice.""" - if cint(self.doc.is_pos) == 1: - dtl = self.pos_details - - for d in getlist(self.doclist,'entries'): - # overwrite if mentioned in item - item = webnotes.conn.sql("""select default_income_account, - default_sales_cost_center, default_warehouse, purchase_account - from tabItem where name = %s""", (d.item_code,), as_dict=1) - - d.income_account = (item and item[0]['default_income_account']) \ - or (dtl and dtl[0]['income_account']) or d.income_account - d.cost_center = (item and item[0]['default_sales_cost_center']) \ - or (dtl and dtl[0]['cost_center']) or d.cost_center - d.warehouse = (item and item[0]['default_warehouse']) \ - or (dtl and dtl[0]['warehouse']) or d.warehouse - d.expense_account = (item and item[0].purchase_account) \ - or (dtl and dtl[0].expense_account) or d.expense_account - def get_customer_account(self): """Get Account Head to which amount needs to be Debited based on Customer""" if not self.doc.company: @@ -299,60 +301,59 @@ class DocType(SellingController): args = args and json.loads(args) or {} if args.get('item_code'): ret = get_obj('Sales Common').get_item_details(args, self) - return self.get_pos_details(args, ret) - else: - for doc in self.doclist: + + if cint(self.doc.is_pos) == 1 and self.pos_settings: + ret = self.apply_pos_settings(args, ret) + + return ret + + elif cint(self.doc.is_pos) == 1 and self.pos_settings: + for doc in self.doclist.get({"parentfield": "entries"}): if doc.fields.get('item_code'): - arg = { - 'item_code':doc.fields.get('item_code'), - 'income_account':doc.fields.get('income_account'), - 'cost_center': doc.fields.get('cost_center'), - 'warehouse': doc.fields.get('warehouse'), - 'expense_account': doc.fields.get('expense_account'), - } - - ret = self.get_pos_details(arg) + ret = self.apply_pos_settings(doc.fields) for r in ret: if not doc.fields.get(r): doc.fields[r] = ret[r] @property - def pos_details(self): - if not hasattr(self, "_pos_details"): + def pos_settings(self): + if not hasattr(self, "_pos_settings"): dtl = webnotes.conn.sql("""select * from `tabPOS Setting` where user = %s and company = %s""", (webnotes.session['user'], self.doc.company), as_dict=1) if not dtl: dtl = webnotes.conn.sql("""select * from `tabPOS Setting` where ifnull(user,'') = '' and company = %s""", self.doc.company, as_dict=1) - self._pos_details = dtl + self._pos_settings = dtl - return self._pos_details + return self._pos_settings - def get_pos_details(self, args, ret = {}): - if args['item_code'] and cint(self.doc.is_pos) == 1: - dtl = self.pos_details - - item = webnotes.conn.sql("""select default_income_account, default_sales_cost_center, - default_warehouse, purchase_account from tabItem where name = %s""", - args['item_code'], as_dict=1) - - ret['income_account'] = item and item[0].get('default_income_account') \ - or (dtl and dtl[0].get('income_account') or args.get('income_account')) - - ret['cost_center'] = item and item[0].get('default_sales_cost_center') \ - or (dtl and dtl[0].get('cost_center') or args.get('cost_center')) + def apply_pos_settings(self, args, ret=None): + if not ret: ret = {} + + pos = self.pos_settings[0] + + item = webnotes.conn.sql("""select default_income_account, default_sales_cost_center, + default_warehouse, purchase_account from tabItem where name = %s""", + args.get('item_code'), as_dict=1) + + if item: + item = item[0] - ret['warehouse'] = item and item[0].get('default_warehouse') \ - or (dtl and dtl[0].get('warehouse') or args.get('warehouse')) + ret.update({ + "income_account": item.get("default_income_account") \ + or pos.get("income_account") or args.get("income_account"), + "cost_center": item.get("default_sales_cost_center") \ + or pos.get("cost_center") or args.get("cost_center"), + "warehouse": item.get("default_warehouse") \ + or pos.get("warehouse") or args.get("warehouse"), + "expense_account": item.get("purchase_account") \ + or pos.get("expense_account") or args.get("expense_account") + }) - ret['expense_account'] = item and item[0].get('purchase_account') \ - or (dtl and dtl[0].get('expense_account') or args.get('expense_account')) - - if ret['warehouse']: - actual_qty = webnotes.conn.sql("""select actual_qty from `tabBin` - where item_code = %s and warehouse = %s""", - (args['item_code'], ret['warehouse'])) - ret['actual_qty']= actual_qty and flt(actual_qty[0][0]) or 0 + if ret.get("warehouse"): + ret["actual_qty"] = flt(webnotes.conn.get_value("Bin", + {"item_code": args.get("item_code"), "warehouse": args.get("warehouse")}, + "actual_qty")) return ret def get_barcode_details(self, barcode): diff --git a/accounts/doctype/sales_invoice/test_sales_invoice.py b/accounts/doctype/sales_invoice/test_sales_invoice.py index fd8dc648d24..b46cdd17770 100644 --- a/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -90,6 +90,9 @@ class TestSalesInvoice(unittest.TestCase): webnotes.conn.sql("delete from `tabStock Ledger Entry`") webnotes.defaults.set_global_default("auto_inventory_accounting", 1) + old_default_company = webnotes.conn.get_default("company") + webnotes.conn.set_default("company", "_Test Company") + self._insert_purchase_receipt() self._insert_pos_settings() @@ -106,7 +109,8 @@ class TestSalesInvoice(unittest.TestCase): # check stock ledger entries sle = webnotes.conn.sql("""select * from `tabStock Ledger Entry` - where voucher_type = 'Sales Invoice' and voucher_no = %s""", si.doc.name, as_dict=1)[0] + where voucher_type = 'Sales Invoice' and voucher_no = %s""", + si.doc.name, as_dict=1)[0] self.assertTrue(sle) self.assertEquals([sle.item_code, sle.warehouse, sle.actual_qty], ["_Test Item", "_Test Warehouse", -5.0]) @@ -145,6 +149,7 @@ class TestSalesInvoice(unittest.TestCase): self.assertEquals(gl_count[0][0], 16) webnotes.defaults.set_global_default("auto_inventory_accounting", 0) + webnotes.conn.set_default("company", old_default_company) def test_sales_invoice_gl_entry_with_aii_no_item_code(self): webnotes.defaults.set_global_default("auto_inventory_accounting", 1) @@ -337,7 +342,7 @@ class TestSalesInvoice(unittest.TestCase): # change posting date but keep recuring day to be today si7 = webnotes.bean(copy=base_si.doclist) si7.doc.fields.update({ - "posting_date": add_to_date(today, days=-3) + "posting_date": add_to_date(today, days=-1) }) si7.insert() si7.submit() @@ -345,7 +350,7 @@ class TestSalesInvoice(unittest.TestCase): # setting so that _test function works si7.doc.posting_date = today self._test_recurring_invoice(si7, True) - + def _test_recurring_invoice(self, base_si, first_and_last_day): from webnotes.utils import add_months, get_last_day, getdate from accounts.doctype.sales_invoice.sales_invoice import manage_recurring_invoices @@ -361,7 +366,8 @@ class TestSalesInvoice(unittest.TestCase): manage_recurring_invoices(next_date=next_date, commit=False) recurred_invoices = webnotes.conn.sql("""select name from `tabSales Invoice` - where recurring_id=%s and docstatus=1 order by name desc""", base_si.doc.recurring_id) + where recurring_id=%s and docstatus=1 order by name desc""", + base_si.doc.recurring_id) self.assertEquals(i+2, len(recurred_invoices)) @@ -395,7 +401,7 @@ class TestSalesInvoice(unittest.TestCase): for i in xrange(count): base_si = _test(i) -test_dependencies = ["Journal Voucher", "POS Setting"] +test_dependencies = ["Journal Voucher", "POS Setting", "Contact", "Address"] test_records = [ [ diff --git a/accounts/page/accounts_home/accounts_home.js b/accounts/page/accounts_home/accounts_home.js index d2b0a0ea0de..c3d4cf18ce2 100644 --- a/accounts/page/accounts_home/accounts_home.js +++ b/accounts/page/accounts_home/accounts_home.js @@ -217,6 +217,11 @@ wn.module_page["Accounts"] = [ route: "query-report/Payment Made With Ageing", doctype: "Journal Voucher" }, + { + "label":wn._("Sales Partners Commission"), + route: "query-report/Sales Partners Commission", + doctype: "Sales Invoice" + }, ] } ] diff --git a/accounts/report/purchase_register/purchase_register.py b/accounts/report/purchase_register/purchase_register.py index c131c17b4b0..d4f23927d56 100644 --- a/accounts/report/purchase_register/purchase_register.py +++ b/accounts/report/purchase_register/purchase_register.py @@ -20,9 +20,10 @@ from webnotes.utils import flt def execute(filters=None): if not filters: filters = {} - columns, expense_accounts, tax_accounts = get_columns() - + invoice_list = get_invoices(filters) + columns, expense_accounts, tax_accounts = get_columns(invoice_list) + invoice_expense_map = get_invoice_expense_map(invoice_list) invoice_tax_map = get_invoice_tax_map(invoice_list) invoice_po_pr_map = get_invoice_po_pr_map(invoice_list) @@ -55,7 +56,7 @@ def execute(filters=None): return columns, data -def get_columns(): +def get_columns(invoice_list): """return columns based on filters""" columns = [ "Invoice:Link/Purchase Invoice:120", "Posting Date:Date:80", "Supplier:Link/Supplier:120", @@ -66,10 +67,14 @@ def get_columns(): expense_accounts = webnotes.conn.sql_list("""select distinct expense_head from `tabPurchase Invoice Item` where docstatus = 1 and ifnull(expense_head, '') != '' - order by expense_head""") + and parent in (%s) order by expense_head""" % + ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list])) + tax_accounts = webnotes.conn.sql_list("""select distinct account_head from `tabPurchase Taxes and Charges` where parenttype = 'Purchase Invoice' - and docstatus = 1 and ifnull(account_head, '') != '' order by account_head""") + and docstatus = 1 and ifnull(account_head, '') != '' and parent in (%s) + order by account_head""" % + ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list])) columns = columns + [(account + ":Currency:120") for account in expense_accounts] + \ ["Net Total:Currency:120"] + [(account + ":Currency:120") for account in tax_accounts] + \ diff --git a/accounts/report/sales_partners_commission/__init__.py b/accounts/report/sales_partners_commission/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/accounts/report/sales_partners_commission/sales_partners_commission.txt b/accounts/report/sales_partners_commission/sales_partners_commission.txt new file mode 100644 index 00000000000..52bbf3c7512 --- /dev/null +++ b/accounts/report/sales_partners_commission/sales_partners_commission.txt @@ -0,0 +1,22 @@ +[ + { + "creation": "2013-05-06 12:28:23", + "docstatus": 0, + "modified": "2013-05-06 12:41:15", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "query": "SELECT\n sales_partner as \"Sales Partner:Link/Sales Partner:150\",\n\tsum(net_total) as \"Invoiced Amount (Exculsive Tax):Currency:210\",\n\tsum(total_commission) as \"Total Commission:Currency:150\",\n\tsum(total_commission)*100/sum(net_total) as \"Average Commission Rate:Currency:170\"\nFROM\n\t`tabSales Invoice`\nWHERE\n\tdocstatus = 1 and ifnull(net_total, 0) > 0 and ifnull(total_commission, 0) > 0\nGROUP BY\n\tsales_partner\nORDER BY\n\t\"Total Commission:Currency:120\"", + "ref_doctype": "Sales Invoice", + "report_name": "Sales Partners Commission", + "report_type": "Query Report" + }, + { + "doctype": "Report", + "name": "Sales Partners Commission" + } +] \ No newline at end of file diff --git a/accounts/report/sales_register/sales_register.py b/accounts/report/sales_register/sales_register.py index 23d2227fc20..b15097457d6 100644 --- a/accounts/report/sales_register/sales_register.py +++ b/accounts/report/sales_register/sales_register.py @@ -20,9 +20,10 @@ from webnotes.utils import flt def execute(filters=None): if not filters: filters = {} - columns, income_accounts, tax_accounts = get_columns() invoice_list = get_invoices(filters) + columns, income_accounts, tax_accounts = get_columns(invoice_list) + invoice_income_map = get_invoice_income_map(invoice_list) invoice_tax_map = get_invoice_tax_map(invoice_list) @@ -59,7 +60,7 @@ def execute(filters=None): return columns, data -def get_columns(): +def get_columns(invoice_list): """return columns based on filters""" columns = [ "Invoice:Link/Sales Invoice:120", "Posting Date:Date:80", "Customer:Link/Customer:120", @@ -69,11 +70,14 @@ def get_columns(): ] income_accounts = webnotes.conn.sql_list("""select distinct income_account - from `tabSales Invoice Item` where docstatus = 1 order by income_account""") + from `tabSales Invoice Item` where docstatus = 1 and parent in (%s) + order by income_account""" % + ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list])) tax_accounts = webnotes.conn.sql_list("""select distinct account_head from `tabSales Taxes and Charges` where parenttype = 'Sales Invoice' - and docstatus = 1 order by account_head""") + and docstatus = 1 and parent in (%s) order by account_head""" % + ', '.join(['%s']*len(invoice_list)), tuple([inv.name for inv in invoice_list])) columns = columns + [(account + ":Currency:120") for account in income_accounts] + \ ["Net Total:Currency:120"] + [(account + ":Currency:120") for account in tax_accounts] + \ diff --git a/buying/page/buying_home/buying_home.js b/buying/page/buying_home/buying_home.js index 2df5f6fb07e..e7532dda2ea 100644 --- a/buying/page/buying_home/buying_home.js +++ b/buying/page/buying_home/buying_home.js @@ -98,6 +98,21 @@ wn.module_page["Buying"] = [ }, ] }, + { + title: wn._("Reports"), + right: true, + icon: "icon-list", + items: [ + { + "label":wn._("Item-wise Purchase History"), + route: "query-report/Item-wise Purchase History", + }, + { + "label":wn._("Purchase In Transit"), + route: "query-report/Purchase In Transit", + }, + ] + } ] pscript['onload_buying-home'] = function(wrapper) { diff --git a/buying/report/__init__.py b/buying/report/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/buying/report/item_wise_purchase_history/__init__.py b/buying/report/item_wise_purchase_history/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/buying/report/item_wise_purchase_history/item_wise_purchase_history.txt b/buying/report/item_wise_purchase_history/item_wise_purchase_history.txt new file mode 100644 index 00000000000..5d36d9445b3 --- /dev/null +++ b/buying/report/item_wise_purchase_history/item_wise_purchase_history.txt @@ -0,0 +1,23 @@ +[ + { + "creation": "2013-05-03 14:55:53", + "docstatus": 0, + "modified": "2013-05-07 11:20:09", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "add_total_row": 1, + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "query": "select\n po_item.item_code as \"Item Code:Link/Item:120\",\n\tpo_item.item_name as \"Item Name::120\",\n\tpo_item.description as \"Description::150\",\n\tpo_item.qty as \"Qty:Float:100\",\n\tpo_item.stock_uom as \"UOM:Link/UOM:80\",\n\tpo_item.purchase_rate as \"Rate:Currency:120\",\n\tpo_item.amount as \"Amount:Currency:120\",\n\tpo.name as \"Purchase Order:Link/Purchase Order:120\",\n\tpo.transaction_date as \"Transaction Date:Date:140\",\n\tpo.supplier as \"Supplier:Link/Supplier:130\",\n\tpo_item.project_name as \"Project:Link/Project:130\",\n\tifnull(po_item.received_qty, 0) as \"Received Qty:Float:120\",\n\tifnull(po_item.billed_qty, 0) as \"Billed Qty:Float:120\"\nfrom\n\t`tabPurchase Order` po, `tabPurchase Order Item` po_item\nwhere\n\tpo.name = po_item.parent and po.docstatus = 1\norder by po.name desc", + "ref_doctype": "Purchase Order", + "report_name": "Item-wise Purchase History", + "report_type": "Query Report" + }, + { + "doctype": "Report", + "name": "Item-wise Purchase History" + } +] \ No newline at end of file diff --git a/controllers/buying_controller.py b/controllers/buying_controller.py index 0c25b9855ea..9e181bc8fe4 100644 --- a/controllers/buying_controller.py +++ b/controllers/buying_controller.py @@ -50,8 +50,7 @@ class BuyingController(StockController): for warehouse, company in webnotes.conn.get_values("Warehouse", self.doclist.get_distinct_values("warehouse"), "company").items(): if company and company != self.doc.company: - webnotes.msgprint(_("Warehouse must belong to company") + \ - (": %s (%s, %s)" % (warehouse, company, self.doc.company)), + webnotes.msgprint(_("Company mismatch for Warehouse") + (": %s" % (warehouse,)), raise_exception=WrongWarehouseCompany) def validate_stock_or_nonstock_items(self): diff --git a/controllers/selling_controller.py b/controllers/selling_controller.py index b22042d0fe9..80af3370315 100644 --- a/controllers/selling_controller.py +++ b/controllers/selling_controller.py @@ -59,7 +59,8 @@ class SellingController(StockController): buying_amount = get_buying_amount(item.item_code, item.warehouse, -1*item.qty, self.doc.doctype, self.doc.name, item.name, stock_ledger_entries, item_sales_bom) - item.buying_amount = buying_amount > 0 and buying_amount or 0 + + item.buying_amount = buying_amount >= 0.01 and buying_amount or 0 webnotes.conn.set_value(item.doctype, item.name, "buying_amount", item.buying_amount) diff --git a/home/page/latest_updates/latest_updates.js b/home/page/latest_updates/latest_updates.js index f254bf2349e..38c00269654 100644 --- a/home/page/latest_updates/latest_updates.js +++ b/home/page/latest_updates/latest_updates.js @@ -2,7 +2,9 @@ erpnext.updates = [ ["2nd May", ["Buying: Warehouse must belong to same company as transaction", "Price List: Added Currency Field. One price list can have only one currency", "Item: Naming can now be by series or item code", - "Naming Series: Set number of digits in series (optionally)"]], + "Naming Series: Set number of digits in series (optionally)", + "Login: Disable Signup link in the login page"]], + ["30th April", ["Price List: Valid for all countries or only valid for specific countries"]], ["18th April", ["Cost Center: Set a default Cost Center for a Company"]], ["12th April", ["Employee: List of Leave Approvers who can approve the Employee's Leave Applications"]], ["10th April", ["Redesigned File Uploads and added File Manager in Setup"]], diff --git a/hr/doctype/salary_slip/salary_slip.py b/hr/doctype/salary_slip/salary_slip.py index 3edf4109547..d1ce3ccf1db 100644 --- a/hr/doctype/salary_slip/salary_slip.py +++ b/hr/doctype/salary_slip/salary_slip.py @@ -152,7 +152,7 @@ class DocType(TransactionBase): d.e_modified_amount = round(flt(d.e_amount)*flt(self.doc.payment_days)/cint(self.doc.total_days_in_month), 2) elif not self.doc.payment_days: d.e_modified_amount = 0 - self.doc.gross_pay += d.e_modified_amount + self.doc.gross_pay += flt(d.e_modified_amount) def calculate_ded_total(self): """ @@ -165,7 +165,7 @@ class DocType(TransactionBase): elif not self.doc.payment_days: d.d_modified_amount = 0 - self.doc.total_deduction += d.d_modified_amount + self.doc.total_deduction += flt(d.d_modified_amount) def calculate_net_pay(self): """ diff --git a/hr/page/hr_home/hr_home.js b/hr/page/hr_home/hr_home.js index df3264501a9..b2cce73f15e 100644 --- a/hr/page/hr_home/hr_home.js +++ b/hr/page/hr_home/hr_home.js @@ -169,6 +169,14 @@ wn.module_page["HR"] = [ "label":wn._("Employee Leave Balance"), route: "query-report/Employee Leave Balance" }, + { + "label":wn._("Employee Birthday"), + route: "query-report/Employee Birthday" + }, + { + "label":wn._("Employee Information"), + route: "Report2/Employee/Employee Information" + }, ] } ]; diff --git a/hr/report/employee_birthday/__init__.py b/hr/report/employee_birthday/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/hr/report/employee_birthday/employee_birthday.js b/hr/report/employee_birthday/employee_birthday.js new file mode 100644 index 00000000000..f2bc9cbe564 --- /dev/null +++ b/hr/report/employee_birthday/employee_birthday.js @@ -0,0 +1,19 @@ +wn.query_reports["Employee Birthday"] = { + "filters": [ + { + "fieldname":"month", + "label": "Month", + "fieldtype": "Select", + "options": "Jan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug\nSep\nOct\nNov\nDec", + "default": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", + "Dec"][wn.datetime.str_to_obj(wn.datetime.get_today()).getMonth()], + }, + { + "fieldname":"company", + "label": "Company", + "fieldtype": "Link", + "options": "Company", + "default": wn.defaults.get_user_default("company") + } + ] +} \ No newline at end of file diff --git a/hr/report/employee_birthday/employee_birthday.py b/hr/report/employee_birthday/employee_birthday.py new file mode 100644 index 00000000000..7268055b728 --- /dev/null +++ b/hr/report/employee_birthday/employee_birthday.py @@ -0,0 +1,50 @@ +# 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() + data = get_employees(filters) + + return columns, data + +def get_columns(): + return [ + "Employee:Link/Employee:120", "Date of Birth:Date:100", "Branch:Link/Branch:120", + "Department:Link/Department:120", "Designation:Link/Designation:120", "Gender::60", + "Company:Link/Company:120" + ] + +def get_employees(filters): + conditions = get_conditions(filters) + return webnotes.conn.sql("""select name, date_of_birth, branch, department, designation, + gender, company from tabEmployee where status = 'Active' %s""" % conditions, as_list=1) + +def get_conditions(filters): + conditions = "" + if filters.get("month"): + month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", + "Dec"].index(filters["month"]) + 1 + conditions += " and month(date_of_birth) = '%s'" % month + + if filters.get("company"): conditions += " and company = '%s'" % filters["company"] + + return conditions \ No newline at end of file diff --git a/hr/report/employee_birthday/employee_birthday.txt b/hr/report/employee_birthday/employee_birthday.txt new file mode 100644 index 00000000000..575ae733527 --- /dev/null +++ b/hr/report/employee_birthday/employee_birthday.txt @@ -0,0 +1,21 @@ +[ + { + "creation": "2013-05-06 17:56:03", + "docstatus": 0, + "modified": "2013-05-06 17:56:03", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Employee", + "report_name": "Employee Birthday", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Employee Birthday" + } +] \ No newline at end of file diff --git a/hr/report/employee_information/__init__.py b/hr/report/employee_information/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/hr/report/employee_information/employee_information.txt b/hr/report/employee_information/employee_information.txt new file mode 100644 index 00000000000..b9d190b0292 --- /dev/null +++ b/hr/report/employee_information/employee_information.txt @@ -0,0 +1,22 @@ +[ + { + "creation": "2013-05-06 18:43:53", + "docstatus": 0, + "modified": "2013-05-06 18:47:43", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "json": "{\"filters\":[],\"columns\":[[\"name\",\"Employee\"],[\"employee_number\",\"Employee\"],[\"date_of_joining\",\"Employee\"],[\"branch\",\"Employee\"],[\"department\",\"Employee\"],[\"designation\",\"Employee\"],[\"gender\",\"Employee\"],[\"status\",\"Employee\"],[\"company\",\"Employee\"],[\"employment_type\",\"Employee\"],[\"grade\",\"Employee\"],[\"reports_to\",\"Employee\"],[\"company_email\",\"Employee\"]],\"sort_by\":\"Employee.bank_ac_no\",\"sort_order\":\"desc\",\"sort_by_next\":\"\",\"sort_order_next\":\"desc\"}", + "name": "__common__", + "ref_doctype": "Employee", + "report_name": "Employee Information", + "report_type": "Report Builder" + }, + { + "doctype": "Report", + "name": "Employee Information" + } +] \ No newline at end of file diff --git a/manufacturing/doctype/bom/bom.js b/manufacturing/doctype/bom/bom.js index f0c15fa2a9d..b1f43f76207 100644 --- a/manufacturing/doctype/bom/bom.js +++ b/manufacturing/doctype/bom/bom.js @@ -64,9 +64,9 @@ cur_frm.add_fetch("item", "stock_uom", "uom"); cur_frm.cscript.workstation = function(doc,dt,dn) { var d = locals[dt][dn]; - wn.model.with_doc("Workstation", d.workstation, function(i, v) { - d.hour_rate = v.hour_rate; - refresh_field("hour_rate"); + wn.model.with_doc("Workstation", d.workstation, function(i, r) { + d.hour_rate = r.docs[0].hour_rate; + refresh_field("hour_rate", dn, "bom_operations"); calculate_op_cost(doc); calculate_total(doc); }); diff --git a/manufacturing/doctype/bom_replace_tool/bom_replace_tool.py b/manufacturing/doctype/bom_replace_tool/bom_replace_tool.py index 177adcda83b..4c9c42da2e9 100644 --- a/manufacturing/doctype/bom_replace_tool/bom_replace_tool.py +++ b/manufacturing/doctype/bom_replace_tool/bom_replace_tool.py @@ -46,11 +46,7 @@ class DocType: webnotes.conn.sql("""update `tabBOM Item` set bom_no=%s, rate=%s, amount=qty*%s where bom_no = %s and docstatus < 2""", (self.doc.new_bom, current_bom_unitcost, current_bom_unitcost, self.doc.current_bom)) - - def get_parent_boms(bom_no): - return [d[0] for d in webnotes.conn.sql("""select distinct parent from - `tabBOM Item` where ifnull(bom_no, '')=%s and docstatus < 2""", bom_no)] - + def get_parent_boms(self): return [d[0] for d in webnotes.conn.sql("""select distinct parent from `tabBOM Item` where ifnull(bom_no, '') = %s and docstatus < 2""", diff --git a/manufacturing/page/manufacturing_home/manufacturing_home.js b/manufacturing/page/manufacturing_home/manufacturing_home.js index b7f28edc411..d4841df2fba 100644 --- a/manufacturing/page/manufacturing_home/manufacturing_home.js +++ b/manufacturing/page/manufacturing_home/manufacturing_home.js @@ -58,6 +58,17 @@ wn.module_page["Manufacturing"] = [ }, ] }, + { + title: wn._("Reports"), + right: true, + icon: "icon-list", + items: [ + { + "label":wn._("Issued Items Against Production Order"), + route: "query-report/Issued Items Against Production Order", + }, + ] + } ] pscript['onload_manufacturing-home'] = function(wrapper) { diff --git a/manufacturing/report/__init__.py b/manufacturing/report/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/manufacturing/report/issued_items_against_production_order/__init__.py b/manufacturing/report/issued_items_against_production_order/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/manufacturing/report/issued_items_against_production_order/issued_items_against_production_order.txt b/manufacturing/report/issued_items_against_production_order/issued_items_against_production_order.txt new file mode 100644 index 00000000000..a5a03bfa00d --- /dev/null +++ b/manufacturing/report/issued_items_against_production_order/issued_items_against_production_order.txt @@ -0,0 +1,23 @@ +[ + { + "creation": "2013-05-03 17:48:46", + "docstatus": 0, + "modified": "2013-05-07 11:49:56", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "add_total_row": 0, + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "query": "select\n ste.production_order as \"Production Order:Link/Production Order:120\",\n ste.posting_date as \"Issue Date:Date:140\",\n ste_item.item_code as \"Item Code:Link/Item:120\",\n\tste_item.description as \"Description::150\",\n\tste_item.transfer_qty as \"Qty:Float:100\",\n\tste_item.stock_uom as \"UOM:Link/UOM:80\",\n\tste_item.amount as \"Amount:Currency:120\",\n\tste_item.serial_no as \"Serial No:Link/Serial No:80\",\n\tste_item.s_warehouse as \"Source Warehouse:Link/Warehouse:120\",\n\tste_item.t_warehouse as \"Target Warehouse:Link/Warehouse:120\",\n\tpro.production_item as \"Finished Goods:Link/Item:120\", \n\tste.name as \"Stock Entry:Link/Stock Entry:120\"\nfrom\n\t`tabStock Entry` ste, `tabStock Entry Detail` ste_item, `tabProduction Order` pro\nwhere\n\tifnull(ste.production_order, '') != '' and ste.name = ste_item.parent \n\tand ste.production_order = pro.name and ste.docstatus = 1 \n\tand ste.purpose = 'Manufacture/Repack'\norder by ste.posting_date, ste.production_order, ste_item.item_code", + "ref_doctype": "Production Order", + "report_name": "Issued Items Against Production Order", + "report_type": "Query Report" + }, + { + "doctype": "Report", + "name": "Issued Items Against Production Order" + } +] \ No newline at end of file diff --git a/patches/april_2013/p08_price_list_country.py b/patches/april_2013/p08_price_list_country.py new file mode 100644 index 00000000000..65643cc2399 --- /dev/null +++ b/patches/april_2013/p08_price_list_country.py @@ -0,0 +1,5 @@ +import webnotes + +def execute(): + webnotes.reload_doc("Setup", "DocType", "Price List") + webnotes.conn.sql("""update `tabPrice List` set valid_for_all_countries=1""") \ No newline at end of file diff --git a/patches/patch_list.py b/patches/patch_list.py index c9a0ab5aedb..ed1c8462cd8 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -154,12 +154,12 @@ patch_list = [ "patches.january_2013.remove_tds_entry_from_gl_mapper", "patches.january_2013.update_number_format", "patches.january_2013.purchase_price_list", + "execute:webnotes.reload_doc('core', 'doctype', 'print_format') #2013-01", "execute:webnotes.reload_doc('accounts','Print Format','Payment Receipt Voucher')", "patches.january_2013.update_fraction_for_usd", "patches.january_2013.enable_currencies", "patches.january_2013.remove_unwanted_permission", "patches.january_2013.remove_landed_cost_master", - "execute:webnotes.reload_doc('core', 'doctype', 'print_format')", "patches.january_2013.reload_print_format", "patches.january_2013.rebuild_tree", "execute:webnotes.reload_doc('core','doctype','docfield') #2013-01-28", @@ -249,4 +249,5 @@ patch_list = [ "execute:webnotes.reset_perms('File Data')", "patches.april_2013.p07_update_file_data_2", "patches.april_2013.rebuild_sales_browser", + "patches.april_2013.p08_price_list_country", ] \ No newline at end of file diff --git a/selling/doctype/sales_common/sales_common.py b/selling/doctype/sales_common/sales_common.py index 7b1528bafe2..78f842291df 100644 --- a/selling/doctype/sales_common/sales_common.py +++ b/selling/doctype/sales_common/sales_common.py @@ -374,7 +374,7 @@ class DocType(TransactionBase): msgprint("Please Enter Appropriate Conversion Rate for Customer's Currency to Base Currency (%s --> %s)" % (obj.doc.currency, default_currency), raise_exception = 1) if (obj.doc.price_list_currency == default_currency and flt(obj.doc.plc_conversion_rate) != 1.00) or not obj.doc.plc_conversion_rate or (obj.doc.price_list_currency != default_currency and flt(obj.doc.plc_conversion_rate) == 1.00): - msgprint("Please Enter Appropriate Conversion Rate for Price List Currency to Base Currency ( (%s --> %s)" % (obj.doc.price_list_currency, default_currency), raise_exception = 1) + msgprint("Please Enter Appropriate Conversion Rate for Price List Currency to Base Currency (%s --> %s)" % (obj.doc.price_list_currency, default_currency), raise_exception = 1) diff --git a/selling/page/selling_home/selling_home.js b/selling/page/selling_home/selling_home.js index 994bb4a5550..682978bd17c 100644 --- a/selling/page/selling_home/selling_home.js +++ b/selling/page/selling_home/selling_home.js @@ -157,6 +157,14 @@ wn.module_page["Selling"] = [ "label":wn._("Sales Orders Pending to be Delivered"), route: "query-report/Sales Orders Pending To Be Delivered" }, + { + "label":wn._("Sales Person-wise Transaction Summary"), + route: "query-report/Sales Person-wise Transaction Summary", + }, + { + "label":wn._("Item-wise Sales History"), + route: "query-report/Item-wise Sales History", + }, ] } ] diff --git a/selling/report/item_wise_sales_history/__init__.py b/selling/report/item_wise_sales_history/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/selling/report/item_wise_sales_history/item_wise_sales_history.txt b/selling/report/item_wise_sales_history/item_wise_sales_history.txt new file mode 100644 index 00000000000..6fee050e0db --- /dev/null +++ b/selling/report/item_wise_sales_history/item_wise_sales_history.txt @@ -0,0 +1,23 @@ +[ + { + "creation": "2013-05-03 14:38:34", + "docstatus": 0, + "modified": "2013-05-07 11:19:40", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "add_total_row": 1, + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "query": "select\n so_item.item_code as \"Item Code:Link/Item:120\",\n\tso_item.item_name as \"Item Name::120\",\n\tso_item.description as \"Description::150\",\n\tso_item.qty as \"Qty:Float:100\",\n\tso_item.stock_uom as \"UOM:Link/UOM:80\",\n\tso_item.basic_rate as \"Rate:Currency:120\",\n\tso_item.amount as \"Amount:Currency:120\",\n\tso.name as \"Sales Order:Link/Sales Order:120\",\n\tso.transaction_date as \"Transaction Date:Date:140\",\n\tso.customer as \"Customer:Link/Customer:130\",\n\tso.territory as \"Territory:Link/Territory:130\",\n so.project_name as \"Project:Link/Project:130\",\n\tifnull(so_item.delivered_qty, 0) as \"Delivered Qty:Float:120\",\n\tifnull(so_item.billed_amt, 0) as \"Billed Amount:Currency:120\"\nfrom\n\t`tabSales Order` so, `tabSales Order Item` so_item\nwhere\n\tso.name = so_item.parent\n\tand so.docstatus = 1\norder by so.name desc", + "ref_doctype": "Sales Order", + "report_name": "Item-wise Sales History", + "report_type": "Query Report" + }, + { + "doctype": "Report", + "name": "Item-wise Sales History" + } +] \ No newline at end of file diff --git a/selling/report/sales_person_wise_transaction_summary/__init__.py b/selling/report/sales_person_wise_transaction_summary/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.js b/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.js new file mode 100644 index 00000000000..4a8e6787ff7 --- /dev/null +++ b/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.js @@ -0,0 +1,54 @@ +wn.query_reports["Sales Person-wise Transaction Summary"] = { + "filters": [ + { + fieldname: "sales_person", + label: "Sales Person", + fieldtype: "Link", + options: "Sales Person" + }, + { + fieldname: "doc_type", + label: "Document Type", + fieldtype: "Select", + options: "Sales Order\nDelivery Note\nSales Invoice", + default: "Sales Order" + }, + { + fieldname: "from_date", + label: "From Date", + fieldtype: "Date", + default: wn.defaults.get_user_default("year_start_date"), + }, + { + fieldname:"to_date", + label: "To Date", + fieldtype: "Date", + default: get_today() + }, + { + fieldname:"company", + label: "Company", + fieldtype: "Link", + options: "Company", + default: sys_defaults.company + }, + { + fieldname:"item_group", + label: "Item Group", + fieldtype: "Link", + options: "Item Group", + }, + { + fieldname:"brand", + label: "Brand", + fieldtype: "Link", + options: "Brand", + }, + { + fieldname:"customer", + label: "Customer", + fieldtype: "Link", + options: "Customer", + }, + ] +} \ No newline at end of file diff --git a/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py b/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py new file mode 100644 index 00000000000..23e8819242b --- /dev/null +++ b/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.py @@ -0,0 +1,81 @@ +# 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 import msgprint, _ + +def execute(filters=None): + if not filters: filters = {} + + columns = get_columns(filters) + data = get_entries(filters) + + return columns, data + +def get_columns(filters): + if not filters.get("doc_type"): + msgprint(_("Please select the document type first"), raise_exception=1) + + return [filters["doc_type"] + ":Link/" + filters["doc_type"] + ":140", + "Customer:Link/Customer:140", "Territory:Link/Territory:100", "Posting Date:Date:100", + "Item Code:Link/Item:120", "Qty:Float:100", "Amount:Currency:120", + "Sales Person:Link/Sales Person:140", "Contribution %:Float:110", + "Contribution Amount:Currency:140"] + +def get_entries(filters): + date_field = filters["doc_type"] == "Sales Order" and "transaction_date" or "posting_date" + conditions, items = get_conditions(filters, date_field) + entries = webnotes.conn.sql("""select dt.name, dt.customer, dt.territory, dt.%s, + dt_item.item_code, dt_item.qty, dt_item.amount, st.sales_person, + st.allocated_percentage, dt_item.amount*st.allocated_percentage/100 + from `tab%s` dt, `tab%s Item` dt_item, `tabSales Team` st + where st.parent = dt.name and dt.name = dt_item.parent and st.parenttype = '%s' + and dt.docstatus = 1 %s order by st.sales_person, dt.name desc""" % + (date_field, filters["doc_type"], filters["doc_type"], filters["doc_type"], conditions), + tuple(items), as_list=1) + + return entries + +def get_conditions(filters, date_field): + conditions = "" + if filters.get("company"): conditions += " and dt.company = '%s'" % filters["company"] + if filters.get("customer"): conditions += " and dt.customer = '%s'" % filters["customer"] + + if filters.get("from_date"): conditions += " and dt.%s >= '%s'" % \ + (date_field, filters["from_date"]) + if filters.get("to_date"): conditions += " and dt.%s <= '%s'" % (date_field, filters["to_date"]) + + if filters.get("sales_person"): conditions += " and st.sales_person = '%s'" % \ + filters["sales_person"] + + items = get_items(filters) + if items: + conditions += " and dt_item.item_code in (%s)" % ', '.join(['%s']*len(items)) + + return conditions, items + +def get_items(filters): + if filters.get("item_group"): key = "item_group" + elif filters.get("brand"): key = "brand" + else: key = "" + + items = [] + if key: + items = webnotes.conn.sql_list("""select name from tabItem where %s = %s""" % + (key, '%s'), (filters[key])) + + return items \ No newline at end of file diff --git a/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.txt b/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.txt new file mode 100644 index 00000000000..abd69f3f2fb --- /dev/null +++ b/selling/report/sales_person_wise_transaction_summary/sales_person_wise_transaction_summary.txt @@ -0,0 +1,22 @@ +[ + { + "creation": "2013-05-03 11:31:05", + "docstatus": 0, + "modified": "2013-05-03 11:31:05", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "add_total_row": 1, + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "ref_doctype": "Sales Order", + "report_name": "Sales Person-wise Transaction Summary", + "report_type": "Script Report" + }, + { + "doctype": "Report", + "name": "Sales Person-wise Transaction Summary" + } +] \ No newline at end of file diff --git a/setup/doctype/global_defaults/global_defaults.py b/setup/doctype/global_defaults/global_defaults.py index 191a47edf29..dc7f6b4b735 100644 --- a/setup/doctype/global_defaults/global_defaults.py +++ b/setup/doctype/global_defaults/global_defaults.py @@ -21,6 +21,7 @@ import webnotes.defaults from webnotes.utils import cint keydict = { + # "key in defaults": "key in Global Defaults" "print_style": "print_style", "fiscal_year": "current_fiscal_year", 'company': 'default_company', diff --git a/setup/doctype/price_list/price_list.js b/setup/doctype/price_list/price_list.js index 75d3d0f1c13..b68627f73f7 100644 --- a/setup/doctype/price_list/price_list.js +++ b/setup/doctype/price_list/price_list.js @@ -14,10 +14,46 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +cur_frm.cscript.onload = function() { + cur_frm.cscript.show_item_prices(); +} + cur_frm.cscript.refresh = function(doc, cdt, cdn) { cur_frm.set_intro(""); if(doc.__islocal) { cur_frm.set_intro("Save this list to begin."); return; + } else { + cur_frm.cscript.show_item_prices(); } } + +cur_frm.cscript.show_item_prices = function() { + var item_price = wn.model.get("Item Price", {price_list_name: cur_frm.doc.name}); + + var show = item_price && item_price.length; + + cur_frm.toggle_display("item_prices_section", show); + $(cur_frm.fields_dict.item_prices.wrapper).empty(); + if (!show) return; + + var out = '\ + \ + \ + \ + \ + \ + \ + ' + + $.map(item_price.sort(function(a, b) { return a.parent.localeCompare(b.parent); }), function(d) { + return '' + + '' + + '' + + '' + + '' + + '' + }).join("\n") + + '\ +
' + wn._("Item Code") + '' + wn._("Price") + '' + wn._("Valid For Selling") + '' + wn._("Valid For Buying") + '
' + d.parent + '' + format_currency(d.ref_rate, d.ref_currency) + '' + (cint(d.selling) ? '' : "") + '' + (cint(d.buying) ? '' : "") + '
'; + $(out).appendTo($(cur_frm.fields_dict.item_prices.wrapper)); +} diff --git a/setup/doctype/price_list/price_list.py b/setup/doctype/price_list/price_list.py index a88309b6db7..ae49bf868dd 100644 --- a/setup/doctype/price_list/price_list.py +++ b/setup/doctype/price_list/price_list.py @@ -16,73 +16,20 @@ from __future__ import unicode_literals import webnotes - -from webnotes.model.doc import Document -from webnotes import msgprint +from webnotes import msgprint, _ +from webnotes.utils import cint class DocType: def __init__(self, d, dl): self.doc, self.doclist = d, dl - self.cl = [] - - # validate currency - def is_currency_valid(self, currency): - if currency in self.cl: - return 1 - - if webnotes.conn.sql("select name from tabCurrency where name=%s", currency): - self.cl.append(currency) - return 1 - else: - return 0 - - def download_template(self, arg=None): - """download 3 column template with all Items""" - default_currency = webnotes.conn.get_default('currency') - item_list = webnotes.conn.sql("""select name from tabItem where - (ifnull(is_sales_item,'')='Yes' or ifnull(is_service_item,'')='Yes')""") - data = [self.get_price(i[0], default_currency) for i in item_list] - return [['Item', 'Rate', 'Currency']] + data - - def get_price(self, item, default_currency): - rate = webnotes.conn.sql("""select ref_rate, ref_currency from `tabItem Price` - where parent=%s and price_list_name=%s""", (item, self.doc.name)) - return [item, rate and rate[0][0] or 0, rate and rate[0][1] or default_currency] - - # update prices in Price List - def update_prices(self): - from webnotes.utils.datautils import read_csv_content_from_attached_file - data = read_csv_content_from_attached_file(self.doc) - webnotes.conn.auto_commit_on_many_writes = 1 - - updated = 0 - - for line in data: - if line and len(line)==3 and line[0]!='Item': - # if item exists - if webnotes.conn.sql("select name from tabItem where name=%s", line[0]): - if self.is_currency_valid(line[2]): - # if price exists - ref_ret_detail = webnotes.conn.sql("select name from `tabItem Price` where parent=%s and price_list_name=%s and ref_currency=%s", \ - (line[0], self.doc.name, line[2])) - if ref_ret_detail: - webnotes.conn.sql("update `tabItem Price` set ref_rate=%s where name=%s", (line[1], ref_ret_detail[0][0])) - else: - d = Document('Item Price') - d.parent = line[0] - d.parentfield = 'ref_rate_details' - d.parenttype = 'Item' - d.price_list_name = self.doc.name - d.ref_rate = line[1] - d.ref_currency = line[2] - d.save(1) - updated += 1 - else: - msgprint("[Ignored] Unknown currency '%s' for Item '%s'" % (line[2], line[0])) - else: - msgprint("[Ignored] Did not find Item '%s'" % line[1]) - - msgprint("%s items updated" % updated) - webnotes.conn.auto_commit_on_many_writes = 0 \ No newline at end of file + def onload(self): + self.doclist.extend(webnotes.conn.sql("""select * from `tabItem Price` + where price_list_name=%s""", self.doc.name, as_dict=True, update={"doctype": "Item Price"})) + + def validate(self): + if not (cint(self.doc.valid_for_all_countries) or len(self.doclist.get({"parentfield": "valid_for_countries"}))): + msgprint(_("""Please check "Valid For All Countries" or \ + enter atlease one row in the "Countries" table."""), raise_exception=True) + diff --git a/setup/doctype/price_list/price_list.txt b/setup/doctype/price_list/price_list.txt index bce8aae6e79..781eae5f68f 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-05-02 14:44:24", + "modified": "2013-05-02 14:45:00", "modified_by": "Administrator", "owner": "Administrator" }, @@ -61,7 +61,41 @@ "reqd": 1 }, { - "depends_on": "price_list_name", + "default": "1", + "doctype": "DocField", + "fieldname": "valid_for_all_countries", + "fieldtype": "Check", + "label": "Valid for all countries" + }, + { + "description": "A list of Countries, for which, this Price List is valid", + "doctype": "DocField", + "fieldname": "valid_for_countries", + "fieldtype": "Table", + "label": "Valid for the following countries", + "options": "Price List Country" + }, + { + "doctype": "DocField", + "fieldname": "item_prices_section", + "fieldtype": "Section Break", + "label": "Item Prices" + }, + { + "doctype": "DocField", + "fieldname": "item_prices", + "fieldtype": "HTML", + "label": "Item Prices" + }, + { + "depends_on": "eval:!doc.__islocal", + "doctype": "DocField", + "fieldname": "section_break_1", + "fieldtype": "Section Break", + "label": "How to upload" + }, + { + "depends_on": "eval:!doc.__islocal", "doctype": "DocField", "fieldname": "how_to_upload", "fieldtype": "HTML", diff --git a/setup/doctype/price_list/test_price_list.py b/setup/doctype/price_list/test_price_list.py index 30262dc8aaa..fe87821904d 100644 --- a/setup/doctype/price_list/test_price_list.py +++ b/setup/doctype/price_list/test_price_list.py @@ -2,6 +2,7 @@ test_records = [ [{ "doctype": "Price List", "price_list_name": "_Test Price List", - "currency": "INR" + "currency": "INR", + "valid_for_all_countries": 1 }] ] \ No newline at end of file diff --git a/setup/doctype/price_list_country/__init__.py b/setup/doctype/price_list_country/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/setup/doctype/price_list_country/price_list_country.py b/setup/doctype/price_list_country/price_list_country.py new file mode 100644 index 00000000000..928aa9ff9f2 --- /dev/null +++ b/setup/doctype/price_list_country/price_list_country.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/setup/doctype/price_list_country/price_list_country.txt b/setup/doctype/price_list_country/price_list_country.txt new file mode 100644 index 00000000000..640b0a80527 --- /dev/null +++ b/setup/doctype/price_list_country/price_list_country.txt @@ -0,0 +1,36 @@ +[ + { + "creation": "2013-04-29 18:24:32", + "docstatus": 0, + "modified": "2013-04-29 18:24:32", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "autoname": "PLCNTRY-.#####", + "doctype": "DocType", + "istable": 1, + "module": "Setup", + "name": "__common__" + }, + { + "doctype": "DocField", + "fieldname": "country", + "fieldtype": "Link", + "label": "Country", + "name": "__common__", + "options": "Country", + "parent": "Price List Country", + "parentfield": "fields", + "parenttype": "DocType", + "permlevel": 0, + "reqd": 1 + }, + { + "doctype": "DocType", + "name": "Price List Country" + }, + { + "doctype": "DocField" + } +] \ No newline at end of file diff --git a/startup/website.py b/startup/website.py index 295e5bb0cab..be8eba6def1 100644 --- a/startup/website.py +++ b/startup/website.py @@ -1,4 +1,5 @@ import webnotes, conf, os +from webnotes.utils import cint, cstr def get_templates_path(): return os.path.join(os.path.dirname(conf.__file__), "app", "website", "templates") @@ -61,12 +62,14 @@ def update_template_args(page_name, args): settings = webnotes.doc("Website Settings", "Website Settings") for k in ["banner_html", "brand_html", "copyright", "address", "twitter_share_via", - "favicon", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share"]: + "favicon", "facebook_share", "google_plus_one", "twitter_share", "linked_in_share", + "disable_signup"]: if k in settings.fields: args[k] = settings.fields.get(k) - for k in ["facebook_share", "google_plus_one", "twitter_share", "linked_in_share"]: - args[k] = int(args.get(k) or 0) + for k in ["facebook_share", "google_plus_one", "twitter_share", "linked_in_share", + "disable_signup"]: + args[k] = cint(args.get(k) or 0) args.url = quote(str(get_request_site_address(full_address=True)), str("")) args.encoded_title = quote(str(args.title or ""), str("")) diff --git a/stock/doctype/bin/bin.py b/stock/doctype/bin/bin.py index be343129bff..2d98c2634f7 100644 --- a/stock/doctype/bin/bin.py +++ b/stock/doctype/bin/bin.py @@ -79,7 +79,7 @@ class DocType: if (flt(args.get("actual_qty")) < 0 or flt(args.get("reserved_qty")) > 0) \ and args.get("is_cancelled") == 'No' and args.get("is_amended")=='No': - self.reorder_item(args.get("voucher_type"), args.get("voucher_no")) + self.reorder_item(args.get("voucher_type"), args.get("voucher_no"), args.get("company")) def get_first_sle(self): sle = sql(""" @@ -92,7 +92,7 @@ class DocType: """, (self.doc.item_code, self.doc.warehouse), as_dict=1) return sle and sle[0] or None - def reorder_item(self,doc_type,doc_name): + def reorder_item(self,doc_type,doc_name, company): """ Reorder item if stock reaches reorder level""" if not hasattr(webnotes, "auto_indent"): webnotes.auto_indent = webnotes.conn.get_value('Global Defaults', None, 'auto_indent') @@ -111,10 +111,10 @@ class DocType: material_request_type = "Purchase" if flt(reorder_qty) and flt(self.doc.projected_qty) < flt(reorder_level): - self.create_material_request(doc_type, doc_name, reorder_level, reorder_qty, - material_request_type) + self.create_material_request(doc_type, doc_name, reorder_level, reorder_qty, + company, material_request_type) - def create_material_request(self, doc_type, doc_name, reorder_level, reorder_qty, + def create_material_request(self, doc_type, doc_name, reorder_level, reorder_qty, company, material_request_type="Purchase"): """ Create indent on reaching reorder level """ defaults = webnotes.defaults.get_defaults() @@ -122,7 +122,7 @@ class DocType: mr = webnotes.bean([{ "doctype": "Material Request", - "company": defaults.company, + "company": company or defaults.company, "fiscal_year": defaults.fiscal_year, "transaction_date": nowdate(), "material_request_type": material_request_type, diff --git a/stock/doctype/item/item.js b/stock/doctype/item/item.js index a344ad3ce92..acc78e77dc5 100644 --- a/stock/doctype/item/item.js +++ b/stock/doctype/item/item.js @@ -134,11 +134,7 @@ cur_frm.fields_dict.item_supplier_details.grid.get_field("supplier").get_query = erpnext.utils.supplier_query; cur_frm.cscript.on_remove_attachment = function(doc) { - // refresh image list before unsetting image - refresh_field("image"); if(!inList(cur_frm.fields_dict.image.df.options.split("\n"), doc.image)) { - // if the selected image is removed from attachment, unset it - cur_frm.set_value("image", ""); msgprint(wn._("Attachment removed. You may need to update: ") + wn.meta.get_docfield(doc.doctype, "description_html").label); } @@ -157,3 +153,7 @@ cur_frm.cscript.copy_from_item_group = function(doc) { cur_frm.refresh(); }); } + +cur_frm.cscript.image = function() { + refresh_field("image_view"); +} \ No newline at end of file diff --git a/stock/doctype/item/item.py b/stock/doctype/item/item.py index 63275047ad7..fde532c96cf 100644 --- a/stock/doctype/item/item.py +++ b/stock/doctype/item/item.py @@ -31,7 +31,9 @@ class DocType(DocListController): if webnotes.conn.get_default("item_naming_by")=="Naming Series": from webnotes.model.doc import make_autoname self.doc.item_code = make_autoname(self.doc.naming_series+'.#####') - + elif not self.doc.item_code: + msgprint(_("Item Code is mandatory"), raise_exception=1) + self.doc.name = self.doc.item_code def validate(self): diff --git a/stock/doctype/item/item.txt b/stock/doctype/item/item.txt index d6eaf345ed4..c799029d95a 100644 --- a/stock/doctype/item/item.txt +++ b/stock/doctype/item/item.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-03-28 10:35:28", + "creation": "2013-05-03 10:45:46", "docstatus": 0, - "modified": "2013-05-02 15:10:53", + "modified": "2013-05-07 15:58:58", "modified_by": "Administrator", "owner": "Administrator" }, @@ -28,13 +28,14 @@ "permlevel": 0 }, { - "amend": 0, "doctype": "DocPerm", "name": "__common__", "parent": "Item", "parentfield": "permissions", "parenttype": "DocType", + "permlevel": 0, "read": 1, + "report": 1, "submit": 0 }, { @@ -55,7 +56,8 @@ "fieldname": "naming_series", "fieldtype": "Select", "label": "Naming Series", - "options": "\nITEM" + "options": "\nITEM", + "read_only": 0 }, { "description": "Item will be saved by this name in the data base.", @@ -64,10 +66,11 @@ "fieldtype": "Data", "in_filter": 0, "label": "Item Code", + "no_copy": 1, "oldfieldname": "item_code", "oldfieldtype": "Data", "read_only": 0, - "reqd": 1, + "reqd": 0, "search_index": 0 }, { @@ -891,6 +894,15 @@ "write": 1 }, { + "amend": 0, + "cancel": 0, + "create": 0, + "doctype": "DocPerm", + "role": "Material Manager", + "write": 0 + }, + { + "amend": 0, "cancel": 0, "create": 0, "doctype": "DocPerm", diff --git a/stock/doctype/item_price/item_price.txt b/stock/doctype/item_price/item_price.txt index 721902bc72b..ad0b840c112 100644 --- a/stock/doctype/item_price/item_price.txt +++ b/stock/doctype/item_price/item_price.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-03-08 15:37:16", + "creation": "2013-04-29 15:18:04", "docstatus": 0, - "modified": "2013-03-21 17:29:15", + "modified": "2013-04-29 19:16:45", "modified_by": "Administrator", "owner": "Administrator" }, @@ -68,13 +68,13 @@ "doctype": "DocField", "fieldname": "selling", "fieldtype": "Check", - "label": "For Selling" + "label": "Valid For Selling" }, { "description": "Allow this price in purchase related forms", "doctype": "DocField", "fieldname": "buying", "fieldtype": "Check", - "label": "For Buying" + "label": "Valid For Buying" } ] \ No newline at end of file diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index fa600725185..d08deefa2b1 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -194,10 +194,10 @@ class DocType(StockController): total_valuation_amount = 0 for item in self.doclist.get({"parentfield": "mtn_details"}): if item.t_warehouse and not item.s_warehouse: - total_valuation_amount += flt(item.incoming_rate) * flt(item.transfer_qty) + total_valuation_amount += flt(item.incoming_rate, 2) * flt(item.transfer_qty) if item.s_warehouse and not item.t_warehouse: - total_valuation_amount -= flt(item.incoming_rate) * flt(item.transfer_qty) + total_valuation_amount -= flt(item.incoming_rate, 2) * flt(item.transfer_qty) return total_valuation_amount @@ -607,7 +607,7 @@ class DocType(StockController): 'voucher_no': self.doc.name, 'voucher_detail_no': d.name, 'actual_qty': qty, - 'incoming_rate': flt(d.incoming_rate) or 0, + 'incoming_rate': flt(d.incoming_rate, 2) or 0, 'stock_uom': d.stock_uom, 'company': self.doc.company, 'is_cancelled': (is_cancelled ==1) and 'Yes' or 'No', diff --git a/stock/doctype/stock_entry/test_stock_entry.py b/stock/doctype/stock_entry/test_stock_entry.py index 7c406f8e8cb..c3ce2d7f40b 100644 --- a/stock/doctype/stock_entry/test_stock_entry.py +++ b/stock/doctype/stock_entry/test_stock_entry.py @@ -25,6 +25,8 @@ class TestStockEntry(unittest.TestCase): where item_code='_Test Item'""") self.assertTrue(mr_name) + + webnotes.conn.set_default("company", self.old_default_company) def test_warehouse_company_validation(self): from stock.doctype.stock_ledger_entry.stock_ledger_entry import InvalidWarehouseCompany @@ -71,7 +73,7 @@ class TestStockEntry(unittest.TestCase): webnotes.defaults.set_global_default("auto_inventory_accounting", 0) def test_material_issue_gl_entry(self): - webnotes.conn.sql("delete from `tabStock Ledger Entry`") + self._clear_stock() webnotes.defaults.set_global_default("auto_inventory_accounting", 1) mr = webnotes.bean(copy=test_records[0]) @@ -111,9 +113,10 @@ class TestStockEntry(unittest.TestCase): ) webnotes.defaults.set_global_default("auto_inventory_accounting", 0) + webnotes.conn.set_default("company", self.old_default_company) def test_material_transfer_gl_entry(self): - webnotes.conn.sql("delete from `tabStock Ledger Entry`") + self._clear_stock() webnotes.defaults.set_global_default("auto_inventory_accounting", 1) mr = webnotes.bean(copy=test_records[0]) @@ -145,6 +148,7 @@ class TestStockEntry(unittest.TestCase): self.assertFalse(gl_entries) webnotes.defaults.set_global_default("auto_inventory_accounting", 0) + webnotes.conn.set_default("company", self.old_default_company) def check_stock_ledger_entries(self, voucher_type, voucher_no, expected_sle): # check stock ledger entries @@ -173,6 +177,9 @@ class TestStockEntry(unittest.TestCase): def _clear_stock(self): webnotes.conn.sql("delete from `tabStock Ledger Entry`") webnotes.conn.sql("""delete from `tabBin`""") + + self.old_default_company = webnotes.conn.get_default("company") + webnotes.conn.set_default("company", "_Test Company") def _insert_material_receipt(self): self._clear_stock() @@ -185,6 +192,8 @@ class TestStockEntry(unittest.TestCase): se2.insert() se2.submit() + webnotes.conn.set_default("company", self.old_default_company) + def _get_actual_qty(self): return flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", "warehouse": "_Test Warehouse"}, "actual_qty")) @@ -463,6 +472,8 @@ class TestStockEntry(unittest.TestCase): self.assertEquals(actual_qty_1 - 5, actual_qty_2) + webnotes.conn.set_default("company", self.old_default_company) + return se, pr.doc.name def test_over_stock_return(self): @@ -563,6 +574,8 @@ class TestStockEntry(unittest.TestCase): self.assertEquals(actual_qty_1 - 5, actual_qty_2) + webnotes.conn.set_default("company", self.old_default_company) + return se, pr.doc.name test_records = [ diff --git a/stock/page/stock_home/stock_home.js b/stock/page/stock_home/stock_home.js index db77fced0ea..bfcaf8acc14 100644 --- a/stock/page/stock_home/stock_home.js +++ b/stock/page/stock_home/stock_home.js @@ -197,6 +197,10 @@ wn.module_page["Stock"] = [ route: "query-report/Item-Wise Price List", doctype: "Item" }, + { + "label":wn._("Purchase In Transit"), + route: "query-report/Purchase In Transit", + }, ] } ] diff --git a/stock/report/item_wise_price_list/item_wise_price_list.txt b/stock/report/item_wise_price_list/item_wise_price_list.txt index 6c2afad8972..824c603597d 100644 --- a/stock/report/item_wise_price_list/item_wise_price_list.txt +++ b/stock/report/item_wise_price_list/item_wise_price_list.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-01-02 14:22:51", + "creation": "2013-02-22 18:01:55", "docstatus": 0, - "modified": "2013-02-22 15:53:01", + "modified": "2013-05-07 11:50:46", "modified_by": "Administrator", "owner": "Administrator" }, @@ -10,7 +10,7 @@ "doctype": "Report", "is_standard": "Yes", "name": "__common__", - "query": "select\n item.name as \"ID:Link/Item:120\", \n item.item_name as \"Item Name::120\", \n item_price.price_list_name as \"Price List::80\",\n item_price.ref_currency as \"Currency::40\", \n item_price.ref_rate as \"Rate:Currency:80\",\n item.description as \"Description::160\",\n item.item_group as \"Item Group:Link/Item Group:100\",\n item.brand as \"Brand::100\"\nfrom `tabItem` item, `tabItem Price` item_price\nwhere\n item_price.parent = item.name", + "query": "select\n item.name as \"ID:Link/Item:120\", \n item.item_name as \"Item Name::120\", \n item_price.price_list_name as \"Price List::80\",\n item_price.ref_currency as \"Currency::40\", \n item_price.ref_rate as \"Rate:Float:80\",\n item.description as \"Description::160\",\n item.item_group as \"Item Group:Link/Item Group:100\",\n item.brand as \"Brand::100\"\nfrom `tabItem` item, `tabItem Price` item_price\nwhere\n item_price.parent = item.name", "ref_doctype": "Item", "report_name": "Item-Wise Price List", "report_type": "Query Report" diff --git a/stock/report/purchase_in_transit/__init__.py b/stock/report/purchase_in_transit/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/stock/report/purchase_in_transit/purchase_in_transit.txt b/stock/report/purchase_in_transit/purchase_in_transit.txt new file mode 100644 index 00000000000..60ce0da460d --- /dev/null +++ b/stock/report/purchase_in_transit/purchase_in_transit.txt @@ -0,0 +1,22 @@ +[ + { + "creation": "2013-05-06 12:09:05", + "docstatus": 0, + "modified": "2013-05-06 12:22:52", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "query": "SELECT\n pi.name as \"Purchase Invoice:Link/Purchase Invoice:120\",\n\tpi.posting_date as \"Posting Date:Date:100\",\n\tpi.credit_to as \"Supplier Account:Link/Account:120\",\n\tpi_item.item_code as \"Item Code:Link/Item:120\",\n\tpi_item.description as \"Description:Data:140\",\n\tpi_item.qty as \"Qty:Float:120\",\n\tpi_item.amount as \"Amount:Currency:120\",\n\tpi_item.purchase_order as \"Purchase Order:Link/Purchase Order:120\",\n\tpi_item.purchase_receipt as \"Purchase Receipt:Link/Purchase Receipt:120\",\n\tpr.posting_date as \"PR Posting Date:Date:130\",\n\tpi.company as \"Company:Link/Company:120\"\nFROM\n\t`tabPurchase Invoice` pi, `tabPurchase Invoice Item` pi_item, `tabPurchase Receipt` pr\nWHERE\n\tpi.name = pi_item.parent and pi_item.purchase_receipt = pr.name\n\tand pi.docstatus = 1 and pr.posting_date > pi.posting_date\nORDER BY\n\tpi.name desc", + "ref_doctype": "Purchase Receipt", + "report_name": "Purchase In Transit", + "report_type": "Query Report" + }, + { + "doctype": "Report", + "name": "Purchase In Transit" + } +] \ No newline at end of file diff --git a/support/page/support_home/support_home.js b/support/page/support_home/support_home.js index d397daa6ce4..bde5e5c00ad 100644 --- a/support/page/support_home/support_home.js +++ b/support/page/support_home/support_home.js @@ -72,6 +72,18 @@ wn.module_page["Support"] = [ }, ] }, + { + title: wn._("Reports"), + right: true, + icon: "icon-list", + items: [ + { + "label":wn._("Maintenance Schedules"), + route: "query-report/Maintenance Schedules", + doctype: "Maintenance Schedule" + } + ] + } ] pscript['onload_support-home'] = function(wrapper) { diff --git a/support/report/__init__.py b/support/report/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/support/report/maintenance_schedules/__init__.py b/support/report/maintenance_schedules/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/support/report/maintenance_schedules/maintenance_schedules.txt b/support/report/maintenance_schedules/maintenance_schedules.txt new file mode 100644 index 00000000000..525f4834ba8 --- /dev/null +++ b/support/report/maintenance_schedules/maintenance_schedules.txt @@ -0,0 +1,22 @@ +[ + { + "creation": "2013-05-06 14:25:21", + "docstatus": 0, + "modified": "2013-05-06 14:32:47", + "modified_by": "Administrator", + "owner": "Administrator" + }, + { + "doctype": "Report", + "is_standard": "Yes", + "name": "__common__", + "query": "SELECT\n ms_item.scheduled_date as \"Schedule Date:Date:120\",\n\tms_item.item_code as \"Item Code:Link/Item:120\",\n\tms_item.item_name as \"Item Name::120\",\n\tms_item.serial_no as \"Serial No::120\",\n\tms_item.incharge_name as \"Incharge::120\",\n\tms.customer_name as \"Customer:Link/Customer:120\",\n\tms.address_display as \"Customer Address::120\",\n\tms.sales_order_no as \"Sales Order:Link/Sales Order:120\",\n\tms.company as \"Company:Link/Company:120\"\n\t\nFROM\n\t`tabMaintenance Schedule` ms, `tabMaintenance Schedule Detail` ms_item\nWHERE\n\tms.name = ms_item.parent and ms.docstatus = 1\nORDER BY\n\tms_item.scheduled_date asc, ms_item.item_code asc", + "ref_doctype": "Maintenance Schedule", + "report_name": "Maintenance Schedules", + "report_type": "Query Report" + }, + { + "doctype": "Report", + "name": "Maintenance Schedules" + } +] \ No newline at end of file diff --git a/utilities/doctype/address/test_address.py b/utilities/doctype/address/test_address.py new file mode 100644 index 00000000000..eddd9c754de --- /dev/null +++ b/utilities/doctype/address/test_address.py @@ -0,0 +1,14 @@ +test_records = [ + [{ + "doctype": "Address", + "customer": "_Test Customer", + "customer_name": "_Test Customer", + "address_type": "Office", + "address_title": "_Test Address", + "address_line1": "_Test Address Line 1", + "city": "_Test City", + "country": "India", + "phone": "+91 0000000000", + "is_primary_address": 1 + }], +] \ No newline at end of file diff --git a/utilities/transaction_base.py b/utilities/transaction_base.py index 4b34ba1286c..5d7d1a84b1a 100644 --- a/utilities/transaction_base.py +++ b/utilities/transaction_base.py @@ -22,6 +22,23 @@ from webnotes.model.doc import addchild from webnotes.model.controller import DocListController class TransactionBase(DocListController): + def get_default_address_and_contact(self, party_type): + """get a dict of default field values of address and contact for a given party type + party_type can be one of: customer, supplier""" + ret = {} + + # {customer: self.doc.fields.get("customer")} + args = {party_type: self.doc.fields.get(party_type)} + + address_text, address_name = self.get_address_text(**args) + ret.update({ + # customer_address + (party_type + "_address"): address_name, + "address_display": address_text + }) + ret.update(self.get_contact_text(**args)) + return ret + # Get Customer Default Primary Address - first load def get_default_customer_address(self, args=''): address_text, address_name = self.get_address_text(customer=self.doc.customer) @@ -73,7 +90,7 @@ class TransactionBase(DocListController): details = webnotes.conn.sql("select name, address_line1, address_line2, city, country, pincode, state, phone, fax from `tabAddress` where %s and docstatus != 2 order by is_shipping_address desc, is_primary_address desc limit 1" % cond, as_dict = 1) else: details = webnotes.conn.sql("select name, address_line1, address_line2, city, country, pincode, state, phone, fax from `tabAddress` where %s and docstatus != 2 order by is_primary_address desc limit 1" % cond, as_dict = 1) - + extract = lambda x: details and details[0] and details[0].get(x,'') or '' address_fields = [('','address_line1'),('\n','address_line2'),('\n','city'),('\n','state'),(' ','pincode'),('\n','country'),('\nPhone: ','phone'),('\nFax: ', 'fax')] address_display = ''.join([a[0]+extract(a[1]) for a in address_fields if extract(a[1])]) diff --git a/website/doctype/about_us_settings/about_us_settings.txt b/website/doctype/about_us_settings/about_us_settings.txt index ef6122ec61a..baf9cc0af8c 100644 --- a/website/doctype/about_us_settings/about_us_settings.txt +++ b/website/doctype/about_us_settings/about_us_settings.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-03-26 12:48:00", + "creation": "2013-03-19 12:02:15", "docstatus": 0, - "modified": "2013-03-12 14:48:34", + "modified": "2013-05-03 11:01:30", "modified_by": "Administrator", "owner": "Administrator" }, @@ -10,7 +10,7 @@ "allow_attach": 1, "description": "Settings for the About Us Page", "doctype": "DocType", - "document_type": "Master", + "document_type": "Other", "issingle": 1, "module": "Website", "name": "__common__" @@ -21,7 +21,8 @@ "parent": "About Us Settings", "parentfield": "fields", "parenttype": "DocType", - "permlevel": 0 + "permlevel": 0, + "read_only": 0 }, { "create": 1, diff --git a/website/doctype/website_settings/website_settings.txt b/website/doctype/website_settings/website_settings.txt index ed3380f16dc..9c15480f07a 100644 --- a/website/doctype/website_settings/website_settings.txt +++ b/website/doctype/website_settings/website_settings.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-03-26 06:51:18", + "creation": "2013-04-30 12:58:46", "docstatus": 0, - "modified": "2013-04-17 11:51:24", + "modified": "2013-05-02 15:51:14", "modified_by": "Administrator", "owner": "Administrator" }, @@ -219,13 +219,16 @@ "reqd": 0 }, { - "description": "Enter domain names associated to this website, each on a new line", "doctype": "DocField", - "fieldname": "domain_list", - "fieldtype": "Text", - "hidden": 1, - "label": "Domain List", - "reqd": 0 + "fieldname": "column_break_28", + "fieldtype": "Column Break" + }, + { + "description": "Disable Customer Signup link in Login page", + "doctype": "DocField", + "fieldname": "disable_signup", + "fieldtype": "Check", + "label": "Disable Signup" }, { "create": 1,