From 0fc24543843c4e3f727f914562d3b6d6885290e8 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 25 Mar 2013 11:06:00 +0530 Subject: [PATCH 1/8] aii: patches and fine tuning --- .../purchase_invoice/purchase_invoice.py | 100 +++++++++--------- .../purchase_invoice/test_purchase_invoice.py | 41 ++++++- .../doctype/sales_invoice/sales_invoice.py | 25 +++-- .../sales_invoice_item/sales_invoice_item.txt | 15 ++- accounts/utils.py | 61 +++++++++++ .../purchase_common/purchase_common.py | 2 +- controllers/accounts_controller.py | 16 +-- controllers/buying_controller.py | 4 +- controllers/selling_controller.py | 10 +- controllers/stock_controller.py | 10 +- selling/doctype/sales_common/sales_common.py | 8 +- setup/doctype/company/company.js | 7 ++ setup/doctype/company/company.py | 14 +-- setup/doctype/company/company.txt | 32 +++--- .../global_defaults/global_defaults.py | 9 ++ .../delivery_note_item/delivery_note_item.txt | 6 +- .../purchase_receipt/purchase_receipt.py | 2 +- stock/doctype/stock_entry/stock_entry.js | 4 +- stock/doctype/stock_entry/stock_entry.py | 3 +- .../stock_reconciliation.js | 4 +- .../stock_reconciliation.py | 6 +- 21 files changed, 255 insertions(+), 124 deletions(-) diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.py b/accounts/doctype/purchase_invoice/purchase_invoice.py index f535d56e60..fb9977c486 100644 --- a/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -33,6 +33,47 @@ class DocType(BuyingController): self.doc, self.doclist = d, dl self.tname = 'Purchase Invoice Item' self.fname = 'entries' + + def validate(self): + super(DocType, self).validate() + + self.po_required() + self.pr_required() + self.check_active_purchase_items() + self.check_conversion_rate() + self.validate_bill_no_date() + self.validate_bill_no() + self.validate_reference_value() + self.validate_credit_acc() + self.clear_unallocated_advances("Purchase Invoice Advance", "advance_allocation_details") + self.check_for_acc_head_of_supplier() + self.check_for_stopped_status() + + self.po_list, self.pr_list = [], [] + for d in getlist(self.doclist, 'entries'): + self.validate_supplier(d) + self.validate_po_pr(d) + if not d.purchase_order in self.po_list: + self.po_list.append(d.purchase_order) + if not d.purhcase_receipt in self.pr_list: + self.pr_list.append(d.purchase_receipt) + + + if not self.doc.is_opening: + self.doc.is_opening = 'No' + + self.set_aging_date() + + #set against account for credit to + self.set_against_expense_account() + + #FY validation + get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year, + self.doc.posting_date,'Posting Date') + + self.validate_write_off_account() + self.update_raw_material_cost() + self.update_valuation_rate("entries") def get_credit_to(self): acc_head = sql("select name, credit_days from `tabAccount` where (name = %s or (master_name = %s and master_type = 'supplier')) and docstatus != 2", (cstr(self.doc.supplier) + " - " + self.company_abbr,self.doc.supplier)) @@ -265,7 +306,7 @@ class DocType(BuyingController): def set_against_expense_account(self): auto_inventory_accounting = \ cint(webnotes.defaults.get_global_default("auto_inventory_accounting")) - stock_not_billed_account = "Stock Received But Not Billed - %s" % self.company_abbr + stock_not_billed_account = self.get_company_default("stock_received_but_not_billed") against_accounts = [] for item in self.doclist.get({"parentfield": "entries"}): @@ -277,6 +318,10 @@ class DocType(BuyingController): if stock_not_billed_account not in against_accounts: against_accounts.append(stock_not_billed_account) + elif not item.expense_head: + msgprint(_("""Expense account is mandatory for item: """) + item.item_code, + raise_exception=1) + elif item.expense_head not in against_accounts: # if no auto_inventory_accounting or not a stock item against_accounts.append(item.expense_head) @@ -303,47 +348,6 @@ class DocType(BuyingController): if self.doc.write_off_amount and not self.doc.write_off_account: msgprint("Please enter Write Off Account", raise_exception=1) - def validate(self): - super(DocType, self).validate() - - self.po_required() - self.pr_required() - self.check_active_purchase_items() - self.check_conversion_rate() - self.validate_bill_no_date() - self.validate_bill_no() - self.validate_reference_value() - self.validate_credit_acc() - self.clear_unallocated_advances("Purchase Invoice Advance", "advance_allocation_details") - self.check_for_acc_head_of_supplier() - self.check_for_stopped_status() - - self.po_list, self.pr_list = [], [] - for d in getlist(self.doclist, 'entries'): - self.validate_supplier(d) - self.validate_po_pr(d) - if not d.purchase_order in self.po_list: - self.po_list.append(d.purchase_order) - if not d.purhcase_receipt in self.pr_list: - self.pr_list.append(d.purchase_receipt) - - - if not self.doc.is_opening: - self.doc.is_opening = 'No' - - self.set_aging_date() - - #set against account for credit to - self.set_against_expense_account() - - #FY validation - get_obj('Sales Common').validate_fiscal_year(self.doc.fiscal_year, - self.doc.posting_date,'Posting Date') - - self.validate_write_off_account() - self.update_raw_material_cost() - self.update_valuation_rate("entries") - def check_prev_docstatus(self): for d in getlist(self.doclist,'entries'): if d.purchase_order: @@ -445,7 +449,7 @@ class DocType(BuyingController): # item gl entries stock_item_and_auto_inventory_accounting = False if auto_inventory_accounting: - stock_acocunt = self.get_default_account("stock_received_but_not_billed") + stock_account = self.get_company_default("stock_received_but_not_billed") for item in self.doclist.get({"parentfield": "entries"}): if auto_inventory_accounting and item.item_code in self.stock_items: @@ -458,7 +462,7 @@ class DocType(BuyingController): gl_entries.append( self.get_gl_dict({ - "account": stock_acocunt, + "account": stock_account, "against": self.doc.credit_to, "debit": flt(item.valuation_rate) * flt(item.conversion_factor) \ * flt(item.qty), @@ -483,8 +487,8 @@ class DocType(BuyingController): # this will balance out valuation amount included in cost of goods sold gl_entries.append( self.get_gl_dict({ - "account": self.get_default_account("expenses_included_in_valuation"), - "cost_center": "Auto Inventory Accounting - %s" % self.company_abbr, + "account": self.get_company_default("expenses_included_in_valuation"), + "cost_center": self.get_company_default("stock_adjustment_cost_center"), "against": self.doc.credit_to, "credit": valuation_tax, "remarks": self.doc.remarks or "Accounting Entry for Stock" @@ -525,8 +529,8 @@ class DocType(BuyingController): and is_active = 1 """, (d.item_code,)) rm_cost = rm_cost and flt(rm_cost[0][0]) or 0 - d.conversion_factor = d.conversion_factor or webnotes.conn.get_value( + d.conversion_factor = d.conversion_factor or flt(webnotes.conn.get_value( "UOM Conversion Detail", {"parent": d.item_code, "uom": d.uom}, - "conversion_factor") or 1 + "conversion_factor")) or 1 d.rm_supp_cost = rm_cost * flt(d.qty) * flt(d.conversion_factor) \ No newline at end of file diff --git a/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 6d9cfca048..621604b96b 100644 --- a/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -109,12 +109,49 @@ class TestPurchaseInvoice(unittest.TestCase): # print tax.account_head, tax.tax_amount, tax.item_wise_tax_detail expected_values = [ - ["_Test Item Home Desktop 100", 90], - ["_Test Item Home Desktop 200", 135] + ["_Test Item Home Desktop 100", 90, 59], + ["_Test Item Home Desktop 200", 135, 177] ] for i, item in enumerate(wrapper.doclist.get({"parentfield": "entries"})): self.assertEqual(item.item_code, expected_values[i][0]) self.assertEqual(item.item_tax_amount, expected_values[i][1]) + self.assertEqual(item.valuation_rate, expected_values[i][2]) + + def test_purchase_invoice_with_subcontracted_item(self): + wrapper = webnotes.bean(copy=test_records[0]) + wrapper.doclist[1].item_code = "_Test FG Item" + wrapper.run_method("calculate_taxes_and_totals") + wrapper.insert() + wrapper.load_from_db() + + self.assertEqual(wrapper.doclist[0].net_total, 1250) + + # tax amounts + expected_values = [ + ["_Test Account Shipping Charges - _TC", 100, 1350], + ["_Test Account Customs Duty - _TC", 125, 1350], + ["_Test Account Excise Duty - _TC", 140, 1490], + ["_Test Account Education Cess - _TC", 2.8, 1492.8], + ["_Test Account S&H Education Cess - _TC", 1.4, 1494.2], + ["_Test Account CST - _TC", 29.88, 1524.08], + ["_Test Account VAT - _TC", 156.25, 1680.33], + ["_Test Account Discount - _TC", 168.03, 1512.30], + ] + + for i, tax in enumerate(wrapper.doclist.get({"parentfield": "purchase_tax_details"})): + self.assertEqual(tax.account_head, expected_values[i][0]) + self.assertEqual(tax.tax_amount, expected_values[i][1]) + self.assertEqual(tax.total, expected_values[i][2]) + # print tax.account_head, tax.tax_amount, tax.item_wise_tax_detail + + expected_values = [ + ["_Test FG Item", 90, 7059], + ["_Test Item Home Desktop 200", 135, 177] + ] + for i, item in enumerate(wrapper.doclist.get({"parentfield": "entries"})): + self.assertEqual(item.item_code, expected_values[i][0]) + self.assertEqual(item.item_tax_amount, expected_values[i][1]) + self.assertEqual(item.valuation_rate, expected_values[i][2]) def test_purchase_invoice_with_advance(self): from accounts.doctype.journal_voucher.test_journal_voucher \ diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py index 9b5c80cfbb..4b0f3b1608 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.py +++ b/accounts/doctype/sales_invoice/sales_invoice.py @@ -249,7 +249,7 @@ class DocType(SellingController): ['Delivery Note Item', 'Sales Invoice Item'], ['Sales Taxes and Charges','Sales Taxes and Charges'], ['Sales Team','Sales Team']]""") - self.get_income_account('entries') + self.get_income_expense_account('entries') elif self.doc.sales_order_main: self.validate_prev_docname('sales order') @@ -259,7 +259,7 @@ class DocType(SellingController): """[['Sales Order', 'Sales Invoice'],['Sales Order Item', 'Sales Invoice Item'], ['Sales Taxes and Charges','Sales Taxes and Charges'], ['Sales Team', 'Sales Team']]""") - self.get_income_account('entries') + self.get_income_expense_account('entries') ret = self.get_debit_to() self.doc.debit_to = ret.get('debit_to') @@ -269,16 +269,21 @@ class DocType(SellingController): """ Loads default accounts from items, customer when called from mapper """ - self.get_income_account('entries') + self.get_income_expense_account('entries') - def get_income_account(self,doctype): + def get_income_expense_account(self,doctype): for d in getlist(self.doclist, doctype): if d.item_code: - item = webnotes.conn.get_value("Item", d.item_code, - ["default_income_account", "default_sales_cost_center"], as_dict=True) + item = webnotes.conn.get_value("Item", d.item_code, ["default_income_account", + "default_sales_cost_center", "purchase_account", "cost_center"], as_dict=True) d.income_account = item['default_income_account'] or "" - d.cost_center = item['default_sales_cost_center'] or "" + d.cost_center = item['default_sales_cost_center'] or "" + + if cint(webnotes.defaults.get_global_default("auto_inventory_accounting")) \ + and cint(self.doc.is_pos) and cint(self.doc.update_stock): + d.expense_account = item['purchase_account'] or "" + d.purchase_cost_center = item['cost_center'] or "" def get_item_details(self, args=None): @@ -294,8 +299,10 @@ class DocType(SellingController): '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') - }; + 'warehouse': doc.fields.get('warehouse'), + 'expense_account': doc.fields.get('expense_account'), + 'purchase_cost_center': doc.fields.get('purchase_cost_center') + } ret = self.get_pos_details(arg) for r in ret: diff --git a/accounts/doctype/sales_invoice_item/sales_invoice_item.txt b/accounts/doctype/sales_invoice_item/sales_invoice_item.txt index bc51198f3b..221359ce90 100644 --- a/accounts/doctype/sales_invoice_item/sales_invoice_item.txt +++ b/accounts/doctype/sales_invoice_item/sales_invoice_item.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-07 11:42:55", "docstatus": 0, - "modified": "2013-03-21 18:35:47", + "modified": "2013-03-22 18:40:48", "modified_by": "Administrator", "owner": "Administrator" }, @@ -222,7 +222,7 @@ "fieldname": "cost_center", "fieldtype": "Link", "in_filter": 1, - "label": "Cost Center", + "label": "Sales Cost Center", "oldfieldname": "cost_center", "oldfieldtype": "Link", "options": "Cost Center", @@ -232,6 +232,17 @@ "reqd": 0, "width": "120px" }, + { + "doctype": "DocField", + "fieldname": "purchase_cost_center", + "fieldtype": "Link", + "hidden": 1, + "in_filter": 1, + "label": "Purchase Cost Center", + "options": "Cost Center", + "print_hide": 1, + "width": "120px" + }, { "doctype": "DocField", "fieldname": "serial_no", diff --git a/accounts/utils.py b/accounts/utils.py index 051cdd1b24..92173ab8ee 100644 --- a/accounts/utils.py +++ b/accounts/utils.py @@ -248,3 +248,64 @@ def remove_against_link_from_jv(ref_type, ref_no, against_field): and voucher_no != ifnull(against_voucher, "") and ifnull(is_cancelled, "No")="No" """, (now(), webnotes.session.user, ref_type, ref_no)) + +@webnotes.whitelist() +def get_company_default(company, fieldname): + value = webnotes.conn.get_value("Company", company, fieldname) + + if not value: + msgprint(_("Please mention default value for '") + + _(webnotes.get_doctype("company").get_label(fieldname) + + _("' in Company: ") + company), raise_exception=True) + + return value + +def create_stock_in_hand_jv(reverse=False): + from webnotes.utils import nowdate + today = nowdate() + fiscal_year = get_fiscal_year(today)[0] + + for company in webnotes.conn.sql_list("select name from `tabCompany`"): + stock_rbnb_value = get_stock_rbnb_value(company) + + jv = webnotes.bean([ + { + "doctype": "Journal Voucher", + "naming_series": "_PATCH-", + "company": company, + "posting_date": today, + "fiscal_year": fiscal_year, + "voucher_type": "Journal Entry" + }, + { + "doctype": "Journal Voucher Detail", + "parentfield": "entries", + "account": get_company_default(company, "stock_received_but_not_billed"), + (reverse and "debit" or "credit"): stock_rbnb_value + }, + { + "doctype": "Journal Voucher Detail", + "parentfield": "entries", + "account": get_company_default(company, "stock_adjustment_account"), + (reverse and "credit" or "debit"): stock_rbnb_value + }, + ]) + jv.insert() + jv.submit() + +def get_stock_rbnb_value(company): + total_received_amount = webnotes.conn.sql("""select sum(valuation_amount) + from `tabPurchase Receipt Item` pr_item where docstatus=1 + and exists(select name from `tabItem` where name = pr_item.item_code + and is_stock_item='Yes') + and exist(select name from `tabPurchase Receipt` + where name = pr_item.parent and company = %s)""", company) + + total_billed_amount = webnotes.conn.sql("""select sum(valuation_amount) + from `tabPurchase Invoice Item` pi_item where docstatus=1 + and exists(select name from `tabItem` where name = pi_item.item_code + and is_stock_item='Yes') + and exist(select name from `tabPurchase Invoice` + where name = pi_item.parent and company = %s)""", company) + + return flt(total_received_amount[0][0]) - flt(total_billed_amount[0][0]) diff --git a/buying/doctype/purchase_common/purchase_common.py b/buying/doctype/purchase_common/purchase_common.py index 6af08c6520..d5b563b3c5 100644 --- a/buying/doctype/purchase_common/purchase_common.py +++ b/buying/doctype/purchase_common/purchase_common.py @@ -402,7 +402,7 @@ class DocType(BuyingController): yed=add_days(str(ysd),365) if str(transaction_date) < str(ysd) or str(transaction_date) > str(yed): msgprint("'%s' Not Within The Fiscal Year"%(dn)) - raise Exception + raise Exception def load_default_taxes(self, obj): return self.get_purchase_tax_details(obj, 1) diff --git a/controllers/accounts_controller.py b/controllers/accounts_controller.py index ac6481cef7..0e7c108f3d 100644 --- a/controllers/accounts_controller.py +++ b/controllers/accounts_controller.py @@ -76,14 +76,9 @@ class AccountsController(TransactionBase): "allocate_amount": 0 }) - def get_default_account(self, account_for): - account = webnotes.conn.get_value("Company", self.doc.company, account_for) - if not account: - msgprint(_("Please mention default account for '") + - _(webnotes.get_doctype("company").get_label(account_for) + - _("' in Company: ") + self.doc.company), raise_exception=True) - - return account + def get_company_default(self, fieldname): + from accounts.utils import get_company_default + return get_company_default(self.doc.company, fieldname) @property def stock_items(self): @@ -101,8 +96,3 @@ class AccountsController(TransactionBase): self._abbr = webnotes.conn.get_value("Company", self.doc.company, "abbr") return self._abbr - - -@webnotes.whitelist() -def get_default_account(account_for, company): - return webnotes.conn.get_value("Company", company, account_for) diff --git a/controllers/buying_controller.py b/controllers/buying_controller.py index 2c2bb44a56..560dec2a15 100644 --- a/controllers/buying_controller.py +++ b/controllers/buying_controller.py @@ -332,9 +332,9 @@ class BuyingController(StockController): # update valuation rate def update_valuation_rate(self, parentfield): for d in self.doclist.get({"parentfield": parentfield}): - d.conversion_factor = d.conversion_factor or webnotes.conn.get_value( + d.conversion_factor = d.conversion_factor or flt(webnotes.conn.get_value( "UOM Conversion Detail", {"parent": d.item_code, "uom": d.uom}, - "conversion_factor") or 1 + "conversion_factor")) or 1 if d.item_code and d.qty: # if no item code, which is sometimes the case in purchase invoice, # then it is not possible to track valuation against it diff --git a/controllers/selling_controller.py b/controllers/selling_controller.py index 538c5c1a7e..ab002be801 100644 --- a/controllers/selling_controller.py +++ b/controllers/selling_controller.py @@ -18,6 +18,7 @@ from __future__ import unicode_literals import webnotes from webnotes.utils import cint from setup.utils import get_company_currency +from webnotes import msgprint, _ from controllers.stock_controller import StockController @@ -58,5 +59,10 @@ class SellingController(StockController): 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 - webnotes.conn.set_value(self.tname, item.name, "buying_amount", - item.buying_amount) \ No newline at end of file + webnotes.conn.set_value(item.doctype, item.name, "buying_amount", + item.buying_amount) + + def check_expense_account(self, item): + if item.buying_amount and not item.expense_account: + msgprint(_("""Expense account is mandatory for item: """) + item.item_code, + raise_exception=1) \ No newline at end of file diff --git a/controllers/stock_controller.py b/controllers/stock_controller.py index c76865d371..89f62aacf3 100644 --- a/controllers/stock_controller.py +++ b/controllers/stock_controller.py @@ -23,7 +23,9 @@ class StockController(AccountsController): def get_gl_entries_for_stock(self, against_stock_account, amount, stock_in_hand_account=None, cost_center=None): if not stock_in_hand_account: - stock_in_hand_account = self.get_default_account("stock_in_hand_account") + stock_in_hand_account = self.get_company_default("stock_in_hand_account") + if not cost_center: + cost_center = self.get_company_default("stock_adjustment_cost_center") if amount: gl_entries = [ @@ -46,12 +48,6 @@ class StockController(AccountsController): ] return gl_entries - - - def check_expense_account(self, item): - if not item.expense_account: - msgprint(_("""Expense account is mandatory for item: """) + item.item_code, - raise_exception=1) def get_stock_ledger_entries(self, item_list=None, warehouse_list=None): if not (item_list and warehouse_list): diff --git a/selling/doctype/sales_common/sales_common.py b/selling/doctype/sales_common/sales_common.py index 12ae4a8c90..fca96b8fa5 100644 --- a/selling/doctype/sales_common/sales_common.py +++ b/selling/doctype/sales_common/sales_common.py @@ -17,11 +17,11 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import cint, cstr, flt, getdate, nowdate, formatdate +from webnotes.utils import cint, cstr, flt, getdate, nowdate from webnotes.model.doc import addchild from webnotes.model.bean import getlist from webnotes.model.code import get_obj -from webnotes import msgprint, _ +from webnotes import msgprint from setup.utils import get_company_currency get_value = webnotes.conn.get_value @@ -127,7 +127,7 @@ class DocType(TransactionBase): if not obj.doc.price_list_name: msgprint("Please Select Price List before selecting Items") raise Exception - item = webnotes.conn.sql("select description, item_name, brand, item_group, stock_uom, default_warehouse, default_income_account, default_sales_cost_center, description_html, barcode from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or end_of_life > now() or end_of_life = '0000-00-00') and (is_sales_item = 'Yes' or is_service_item = 'Yes')" % (args['item_code']), as_dict=1) + item = webnotes.conn.sql("select description, item_name, brand, item_group, stock_uom, default_warehouse, default_income_account, default_sales_cost_center, purchase_account, cost_center, description_html, barcode from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or end_of_life > now() or end_of_life = '0000-00-00') and (is_sales_item = 'Yes' or is_service_item = 'Yes')" % (args['item_code']), as_dict=1) tax = webnotes.conn.sql("select tax_type, tax_rate from `tabItem Tax` where parent = %s" , args['item_code']) t = {} for x in tax: t[x[0]] = flt(x[1]) @@ -141,7 +141,9 @@ class DocType(TransactionBase): 'reserved_warehouse' : item and item[0]['default_warehouse'] or '', 'warehouse' : item and item[0]['default_warehouse'] or args.get('warehouse'), 'income_account' : item and item[0]['default_income_account'] or args.get('income_account'), + 'expense_account' : item and item[0]['purchase_account'] or args.get('expense_account'), 'cost_center' : item and item[0]['default_sales_cost_center'] or args.get('cost_center'), + 'purchase_cost_center' : item and item[0]['cost_center'] or args.get('purchase_cost_center'), 'qty' : 1.00, # this is done coz if item once fetched is fetched again thn its qty shld be reset to 1 'adj_rate' : 0, 'amount' : 0, diff --git a/setup/doctype/company/company.js b/setup/doctype/company/company.js index a89882347e..735f5149cc 100644 --- a/setup/doctype/company/company.js +++ b/setup/doctype/company/company.js @@ -97,4 +97,11 @@ cur_frm.fields_dict["stock_received_but_not_billed"].get_query = function(doc) { "company": doc.name } } +} + +cur_frm.fields_dict["stock_adjustment_cost_center"].get_query = function(doc) { + return { + "query": "accounts.utils.get_cost_center_list", + "filters": {"company": doc.name} + } } \ No newline at end of file diff --git a/setup/doctype/company/company.py b/setup/doctype/company/company.py index 15241a2ba6..a2e56eb331 100644 --- a/setup/doctype/company/company.py +++ b/setup/doctype/company/company.py @@ -199,12 +199,7 @@ class DocType: if not self.doc.payables_group and webnotes.conn.exists('Account', 'Accounts Payable - ' + self.doc.abbr): webnotes.conn.set(self.doc, 'payables_group', 'Accounts Payable - ' + self.doc.abbr) - - if not self.doc.stock_delivered_but_not_billed and webnotes.conn.exists("Account", - "Stock Delivered But Not Billed - " + self.doc.abbr): - webnotes.conn.set(self.doc, "stock_delivered_but_not_billed", - "Stock Delivered But Not Billed - " + self.doc.abbr) - + if not self.doc.stock_received_but_not_billed and webnotes.conn.exists("Account", "Stock Received But Not Billed - " + self.doc.abbr): webnotes.conn.set(self.doc, "stock_received_but_not_billed", @@ -219,7 +214,12 @@ class DocType: "Expenses Included In Valuation - " + self.doc.abbr): webnotes.conn.set(self.doc, "expenses_included_in_valuation", "Expenses Included In Valuation - " + self.doc.abbr) - + + if not self.doc.stock_adjustment_cost_center and webnotes.conn.exists("Cost Center", + "Auto Inventory Accounting - " + self.doc.abbr): + webnotes.conn.set(self.doc, "stock_adjustment_cost_center", + "Auto Inventory Accounting - " + self.doc.abbr) + # Create default cost center # --------------------------------------------------- def create_default_cost_center(self): diff --git a/setup/doctype/company/company.txt b/setup/doctype/company/company.txt index 4d2dcdae68..e9976aa26d 100644 --- a/setup/doctype/company/company.txt +++ b/setup/doctype/company/company.txt @@ -2,7 +2,7 @@ { "creation": "2013-02-27 09:38:05", "docstatus": 0, - "modified": "2013-03-19 12:52:00", + "modified": "2013-03-22 18:19:36", "modified_by": "Administrator", "owner": "Administrator" }, @@ -189,16 +189,10 @@ }, { "doctype": "DocField", - "fieldname": "stock_adjustment_account", + "fieldname": "stock_received_but_not_billed", "fieldtype": "Link", - "label": "Stock Adjustment Account", - "options": "Account" - }, - { - "doctype": "DocField", - "fieldname": "expenses_included_in_valuation", - "fieldtype": "Link", - "label": "Expenses Included In Valuation", + "label": "Stock Received But Not Billed", + "no_copy": 1, "options": "Account" }, { @@ -209,18 +203,28 @@ }, { "doctype": "DocField", - "fieldname": "stock_delivered_but_not_billed", + "fieldname": "stock_adjustment_account", "fieldtype": "Link", - "label": "Stock Delivered But Not Billed", + "label": "Stock Adjustment Account", + "no_copy": 1, "options": "Account" }, { "doctype": "DocField", - "fieldname": "stock_received_but_not_billed", + "fieldname": "expenses_included_in_valuation", "fieldtype": "Link", - "label": "Stock Received But Not Billed", + "label": "Expenses Included In Valuation", + "no_copy": 1, "options": "Account" }, + { + "doctype": "DocField", + "fieldname": "stock_adjustment_cost_center", + "fieldtype": "Link", + "label": "Stock Adjustment Cost Center", + "no_copy": 1, + "options": "Cost Center" + }, { "description": "For reference only.", "doctype": "DocField", diff --git a/setup/doctype/global_defaults/global_defaults.py b/setup/doctype/global_defaults/global_defaults.py index 8d94a03aa5..e755bb9522 100644 --- a/setup/doctype/global_defaults/global_defaults.py +++ b/setup/doctype/global_defaults/global_defaults.py @@ -44,11 +44,20 @@ keydict = { 'session_expiry': 'session_expiry', 'disable_rounded_total': 'disable_rounded_total', "update_stock": "update_stock", + # "auto_inventory_accounting": "auto_inventory_accounting", } class DocType: def __init__(self, d, dl): self.doc, self.doclist = d, dl + + def validate(self): + previous_auto_inventory_accounting = cint(webnotes.conn.get_value("Global Defaults", None, + "auto_inventory_accounting")) + if cint(self.doc.auto_inventory_accounting) != previous_auto_inventory_accounting: + from accounts.utils import create_stock_in_hand_jv + create_stock_in_hand_jv(reverse = \ + cint(self.doc.auto_inventory_accounting) < previous_auto_inventory_accounting) def on_update(self): """update defaults""" diff --git a/stock/doctype/delivery_note_item/delivery_note_item.txt b/stock/doctype/delivery_note_item/delivery_note_item.txt index 94c6541172..ffc19c36e1 100644 --- a/stock/doctype/delivery_note_item/delivery_note_item.txt +++ b/stock/doctype/delivery_note_item/delivery_note_item.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-07 11:42:59", "docstatus": 0, - "modified": "2013-03-21 18:36:22", + "modified": "2013-03-22 18:43:10", "modified_by": "Administrator", "owner": "Administrator" }, @@ -257,10 +257,10 @@ }, { "doctype": "DocField", - "fieldname": "cost_center", + "fieldname": "purchase_cost_center", "fieldtype": "Link", "hidden": 1, - "label": "Cost Center", + "label": "Purchase Cost Center", "no_copy": 1, "options": "Cost Center", "print_hide": 1, diff --git a/stock/doctype/purchase_receipt/purchase_receipt.py b/stock/doctype/purchase_receipt/purchase_receipt.py index 7949a1c1c3..11c294c72d 100644 --- a/stock/doctype/purchase_receipt/purchase_receipt.py +++ b/stock/doctype/purchase_receipt/purchase_receipt.py @@ -320,7 +320,7 @@ class DocType(BuyingController): from accounts.general_ledger import make_gl_entries - against_stock_account = self.get_default_account("stock_received_but_not_billed") + against_stock_account = self.get_company_default("stock_received_but_not_billed") total_valuation_amount = self.get_total_valuation_amount() gl_entries = self.get_gl_entries_for_stock(against_stock_account, total_valuation_amount) diff --git a/stock/doctype/stock_entry/stock_entry.js b/stock/doctype/stock_entry/stock_entry.js index 447f5035ab..dc57ec6340 100644 --- a/stock/doctype/stock_entry/stock_entry.js +++ b/stock/doctype/stock_entry/stock_entry.js @@ -33,9 +33,9 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ else account_for = "stock_adjustment_account"; this.frm.call({ - method: "controllers.accounts_controller.get_default_account", + method: "accounts.utils.get_company_default", args: { - "account_for": account_for, + "fieldname": account_for, "company": this.frm.doc.company }, callback: function(r) { diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index f54ce605a0..a4a3f9124a 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -176,11 +176,10 @@ class DocType(StockController): from accounts.general_ledger import make_gl_entries - cost_center = "Auto Inventory Accounting - %s" % (self.company_abbr,) total_valuation_amount = self.get_total_valuation_amount() gl_entries = self.get_gl_entries_for_stock(self.doc.expense_adjustment_account, - total_valuation_amount, cost_center=cost_center) + total_valuation_amount) if gl_entries: make_gl_entries(gl_entries, cancel=self.doc.docstatus == 2) diff --git a/stock/doctype/stock_reconciliation/stock_reconciliation.js b/stock/doctype/stock_reconciliation/stock_reconciliation.js index 372166eaac..e66ae3b2a3 100644 --- a/stock/doctype/stock_reconciliation/stock_reconciliation.js +++ b/stock/doctype/stock_reconciliation/stock_reconciliation.js @@ -27,9 +27,9 @@ erpnext.stock.StockReconciliation = erpnext.stock.StockController.extend({ if (sys_defaults.auto_inventory_accounting && !this.frm.doc.expense_account) { this.frm.call({ - method: "controllers.accounts_controller.get_default_account", + method: "accounts.utils.get_company_default", args: { - "account_for": "stock_adjustment_account", + "fieldname": "stock_adjustment_account", "company": this.frm.doc.company }, callback: function(r) { diff --git a/stock/doctype/stock_reconciliation/stock_reconciliation.py b/stock/doctype/stock_reconciliation/stock_reconciliation.py index ac0ab987f4..13c8ee4880 100644 --- a/stock/doctype/stock_reconciliation/stock_reconciliation.py +++ b/stock/doctype/stock_reconciliation/stock_reconciliation.py @@ -310,11 +310,9 @@ class DocType(StockController): msgprint(_("Please enter Expense Account"), raise_exception=1) from accounts.general_ledger import make_gl_entries - - cost_center = "Auto Inventory Accounting - %s" % (self.company_abbr,) - + gl_entries = self.get_gl_entries_for_stock(self.doc.expense_account, - self.doc.stock_value_difference, cost_center=cost_center) + self.doc.stock_value_difference) if gl_entries: make_gl_entries(gl_entries, cancel=self.doc.docstatus == 2) From 456465770bbea56d76e771a428509d02bcf45d4e Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 25 Mar 2013 11:07:12 +0530 Subject: [PATCH 2/8] aii: patch: update valuation rate in purchase invoice item --- patches/march_2013/p07_update_valuation_rate.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 patches/march_2013/p07_update_valuation_rate.py diff --git a/patches/march_2013/p07_update_valuation_rate.py b/patches/march_2013/p07_update_valuation_rate.py new file mode 100644 index 0000000000..0bce8a47ec --- /dev/null +++ b/patches/march_2013/p07_update_valuation_rate.py @@ -0,0 +1,13 @@ +import webnotes + +def execute(): + for purchase_invoice in webnotes.conn.sql("""select distinct parent + from `tabPurchase Invoice Item` where docstatus = 1 and ifnull(valuation_rate, 0)=0"""): + pi = webnotes.get_obj("Purchase Invoice", purchase_invoice) + pi.calculate_taxes_and_totals() + pi.update_raw_material_cost() + pi.update_valuation_rate("entries") + for item in pi.doclist.get({"parentfield": "entries"}): + webnotes.conn.set_value("Purchase Invoice Item", item.name, "valuation_rate", + item.valuation_rate) + \ No newline at end of file From 0931642c3aaaa03e7cbc875c4d89c62cc9d0580b Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 25 Mar 2013 11:54:42 +0530 Subject: [PATCH 3/8] fixes in backup_dropbox --- .../doctype/backup_manager/backup_dropbox.py | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/setup/doctype/backup_manager/backup_dropbox.py b/setup/doctype/backup_manager/backup_dropbox.py index 4e9efdf7ec..2901638c04 100644 --- a/setup/doctype/backup_manager/backup_dropbox.py +++ b/setup/doctype/backup_manager/backup_dropbox.py @@ -44,7 +44,10 @@ def dropbox_callback(oauth_token=None, not_approved=False): webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_secret", access_token.secret) webnotes.conn.set_value("Backup Manager", "Backup Manager", "dropbox_access_allowed", allowed) dropbox_client = client.DropboxClient(sess) - dropbox_client.file_create_folder("files") + try: + dropbox_client.file_create_folder("files") + except: + pass else: allowed = 0 @@ -94,7 +97,11 @@ def backup_to_dropbox(): upload_file_to_dropbox(filepath, "files", dropbox_client) def get_dropbox_session(): - from dropbox import session + try: + from dropbox import session + except: + webnotes.msgprint(_("Please install dropbox python module"), raise_exception=1) + try: from conf import dropbox_access_key, dropbox_secret_key except ImportError: @@ -107,16 +114,20 @@ def upload_file_to_dropbox(filename, folder, dropbox_client): from dropbox import rest size = os.stat(filename).st_size f = open(filename,'r') - if size > 4194304: + + # if max packet size reached, use chunked uploader + max_packet_size = 4194304 + + if size > max_packet_size: uploader = dropbox_client.get_chunked_uploader(f, size) while uploader.offset < size: try: uploader.upload_chunked() - uploader.finish(os.path.join(folder, os.path.basename(filename)), overwrite=True) + uploader.finish(folder + "/" + os.path.basename(filename), overwrite=True) except rest.ErrorResponse: pass else: - dropbox_client.put_file(os.path.join(folder, os.path.basename(filename)), f, overwrite=True) + dropbox_client.put_file(folder + "/" + os.path.basename(filename), f, overwrite=True) if __name__=="__main__": backup_to_dropbox() \ No newline at end of file From 557d858d89a751f403a555ffa2ed613bb2ada4ef Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 25 Mar 2013 18:28:16 +0530 Subject: [PATCH 4/8] aii: patches and default values fetching --- accounts/doctype/account/account.py | 10 ++- accounts/doctype/pos_setting/pos_setting.txt | 12 ++- .../doctype/sales_invoice/sales_invoice.py | 90 ++++++++++++------- .../sales_invoice_item/sales_invoice_item.txt | 16 +--- controllers/selling_controller.py | 2 +- patches/march_2013/p08_create_aii_accounts.py | 26 ++++++ selling/doctype/sales_common/sales_common.py | 69 ++++++++------ setup/doctype/company/company.py | 14 +-- setup/doctype/company/test_company.py | 2 +- stock/doctype/delivery_note/delivery_note.js | 2 +- stock/doctype/delivery_note/delivery_note.py | 7 +- .../delivery_note_item/delivery_note_item.txt | 9 +- stock/doctype/stock_entry/stock_entry.js | 2 +- 13 files changed, 166 insertions(+), 95 deletions(-) create mode 100644 patches/march_2013/p08_create_aii_accounts.py diff --git a/accounts/doctype/account/account.py b/accounts/doctype/account/account.py index 3cd131fc29..410994fed2 100644 --- a/accounts/doctype/account/account.py +++ b/accounts/doctype/account/account.py @@ -48,15 +48,17 @@ class DocType: from tabAccount where name =%s""", self.doc.parent_account) if not par: msgprint("Parent account does not exists", raise_exception=1) - elif par and par[0][0] == self.doc.name: + elif par[0][0] == self.doc.name: msgprint("You can not assign itself as parent account", raise_exception=1) - elif par and par[0][1] != 'Group': + elif par[0][1] != 'Group': msgprint("Parent account can not be a ledger", raise_exception=1) - elif par and self.doc.debit_or_credit and par[0][3] != self.doc.debit_or_credit: + elif self.doc.debit_or_credit and par[0][3] != self.doc.debit_or_credit: msgprint("You can not move a %s account under %s account" % (self.doc.debit_or_credit, par[0][3]), raise_exception=1) - elif par and not self.doc.is_pl_account: + + if not self.doc.is_pl_account: self.doc.is_pl_account = par[0][2] + if not self.doc.debit_or_credit: self.doc.debit_or_credit = par[0][3] def validate_max_root_accounts(self): diff --git a/accounts/doctype/pos_setting/pos_setting.txt b/accounts/doctype/pos_setting/pos_setting.txt index a91c44354e..a625ad8c0b 100755 --- a/accounts/doctype/pos_setting/pos_setting.txt +++ b/accounts/doctype/pos_setting/pos_setting.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-01-10 16:34:07", + "creation": "2013-01-24 11:03:29", "docstatus": 0, - "modified": "2013-01-22 16:55:20", + "modified": "2013-03-25 15:27:52", "modified_by": "Administrator", "owner": "Administrator" }, @@ -140,6 +140,14 @@ "options": "Account", "reqd": 1 }, + { + "doctype": "DocField", + "fieldname": "expense_account", + "fieldtype": "Link", + "label": "Expense Account", + "options": "Account", + "reqd": 1 + }, { "doctype": "DocField", "fieldname": "warehouse", diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py index 4b0f3b1608..15b136bf37 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.py +++ b/accounts/doctype/sales_invoice/sales_invoice.py @@ -27,8 +27,6 @@ from webnotes.model.bean import getlist from webnotes.model.code import get_obj from webnotes import _, msgprint -session = webnotes.session - month_map = {'Monthly': 1, 'Quarterly': 3, 'Half-yearly': 6, 'Yearly': 12} @@ -156,46 +154,57 @@ class DocType(SellingController): def set_pos_fields(self): """Set retail related fields from pos settings""" - pos = webnotes.conn.sql("select * from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company), as_dict=1) - if not pos: - pos = webnotes.conn.sql("select * from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % (self.doc.company), as_dict=1) + 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 = 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 and pos[0]['customer_account'] or '' + if not val: val = pos[0]['customer_account'] or '' + 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'] + lst = ['territory', 'naming_series', 'currency', 'charge', 'letter_head', 'tc_name', + 'price_list_name', 'company', 'select_print_heading', 'cash_bank_account'] for i in lst: - val = pos and pos[0][i] or '' - self.doc.fields[i] = val + self.doc.fields[i] = pos[0][i] or '' + self.set_pos_item_values() - val = pos and flt(pos[0]['conversion_rate']) or 0 - self.doc.conversion_rate = val + self.doc.conversion_rate = flt(pos[0]['conversion_rate']) or 0 #fetch terms - if self.doc.tc_name: self.get_tc_details() + if self.doc.tc_name: + self.get_tc_details() #fetch charges - if self.doc.charge: self.get_other_charges() + if self.doc.charge: + 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 = webnotes.conn.sql("select income_account, warehouse, cost_center from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company), as_dict=1) - if not dtl: - dtl = webnotes.conn.sql("select income_account, warehouse, cost_center from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % (self.doc.company), as_dict=1) + 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 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 - + 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""" @@ -276,15 +285,13 @@ class DocType(SellingController): for d in getlist(self.doclist, doctype): if d.item_code: item = webnotes.conn.get_value("Item", d.item_code, ["default_income_account", - "default_sales_cost_center", "purchase_account", "cost_center"], as_dict=True) + "default_sales_cost_center", "purchase_account"], as_dict=True) d.income_account = item['default_income_account'] or "" d.cost_center = item['default_sales_cost_center'] or "" if cint(webnotes.defaults.get_global_default("auto_inventory_accounting")) \ and cint(self.doc.is_pos) and cint(self.doc.update_stock): d.expense_account = item['purchase_account'] or "" - d.purchase_cost_center = item['cost_center'] or "" - def get_item_details(self, args=None): import json @@ -301,7 +308,6 @@ class DocType(SellingController): 'cost_center': doc.fields.get('cost_center'), 'warehouse': doc.fields.get('warehouse'), 'expense_account': doc.fields.get('expense_account'), - 'purchase_cost_center': doc.fields.get('purchase_cost_center') } ret = self.get_pos_details(arg) @@ -309,14 +315,27 @@ class DocType(SellingController): if not doc.fields.get(r): doc.fields[r] = ret[r] + @property + def pos_details(self): + if not hasattr(self, "_pos_details"): + dtl = webnotes.conn.sql("""select income_account, warehouse, cost_center, + expense_account 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 income_account, warehouse, cost_center, + expense_account from `tabPOS Setting` where ifnull(user,'') = '' + and company = %s""", self.doc.company, as_dict=1) + self._pos_details = dtl + + return self._pos_details def get_pos_details(self, args, ret = {}): if args['item_code'] and cint(self.doc.is_pos) == 1: - dtl = webnotes.conn.sql("select income_account, warehouse, cost_center from `tabPOS Setting` where user = '%s' and company = '%s'" % (session['user'], self.doc.company), as_dict=1) - if not dtl: - dtl = webnotes.conn.sql("select income_account, warehouse, cost_center from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % (self.doc.company), as_dict=1) + dtl = self.pos_details - item = webnotes.conn.sql("select default_income_account, default_sales_cost_center, default_warehouse from tabItem where name = '%s'" %(args['item_code']), as_dict=1) + 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')) @@ -326,9 +345,14 @@ class DocType(SellingController): ret['warehouse'] = item and item[0].get('default_warehouse') \ or (dtl and dtl[0].get('warehouse') or args.get('warehouse')) + + 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'])) + 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 return ret @@ -545,7 +569,7 @@ class DocType(SellingController): def get_warehouse(self): - w = webnotes.conn.sql("select warehouse from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (session['user'], self.doc.company)) + w = webnotes.conn.sql("select warehouse from `tabPOS Setting` where ifnull(user,'') = '%s' and company = '%s'" % (webnotes.session['user'], self.doc.company)) w = w and w[0][0] or '' if not w: ps = webnotes.conn.sql("select name, warehouse from `tabPOS Setting` where ifnull(user,'') = '' and company = '%s'" % self.doc.company) diff --git a/accounts/doctype/sales_invoice_item/sales_invoice_item.txt b/accounts/doctype/sales_invoice_item/sales_invoice_item.txt index 221359ce90..ca5fae49c3 100644 --- a/accounts/doctype/sales_invoice_item/sales_invoice_item.txt +++ b/accounts/doctype/sales_invoice_item/sales_invoice_item.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-03-07 11:42:55", + "creation": "2013-03-25 15:35:04", "docstatus": 0, - "modified": "2013-03-22 18:40:48", + "modified": "2013-03-25 15:35:23", "modified_by": "Administrator", "owner": "Administrator" }, @@ -215,6 +215,7 @@ "label": "Expense Account", "options": "Account", "print_hide": 1, + "read_only": 0, "width": "120px" }, { @@ -232,17 +233,6 @@ "reqd": 0, "width": "120px" }, - { - "doctype": "DocField", - "fieldname": "purchase_cost_center", - "fieldtype": "Link", - "hidden": 1, - "in_filter": 1, - "label": "Purchase Cost Center", - "options": "Cost Center", - "print_hide": 1, - "width": "120px" - }, { "doctype": "DocField", "fieldname": "serial_no", diff --git a/controllers/selling_controller.py b/controllers/selling_controller.py index ab002be801..f3fb47fc2a 100644 --- a/controllers/selling_controller.py +++ b/controllers/selling_controller.py @@ -65,4 +65,4 @@ class SellingController(StockController): def check_expense_account(self, item): if item.buying_amount and not item.expense_account: msgprint(_("""Expense account is mandatory for item: """) + item.item_code, - raise_exception=1) \ No newline at end of file + raise_exception=1) \ No newline at end of file diff --git a/patches/march_2013/p08_create_aii_accounts.py b/patches/march_2013/p08_create_aii_accounts.py new file mode 100644 index 0000000000..c39c206c84 --- /dev/null +++ b/patches/march_2013/p08_create_aii_accounts.py @@ -0,0 +1,26 @@ +import webnotes +def execute(): + accounts_to_add = [ + ["Stock Assets", "Current Assets", "Group", ""], + ["Stock In Hand", "Stock Assets", "Ledger", ""], + ["Stock Debit But Not Billed", "Stock Assets", "Ledger", ""], + ["Stock Expenses", "Direct Expenses", "Group", "Expense Account"], + ["Cost of Goods Sold", "Stock Expenses", "Ledger", "Expense Account"], + ["Stock Adjustment", "Stock Expenses", "Ledger", "Expense Account"], + ["Expenses Included In Valuation", "Stock Expenses", "Ledger", "Expense Account"], + ["Stock Liabilities", "Current Liabilities", "Group", ""], + ["Stock Received But Not Billed", "Stock Liabilities", "Ledger", ""], + ] + + for company, abbr in webnotes.conn.sql_list("""select name, abbr from `tabCompany`"""): + for account_name, parent_account_name, group_or_ledger, account_type in accounts_to_add: + if not webnotes.conn.exists("Account", "%s - %s" % (account_name, abbr)): + account = webnotes.bean({ + "doctype": "Account", + "account_name": account_name, + "parent_account": "%s - %s" % (parent_account_name, abbr), + "group_or_ledger": group_or_ledger, + "account_type": account_type, + "company": company + }) + account.insert() \ 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 fca96b8fa5..729013f053 100644 --- a/selling/doctype/sales_common/sales_common.py +++ b/selling/doctype/sales_common/sales_common.py @@ -127,29 +127,40 @@ class DocType(TransactionBase): if not obj.doc.price_list_name: msgprint("Please Select Price List before selecting Items") raise Exception - item = webnotes.conn.sql("select description, item_name, brand, item_group, stock_uom, default_warehouse, default_income_account, default_sales_cost_center, purchase_account, cost_center, description_html, barcode from `tabItem` where name = '%s' and (ifnull(end_of_life,'')='' or end_of_life > now() or end_of_life = '0000-00-00') and (is_sales_item = 'Yes' or is_service_item = 'Yes')" % (args['item_code']), as_dict=1) - tax = webnotes.conn.sql("select tax_type, tax_rate from `tabItem Tax` where parent = %s" , args['item_code']) + item = webnotes.conn.sql("""select description, item_name, brand, item_group, stock_uom, + default_warehouse, default_income_account, default_sales_cost_center, + purchase_account, description_html, barcode from `tabItem` + where name = %s and (ifnull(end_of_life,'')='' or end_of_life > now() + or end_of_life = '0000-00-00') and (is_sales_item = 'Yes' + or is_service_item = 'Yes')""", args['item_code'], as_dict=1) + tax = webnotes.conn.sql("""select tax_type, tax_rate from `tabItem Tax` + where parent = %s""", args['item_code']) t = {} for x in tax: t[x[0]] = flt(x[1]) ret = { - 'description' : item and item[0]['description_html'] or item[0]['description'], - 'barcode' : item and item[0]['barcode'] or '', - 'item_group' : item and item[0]['item_group'] or '', - 'item_name' : item and item[0]['item_name'] or '', - 'brand' : item and item[0]['brand'] or '', - 'stock_uom' : item and item[0]['stock_uom'] or '', - 'reserved_warehouse' : item and item[0]['default_warehouse'] or '', - 'warehouse' : item and item[0]['default_warehouse'] or args.get('warehouse'), - 'income_account' : item and item[0]['default_income_account'] or args.get('income_account'), - 'expense_account' : item and item[0]['purchase_account'] or args.get('expense_account'), - 'cost_center' : item and item[0]['default_sales_cost_center'] or args.get('cost_center'), - 'purchase_cost_center' : item and item[0]['cost_center'] or args.get('purchase_cost_center'), - 'qty' : 1.00, # this is done coz if item once fetched is fetched again thn its qty shld be reset to 1 - 'adj_rate' : 0, - 'amount' : 0, - 'export_amount' : 0, - 'item_tax_rate' : json.dumps(t), - 'batch_no' : '' + 'description': item and item[0]['description_html'] or \ + item[0]['description'], + 'barcode': item and item[0]['barcode'] or '', + 'item_group': item and item[0]['item_group'] or '', + 'item_name': item and item[0]['item_name'] or '', + 'brand': item and item[0]['brand'] or '', + 'stock_uom': item and item[0]['stock_uom'] or '', + 'reserved_warehouse': item and item[0]['default_warehouse'] or '', + 'warehouse': item and item[0]['default_warehouse'] or \ + args.get('warehouse'), + 'income_account': item and item[0]['default_income_account'] or \ + args.get('income_account'), + 'expense_account': item and item[0]['purchase_account'] or \ + args.get('expense_account'), + 'cost_center': item and item[0]['default_sales_cost_center'] or \ + args.get('cost_center'), + # this is done coz if item once fetched is fetched again than its qty shld be reset to 1 + 'qty': 1.00, + 'adj_rate': 0, + 'amount': 0, + 'export_amount': 0, + 'item_tax_rate': json.dumps(t), + 'batch_no': '' } if(obj.doc.price_list_name and item): #this is done to fetch the changed BASIC RATE and REF RATE based on PRICE LIST base_ref_rate = self.get_ref_rate(args['item_code'], obj.doc.price_list_name, obj.doc.price_list_currency, obj.doc.plc_conversion_rate) @@ -174,14 +185,18 @@ class DocType(TransactionBase): def get_item_defaults(self, args): - item = webnotes.conn.sql("""select default_warehouse, default_income_account, default_sales_cost_center from `tabItem` - where name = '%s' and (ifnull(end_of_life,'') = '' or end_of_life > now() or end_of_life = '0000-00-00') - and (is_sales_item = 'Yes' or is_service_item = 'Yes') """ % (args['item_code']), as_dict=1) + item = webnotes.conn.sql("""select default_warehouse, default_income_account, + default_sales_cost_center, purchase_account from `tabItem` where name = %s + and (ifnull(end_of_life,'') = '' or end_of_life > now() or end_of_life = '0000-00-00') + and (is_sales_item = 'Yes' or is_service_item = 'Yes') """, + (args['item_code']), as_dict=1) ret = { - 'reserved_warehouse' : item and item[0]['default_warehouse'] or '', - 'warehouse' : item and item[0]['default_warehouse'] or args.get('warehouse'), - 'income_account' : item and item[0]['default_income_account'] or args.get('income_account'), - 'cost_center' : item and item[0]['default_sales_cost_center'] or args.get('cost_center') + 'reserved_warehouse': item and item[0]['default_warehouse'] or '', + 'warehouse': item and item[0]['default_warehouse'] or args.get('warehouse'), + 'income_account': item and item[0]['default_income_account'] or \ + args.get('income_account'), + 'expense_account': item and item[0]['purchase_account'] or args.get('expense_account'), + 'cost_center': item and item[0]['default_sales_cost_center'] or args.get('cost_center'), } return ret diff --git a/setup/doctype/company/company.py b/setup/doctype/company/company.py index a2e56eb331..47b250d9c2 100644 --- a/setup/doctype/company/company.py +++ b/setup/doctype/company/company.py @@ -249,15 +249,17 @@ class DocType: def on_update(self): self.set_letter_head() - ac = sql("select name from tabAccount where company=%s and docstatus<2 limit 1", - self.doc.name) - if not ac: + + if not webnotes.conn.sql("""select name from tabAccount + where company=%s and docstatus<2 limit 1""", self.doc.name): self.create_default_accounts() - self.set_default_accounts() - cc = sql("select name from `tabCost Center` where cost_center_name = 'Root' and company_name = '%s'"%(self.doc.name)) - if not cc: + + if not webnotes.conn.sql("""select name from `tabCost Center` + where cost_center_name = 'Root' and company_name = %s""", self.doc.name): self.create_default_cost_center() + self.set_default_accounts() + if self.doc.default_currency: webnotes.conn.set_value("Currency", self.doc.default_currency, "enabled", 1) diff --git a/setup/doctype/company/test_company.py b/setup/doctype/company/test_company.py index fe793ffce4..e79bd07c1c 100644 --- a/setup/doctype/company/test_company.py +++ b/setup/doctype/company/test_company.py @@ -1,4 +1,4 @@ -test_ignore = ["Account"] +test_ignore = ["Account", "Cost Center"] test_records = [ [{ diff --git a/stock/doctype/delivery_note/delivery_note.js b/stock/doctype/delivery_note/delivery_note.js index 7e6031c6f9..c7feb1b88e 100644 --- a/stock/doctype/delivery_note/delivery_note.js +++ b/stock/doctype/delivery_note/delivery_note.js @@ -323,7 +323,7 @@ cur_frm.fields_dict['delivery_note_details'].grid.get_field('expense_account').g } // cost center -cur_frm.fields_dict["delivery_note_details"].grid.get_field("cost_center").get_query = function(doc) { +cur_frm.fields_dict.delivery_note_details.grid.get_field("cost_center").get_query = function(doc) { return { query: "accounts.utils.get_cost_center_list", filters: { company_name: doc.company} diff --git a/stock/doctype/delivery_note/delivery_note.py b/stock/doctype/delivery_note/delivery_note.py index 5e3c9e94fe..fce379efa5 100644 --- a/stock/doctype/delivery_note/delivery_note.py +++ b/stock/doctype/delivery_note/delivery_note.py @@ -85,8 +85,11 @@ class DocType(SellingController): obj = get_obj('Sales Common') for doc in self.doclist: 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')}; + arg = { + 'item_code':doc.fields.get('item_code'), + 'expense_account':doc.fields.get('expense_account'), + 'cost_center': doc.fields.get('cost_center'), + 'warehouse': doc.fields.get('warehouse')}; ret = obj.get_item_defaults(arg) for r in ret: if not doc.fields.get(r): diff --git a/stock/doctype/delivery_note_item/delivery_note_item.txt b/stock/doctype/delivery_note_item/delivery_note_item.txt index ffc19c36e1..1961e6cfa8 100644 --- a/stock/doctype/delivery_note_item/delivery_note_item.txt +++ b/stock/doctype/delivery_note_item/delivery_note_item.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-03-07 11:42:59", + "creation": "2013-03-25 11:55:16", "docstatus": 0, - "modified": "2013-03-22 18:43:10", + "modified": "2013-03-25 15:43:04", "modified_by": "Administrator", "owner": "Administrator" }, @@ -253,14 +253,15 @@ "no_copy": 1, "options": "Account", "print_hide": 1, + "read_only": 0, "width": "120px" }, { "doctype": "DocField", - "fieldname": "purchase_cost_center", + "fieldname": "cost_center", "fieldtype": "Link", "hidden": 1, - "label": "Purchase Cost Center", + "label": "Cost Center", "no_copy": 1, "options": "Cost Center", "print_hide": 1, diff --git a/stock/doctype/stock_entry/stock_entry.js b/stock/doctype/stock_entry/stock_entry.js index dc57ec6340..9b89d7859b 100644 --- a/stock/doctype/stock_entry/stock_entry.js +++ b/stock/doctype/stock_entry/stock_entry.js @@ -27,7 +27,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ if (sys_defaults.auto_inventory_accounting && !this.frm.doc.expense_adjustment_account) { if (this.frm.doc.purpose == "Sales Return") - account_for = "stock_delivered_but_not_billed"; + account_for = "stock_in_hand_account"; else if (this.frm.doc.purpose == "Purchase Return") account_for = "stock_received_but_not_billed"; else account_for = "stock_adjustment_account"; From 6dcee5a1f823a06fc26594f2c5faacca153b5c2d Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 26 Mar 2013 10:45:29 +0530 Subject: [PATCH 5/8] fixes in website utils --- public/js/website_utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/js/website_utils.js b/public/js/website_utils.js index a33eee04ba..d1b5ab7f20 100644 --- a/public/js/website_utils.js +++ b/public/js/website_utils.js @@ -127,7 +127,7 @@ function getCookies() { var parts = cookie.split(/=/, 2), name = decodeURIComponent(parts[0].trimLeft()), value = parts.length > 1 ? decodeURIComponent(parts[1].trimRight()) : null; - if(value.charAt(0)==='"') { + if(value && value.charAt(0)==='"') { value = value.substr(1, value.length-2); } cookies[name] = value; From fc33ef6bfbd117c078efb49af8b1f1582e0c8f38 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 26 Mar 2013 12:13:14 +0530 Subject: [PATCH 6/8] fixes in purchase invoice --- accounts/doctype/purchase_invoice/purchase_invoice.py | 4 +++- accounts/doctype/sales_invoice/sales_invoice.py | 1 - setup/doctype/email_settings/email_settings.txt | 8 +++----- stock/doctype/delivery_note/delivery_note.py | 1 - stock/doctype/stock_entry/stock_entry.py | 2 -- 5 files changed, 6 insertions(+), 10 deletions(-) diff --git a/accounts/doctype/purchase_invoice/purchase_invoice.py b/accounts/doctype/purchase_invoice/purchase_invoice.py index fb9977c486..85fdb47866 100644 --- a/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -306,7 +306,9 @@ class DocType(BuyingController): def set_against_expense_account(self): auto_inventory_accounting = \ cint(webnotes.defaults.get_global_default("auto_inventory_accounting")) - stock_not_billed_account = self.get_company_default("stock_received_but_not_billed") + + if auto_inventory_accounting: + stock_not_billed_account = self.get_company_default("stock_received_but_not_billed") against_accounts = [] for item in self.doclist.get({"parentfield": "entries"}): diff --git a/accounts/doctype/sales_invoice/sales_invoice.py b/accounts/doctype/sales_invoice/sales_invoice.py index a46e299879..a8f76856e2 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.py +++ b/accounts/doctype/sales_invoice/sales_invoice.py @@ -641,7 +641,6 @@ class DocType(SellingController): self.values.append({ 'item_code' : d['item_code'], 'warehouse' : wh, - 'transaction_date' : getdate(self.doc.modified).strftime('%Y-%m-%d'), 'posting_date' : self.doc.posting_date, 'posting_time' : self.doc.posting_time, 'voucher_type' : 'Sales Invoice', diff --git a/setup/doctype/email_settings/email_settings.txt b/setup/doctype/email_settings/email_settings.txt index 1de2c93045..5547c2e74c 100644 --- a/setup/doctype/email_settings/email_settings.txt +++ b/setup/doctype/email_settings/email_settings.txt @@ -1,10 +1,10 @@ [ { - "creation": "2012-07-12 23:29:44", + "creation": "2013-03-25 17:53:21", "docstatus": 0, - "modified": "2013-03-25 17:32:05", + "modified": "2013-03-25 18:41:27", "modified_by": "Administrator", - "owner": "harshada@webnotestech.com" + "owner": "Administrator" }, { "allow_copy": 1, @@ -34,9 +34,7 @@ "parenttype": "DocType", "permlevel": 0, "read": 1, - "report": 0, "role": "System Manager", - "submit": 0, "write": 1 }, { diff --git a/stock/doctype/delivery_note/delivery_note.py b/stock/doctype/delivery_note/delivery_note.py index 16d1795fb6..ded689734f 100644 --- a/stock/doctype/delivery_note/delivery_note.py +++ b/stock/doctype/delivery_note/delivery_note.py @@ -377,7 +377,6 @@ class DocType(SellingController): self.values.append({ 'item_code' : d['item_code'], 'warehouse' : wh, - 'transaction_date' : getdate(self.doc.modified).strftime('%Y-%m-%d'), 'posting_date' : self.doc.posting_date, 'posting_time' : self.doc.posting_time, 'voucher_type' : 'Delivery Note', diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index c3739ced43..d89d95b272 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -776,8 +776,6 @@ def make_return_jv(stock_entry): from accounts.utils import get_balance_on for r in result: - if not r.get("account"): - print result jv_list.append({ "__islocal": 1, "doctype": "Journal Voucher Detail", From 9f91053201ad1e95a5bd6d48c30956078a2a7605 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 26 Mar 2013 12:25:11 +0530 Subject: [PATCH 7/8] patch to set user type as System User if user has a role and if previous user type is Partner --- patches/march_2013/p09_unset_user_type_partner.py | 6 ++++++ patches/patch_list.py | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 patches/march_2013/p09_unset_user_type_partner.py diff --git a/patches/march_2013/p09_unset_user_type_partner.py b/patches/march_2013/p09_unset_user_type_partner.py new file mode 100644 index 0000000000..cc5cdce5c2 --- /dev/null +++ b/patches/march_2013/p09_unset_user_type_partner.py @@ -0,0 +1,6 @@ +import webnotes + +def execute(): + webnotes.conn.sql("""update `tabProfile` set user_type='System User' + where user_type='Partner' and exists (select name from `tabUserRole` + where parent=`tabProfile`.name)""") \ No newline at end of file diff --git a/patches/patch_list.py b/patches/patch_list.py index 00dd5da200..0c5427b52b 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -217,5 +217,6 @@ patch_list = [ "execute:webnotes.bean('Global Defaults').save()", "patches.march_2013.p07_update_project_in_stock_ledger", "execute:webnotes.bean('Style Settings').save() #2013-03-25", - "execute:webnotes.conn.set_value('Email Settings', None, 'send_print_in_body_and_attachment', 1)" + "execute:webnotes.conn.set_value('Email Settings', None, 'send_print_in_body_and_attachment', 1)", + "patches.march_2013.p09_unset_user_type_partner", ] \ No newline at end of file From acec0227c5b9e9a629ee614642ab03d11c657f9e Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 26 Mar 2013 12:33:43 +0530 Subject: [PATCH 8/8] fixes in stock entry --- .../Purchase Order-Purchase Receipt.txt | 144 ++++++++---------- stock/doctype/stock_entry/stock_entry.py | 6 + stock/doctype/stock_entry/stock_entry.txt | 22 +-- stock/doctype/stock_entry/test_stock_entry.py | 2 +- utilities/transaction_base.py | 3 +- 5 files changed, 83 insertions(+), 94 deletions(-) diff --git a/stock/DocType Mapper/Purchase Order-Purchase Receipt/Purchase Order-Purchase Receipt.txt b/stock/DocType Mapper/Purchase Order-Purchase Receipt/Purchase Order-Purchase Receipt.txt index 8d7fab1235..0833aaa849 100644 --- a/stock/DocType Mapper/Purchase Order-Purchase Receipt/Purchase Order-Purchase Receipt.txt +++ b/stock/DocType Mapper/Purchase Order-Purchase Receipt/Purchase Order-Purchase Receipt.txt @@ -1,189 +1,169 @@ [ { - "owner": "Administrator", + "creation": "2013-02-22 01:28:05", "docstatus": 0, - "creation": "2010-08-08 17:09:35", + "modified": "2013-03-26 07:58:20", "modified_by": "Administrator", - "modified": "2012-04-02 14:03:39" + "owner": "Administrator" }, { + "doctype": "Table Mapper Detail", "name": "__common__", "parent": "Purchase Order-Purchase Receipt", - "doctype": "Table Mapper Detail", - "parenttype": "DocType Mapper", - "parentfield": "table_mapper_details" + "parentfield": "table_mapper_details", + "parenttype": "DocType Mapper" }, { + "doctype": "Field Mapper Detail", "map": "Yes", "name": "__common__", "parent": "Purchase Order-Purchase Receipt", - "doctype": "Field Mapper Detail", - "parenttype": "DocType Mapper", - "parentfield": "field_mapper_details" + "parentfield": "field_mapper_details", + "parenttype": "DocType Mapper" }, { - "name": "__common__", - "to_doctype": "Purchase Receipt", - "module": "Stock", "doctype": "DocType Mapper", + "from_doctype": "Purchase Order", + "module": "Stock", + "name": "__common__", "ref_doc_submitted": 1, - "from_doctype": "Purchase Order" + "to_doctype": "Purchase Receipt" }, { - "name": "Purchase Order-Purchase Receipt", - "doctype": "DocType Mapper" + "doctype": "DocType Mapper", + "name": "Purchase Order-Purchase Receipt" }, { - "match_id": 0, - "to_field": "supplier", + "checking_operator": "=", "doctype": "Field Mapper Detail", "from_field": "supplier", - "checking_operator": "=" + "match_id": 0, + "to_field": "supplier" }, { - "match_id": 0, - "to_field": "company", + "checking_operator": "=", "doctype": "Field Mapper Detail", "from_field": "company", - "checking_operator": "=" + "match_id": 0, + "to_field": "company" }, { - "match_id": 0, - "to_field": "currency", + "checking_operator": "=", "doctype": "Field Mapper Detail", "from_field": "currency", - "checking_operator": "=" + "match_id": 0, + "to_field": "currency" }, { - "to_field": "prevdoc_detail_docname", "doctype": "Field Mapper Detail", + "from_field": "name", "match_id": 1, - "from_field": "name" + "to_field": "prevdoc_detail_docname" }, { - "to_field": "prevdoc_docname", "doctype": "Field Mapper Detail", + "from_field": "parent", "match_id": 1, - "from_field": "parent" + "to_field": "prevdoc_docname" }, { - "to_field": "prevdoc_doctype", "doctype": "Field Mapper Detail", + "from_field": "parenttype", "match_id": 1, - "from_field": "parenttype" + "to_field": "prevdoc_doctype" }, { - "match_id": 1, - "to_field": "item_code", + "checking_operator": "=", "doctype": "Field Mapper Detail", "from_field": "item_code", - "checking_operator": "=" - }, - { - "to_field": "received_qty", - "doctype": "Field Mapper Detail", "match_id": 1, - "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) " + "to_field": "item_code" }, { - "to_field": "qty", "doctype": "Field Mapper Detail", + "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) ", "match_id": 1, - "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) " + "to_field": "received_qty" }, { - "to_field": "stock_qty", "doctype": "Field Mapper Detail", + "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) ", "match_id": 1, - "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) * flt(obj.conversion_factor)" + "to_field": "qty" }, { - "to_field": "import_amount", "doctype": "Field Mapper Detail", + "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) * flt(obj.conversion_factor)", "match_id": 1, - "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) * flt(obj.import_rate)" + "to_field": "stock_qty" }, { - "to_field": "amount", "doctype": "Field Mapper Detail", + "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) * flt(obj.import_rate)", "match_id": 1, - "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) * flt(obj.purchase_rate)" + "to_field": "import_amount" }, { - "to_field": "schedule_date", "doctype": "Field Mapper Detail", + "from_field": "eval:(flt(obj.qty) - flt(obj.received_qty)) * flt(obj.purchase_rate)", "match_id": 1, - "from_field": "schedule_date" + "to_field": "amount" }, { - "to_field": "net_total", "doctype": "Field Mapper Detail", + "from_field": "schedule_date", + "match_id": 1, + "to_field": "schedule_date" + }, + { + "doctype": "Field Mapper Detail", + "from_field": "net_total", "match_id": 0, - "from_field": "net_total" + "to_field": "net_total" }, { - "to_field": "grand_total", "doctype": "Field Mapper Detail", + "from_field": "grand_total", "match_id": 0, - "from_field": "grand_total" + "to_field": "grand_total" }, { - "to_field": "total_tax", "doctype": "Field Mapper Detail", + "from_field": "total_tax", "match_id": 0, - "from_field": "total_tax" + "to_field": "total_tax" }, { - "to_field": "conversion_rate", "doctype": "Field Mapper Detail", + "from_field": "conversion_rate", "match_id": 0, - "from_field": "conversion_rate" + "to_field": "conversion_rate" }, { - "reference_key": "prevdoc_detail_docname", - "match_id": 1, - "reference_doctype_key": "prevdoc_doctype", - "to_field": "purchase_receipt_details", "doctype": "Table Mapper Detail", "from_field": "po_details", "from_table": "Purchase Order Item", + "match_id": 1, + "reference_doctype_key": "prevdoc_doctype", + "reference_key": "prevdoc_detail_docname", + "to_field": "purchase_receipt_details", "to_table": "Purchase Receipt Item", "validation_logic": "docstatus=1 and qty > ifnull(received_qty,0)" }, { - "reference_key": "prevdoc_detail_docname", - "match_id": 1, - "reference_doctype_key": "prevdoc_doctype", - "to_field": "purchase_receipt_details", - "doctype": "Table Mapper Detail", - "from_field": "po_details", - "from_table": "Purchase Order Item", - "to_table": "Purchase Receipt Item", - "validation_logic": "docstatus=1 and qty > ifnull(received_qty,0)" - }, - { - "reference_key": "prevdoc_docname", - "match_id": 0, "doctype": "Table Mapper Detail", "from_table": "Purchase Order", + "match_id": 0, + "reference_key": "prevdoc_docname", "to_table": "Purchase Receipt", "validation_logic": "docstatus = 1" }, { - "match_id": 2, - "to_field": "purchase_tax_details", "doctype": "Table Mapper Detail", "from_field": "purchase_tax_details", "from_table": "Purchase Taxes and Charges", - "to_table": "Purchase Taxes and Charges", - "validation_logic": "docstatus = 1" - }, - { "match_id": 2, "to_field": "purchase_tax_details", - "doctype": "Table Mapper Detail", - "from_field": "purchase_tax_details", - "from_table": "Purchase Taxes and Charges", "to_table": "Purchase Taxes and Charges", "validation_logic": "docstatus = 1" } diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index d89d95b272..c437135ad6 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -55,6 +55,7 @@ class DocType(StockController): self.validate_finished_goods() self.validate_return_reference_doc() self.validate_with_material_request() + self.validate_fiscal_year() def on_submit(self): self.update_serial_no(1) @@ -68,6 +69,11 @@ class DocType(StockController): self.update_production_order(0) self.make_gl_entries() + def validate_fiscal_year(self): + import accounts.utils + accounts.utils.validate_fiscal_year(self.doc.posting_date, self.doc.fiscal_year, + self.meta.get_label("posting_date")) + def validate_purpose(self): valid_purposes = ["Material Issue", "Material Receipt", "Material Transfer", "Manufacture/Repack", "Subcontract", "Sales Return", "Purchase Return"] diff --git a/stock/doctype/stock_entry/stock_entry.txt b/stock/doctype/stock_entry/stock_entry.txt index df5b613baf..91f9bb4fc0 100644 --- a/stock/doctype/stock_entry/stock_entry.txt +++ b/stock/doctype/stock_entry/stock_entry.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-03-11 12:34:40", + "creation": "2013-03-26 06:51:17", "docstatus": 0, - "modified": "2013-03-19 17:48:29", + "modified": "2013-03-26 07:24:53", "modified_by": "Administrator", "owner": "Administrator" }, @@ -542,6 +542,16 @@ "reqd": 0, "search_index": 0 }, + { + "doctype": "DocField", + "fieldname": "fiscal_year", + "fieldtype": "Select", + "in_filter": 0, + "label": "Fiscal Year", + "options": "link:Fiscal Year", + "print_hide": 1, + "reqd": 1 + }, { "allow_on_submit": 0, "doctype": "DocField", @@ -610,13 +620,5 @@ { "doctype": "DocPerm", "role": "Manufacturing User" - }, - { - "doctype": "DocPerm", - "role": "Manufacturing Manager" - }, - { - "doctype": "DocPerm", - "role": "Material Manager" } ] \ No newline at end of file diff --git a/stock/doctype/stock_entry/test_stock_entry.py b/stock/doctype/stock_entry/test_stock_entry.py index 25018930dd..3f8012a726 100644 --- a/stock/doctype/stock_entry/test_stock_entry.py +++ b/stock/doctype/stock_entry/test_stock_entry.py @@ -490,7 +490,7 @@ class TestStockEntry(unittest.TestCase): def test_make_return_jv_for_purchase_receipt(self): se, pr_name = self.test_purchase_receipt_return() self._test_purchase_return_jv(se) - + se, pr_name = self._test_purchase_return_return_against_purchase_order() self._test_purchase_return_jv(se) diff --git a/utilities/transaction_base.py b/utilities/transaction_base.py index 2dc8c6a2d7..c43a456687 100644 --- a/utilities/transaction_base.py +++ b/utilities/transaction_base.py @@ -250,4 +250,5 @@ class TransactionBase(DocListController): def validate_posting_time(self): if not self.doc.posting_time: - self.doc.posting_time = now_datetime().strftime('%H:%M:%S') \ No newline at end of file + self.doc.posting_time = now_datetime().strftime('%H:%M:%S') + \ No newline at end of file