From 71bed3116fb45cb1be0abdb97187e9cfcf62ca1c Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 13 Mar 2013 12:57:04 +0530 Subject: [PATCH 01/19] working on merging sales purchase return into stock entry --- .../doctype/pos_setting/test_pos_setting.py | 14 ++ .../doctype/sales_invoice/sales_invoice.py | 6 +- .../doctype/sales_invoice/sales_invoice.txt | 5 +- .../sales_invoice/test_sales_invoice.py | 2 +- .../march_2013/p04_pos_update_stock_check.py | 18 +++ patches/patch_list.py | 1 + .../global_defaults/global_defaults.txt | 11 +- stock/doctype/bin/bin.py | 6 +- stock/doctype/stock_entry/stock_entry.js | 72 +++++++-- stock/doctype/stock_entry/stock_entry.py | 142 +++++++++++++++--- stock/doctype/stock_entry/test_stock_entry.py | 126 +++++++++++++++- stock/doctype/stock_ledger/stock_ledger.py | 3 +- .../stock_ledger_entry/stock_ledger_entry.py | 2 +- stock/stock_ledger.py | 5 +- 14 files changed, 365 insertions(+), 48 deletions(-) create mode 100644 accounts/doctype/pos_setting/test_pos_setting.py create mode 100644 patches/march_2013/p04_pos_update_stock_check.py diff --git a/accounts/doctype/pos_setting/test_pos_setting.py b/accounts/doctype/pos_setting/test_pos_setting.py new file mode 100644 index 0000000000..2c45c4dce8 --- /dev/null +++ b/accounts/doctype/pos_setting/test_pos_setting.py @@ -0,0 +1,14 @@ +test_records = [ + [{ + "doctype": "POS Setting", + "name": "_Test POS Setting", + "currency": "INR", + "conversion_rate": 1.0, + "price_list_name": "_Test Price List", + "company": "_Test Company", + "warehouse": "_Test Warehouse", + "cash_bank_account": "_Test Account Bank Account - _TC", + "income_account": "Sales - _TC", + "cost_center": "_Test Cost Center - _TC", + }] +] \ 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 de3ee95897..0271a5855e 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.py +++ b/accounts/doctype/sales_invoice/sales_invoice.py @@ -47,6 +47,7 @@ class DocType(SellingController): def validate(self): super(DocType, self).validate() + self.validate_posting_time() self.so_dn_required() self.validate_proj_cust() sales_com_obj = get_obj('Sales Common') @@ -636,10 +637,9 @@ class DocType(SellingController): # Reduce actual qty from warehouse self.make_sl_entry( d, d['warehouse'], - flt(d['qty']) , 0, update_stock) - + get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values) - - + def get_actual_qty(self,args): args = eval(args) actual_qty = webnotes.conn.sql("select actual_qty from `tabBin` where item_code = '%s' and warehouse = '%s'" % (args['item_code'], args['warehouse']), as_dict=1) diff --git a/accounts/doctype/sales_invoice/sales_invoice.txt b/accounts/doctype/sales_invoice/sales_invoice.txt index c7c8fbac71..35710b4d49 100644 --- a/accounts/doctype/sales_invoice/sales_invoice.txt +++ b/accounts/doctype/sales_invoice/sales_invoice.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-01-29 17:54:09", + "creation": "2013-03-12 11:56:25", "docstatus": 0, - "modified": "2013-01-29 18:22:52", + "modified": "2013-03-12 14:31:24", "modified_by": "Administrator", "owner": "Administrator" }, @@ -77,7 +77,6 @@ "print_hide": 1 }, { - "default": "1", "depends_on": "eval:doc.is_pos==1", "doctype": "DocField", "fieldname": "update_stock", diff --git a/accounts/doctype/sales_invoice/test_sales_invoice.py b/accounts/doctype/sales_invoice/test_sales_invoice.py index 84eddea218..91c0622cee 100644 --- a/accounts/doctype/sales_invoice/test_sales_invoice.py +++ b/accounts/doctype/sales_invoice/test_sales_invoice.py @@ -297,7 +297,7 @@ class TestSalesInvoice(unittest.TestCase): ]) ps.insert() -test_dependencies = ["Journal Voucher"] +test_dependencies = ["Journal Voucher", "POS Setting"] test_records = [ [ diff --git a/patches/march_2013/p04_pos_update_stock_check.py b/patches/march_2013/p04_pos_update_stock_check.py new file mode 100644 index 0000000000..da48efe155 --- /dev/null +++ b/patches/march_2013/p04_pos_update_stock_check.py @@ -0,0 +1,18 @@ +import webnotes + +def execute(): + from webnotes.utils import cint + webnotes.reload_doc("setup", "doctype", "global_defaults") + + doctype_list = webnotes.get_doctype("Sales Invoice") + update_stock_df = doctype_list.get_field("update_stock") + + global_defaults = webnotes.bean("Global Defaults", "Global Defaults") + global_defaults.doc.update_stock = cint(update_stock_df.default) + global_defaults.save() + + webnotes.conn.sql("""delete from `tabProperty Setter` + where doc_type='Sales Invoice' and doctype_or_field='DocField' + and field_name='update_stock' and property='default'""") + + webnotes.reload_doc("accounts", "doctype", "sales_invoice") \ No newline at end of file diff --git a/patches/patch_list.py b/patches/patch_list.py index 5a504f8a51..f27ed31f0a 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -213,4 +213,5 @@ patch_list = [ "patches.march_2013.p03_rename_blog_to_blog_post", "execute:webnotes.bean('Style Settings', 'Style Settings').save()", "execute:webnotes.reload_doc('hr', 'search_criteria', 'monthly_attendance_details')", + "patches.march_2013.p04_pos_update_stock_check", ] \ No newline at end of file diff --git a/setup/doctype/global_defaults/global_defaults.txt b/setup/doctype/global_defaults/global_defaults.txt index 960da7e231..a55c6c0cdc 100644 --- a/setup/doctype/global_defaults/global_defaults.txt +++ b/setup/doctype/global_defaults/global_defaults.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-02-19 12:28:27", + "creation": "2013-03-08 15:37:09", "docstatus": 0, - "modified": "2013-02-20 14:09:00", + "modified": "2013-03-12 18:48:53", "modified_by": "Administrator", "owner": "Administrator" }, @@ -249,6 +249,13 @@ "fieldname": "column_break4", "fieldtype": "Column Break" }, + { + "description": "If checked, then in POS Sales Invoice, Update Stock gets checked by default", + "doctype": "DocField", + "fieldname": "update_stock", + "fieldtype": "Check", + "label": "Update Stock when using POS Sales Invoice" + }, { "doctype": "DocField", "fieldname": "account_info", diff --git a/stock/doctype/bin/bin.py b/stock/doctype/bin/bin.py index 37ecf85d2c..e1bc6bd20a 100644 --- a/stock/doctype/bin/bin.py +++ b/stock/doctype/bin/bin.py @@ -70,7 +70,7 @@ class DocType: "posting_date": args.get("posting_date"), "posting_time": args.get("posting_time") }) - + def update_qty(self, args): # update the stock values (for current quantities) self.doc.actual_qty = flt(self.doc.actual_qty) + flt(args.get("actual_qty")) @@ -83,11 +83,11 @@ class DocType: flt(self.doc.indented_qty) + flt(self.doc.planned_qty) - flt(self.doc.reserved_qty) self.doc.save() - + 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")) - + def get_first_sle(self): sle = sql(""" select * from `tabStock Ledger Entry` diff --git a/stock/doctype/stock_entry/stock_entry.js b/stock/doctype/stock_entry/stock_entry.js index ba1f64802a..010b27040d 100644 --- a/stock/doctype/stock_entry/stock_entry.js +++ b/stock/doctype/stock_entry/stock_entry.js @@ -18,6 +18,39 @@ wn.require("public/app/js/controllers/stock_controller.js"); wn.provide("erpnext.stock"); erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ + setup: function() { + var me = this; + + this.frm.fields_dict.delivery_note_no.get_query = function() { + return { query: "stock.doctype.stock_entry.stock_entry.query_sales_return_doc" }; + }; + + this.frm.fields_dict.sales_invoice_no.get_query = + this.frm.fields_dict.delivery_note_no.get_query; + + this.frm.fields_dict.purchase_receipt_no.get_query = function() { + return { query: "stock.doctype.stock_entry.stock_entry.query_purchase_return_doc" }; + }; + + this.frm.fields_dict.mtn_details.grid.get_field('item_code').get_query = function() { + if(in_list(["Sales Return", "Purchase Return"], me.frm.doc.purpose) && + me.get_doctype_docname()) { + return { + query: "stock.doctype.stock_entry.stock_entry.query_return_item", + filters: { + purpose: me.frm.doc.purpose, + delivery_note_no: me.frm.doc.delivery_note_no, + sales_invoice_no: me.frm.doc.sales_invoice_no, + purchase_receipt_no: me.frm.doc.purchase_receipt_no + } + }; + } else { + return erpnext.queries.item({is_stock_item: "Yes"}); + } + }; + + }, + onload_post_render: function() { if(this.frm.doc.__islocal && (this.frm.doc.production_order || this.frm.doc.bom_no) && !getchildren('Stock Entry Detail', this.frm.doc.name, 'mtn_details').length) { @@ -80,6 +113,36 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ toggle_enable_bom: function() { this.frm.toggle_enable("bom_no", !this.frm.doc.production_order); }, + + get_doctype_docname: function() { + if(this.frm.doc.purpose === "Sales Return") { + if(this.frm.doc.delivery_note_no && this.frm.doc.sales_invoice_no) { + // both specified + msgprint(wn._("You can not enter both Delivery Note No and Sales Invoice No. \ + Please enter any one.")); + + } else if(!(this.frm.doc.delivery_note_no || this.frm.doc.sales_invoice_no)) { + // none specified + msgprint(wn._("Please enter Delivery Note No or Sales Invoice No to proceed")); + + } else if(this.frm.doc.delivery_note_no) { + return {doctype: "Delivery Note", docname: this.frm.doc.delivery_note_no}; + + } else if(this.frm.doc.sales_invoice_no) { + return {doctype: "Sales Invoice", docname: this.frm.doc.sales_invoice_no}; + + } + } else if(this.frm.doc.purpose === "Purchase Return") { + if(this.frm.doc.purchase_receipt_no) { + return {doctype: "Purchase Receipt", docname: this.frm.doc.purchase_receipt_no}; + + } else { + // not specified + msgprint(wn._("Please enter Purchase Receipt No to proceed")); + + } + } + }, }); @@ -140,15 +203,6 @@ cur_frm.cscript.purpose = function(doc, cdt, cdn) { cur_frm.cscript.toggle_related_fields(doc, cdt, cdn); } -// item code - only if quantity present in source warehosue -var fld = cur_frm.fields_dict['mtn_details'].grid.get_field('item_code'); -fld.query_description = "If Source Warehouse is selected, items with existing stock \ - for that warehouse will be selected"; - -fld.get_query = function() { - return erpnext.queries.item({is_stock_item: "Yes"}); -} - // copy over source and target warehouses cur_frm.fields_dict['mtn_details'].grid.onrowadd = function(doc, cdt, cdn){ var d = locals[cdt][cdn]; diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index 74b71d97b3..d987fa7c5f 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -26,8 +26,9 @@ from stock.utils import get_incoming_rate from stock.stock_ledger import get_previous_sle import json - sql = webnotes.conn.sql + +class NotUpdateStockError(webnotes.ValidationError): pass from controllers.accounts_controller import AccountsController @@ -38,6 +39,7 @@ class DocType(AccountsController): self.fname = 'mtn_details' def validate(self): + self.validate_posting_time() self.validate_purpose() self.validate_serial_nos() @@ -237,26 +239,54 @@ class DocType(AccountsController): or update the Quantity manually."), raise_exception=1) def validate_return_reference_doc(self): - """ validate item with reference doc""" - ref_doctype = ref_docname = "" - if self.doc.purpose == "Sales Return" and \ - (self.doc.delivery_note_no or self.doc.sales_invoice_no): - ref_doctype = self.doc.delivery_note_no and "Delivery Note" or "Sales Invoice" - ref_docname = self.doc.delivery_note_no or self.doc.sales_invoice_no - elif self.doc.purpose == "Purchase Return" and self.doc.purchase_receipt_no: - ref_doctype = "Purchase Receipt" - ref_docname = self.doc.purchase_receipt_no + """validate item with reference doc""" + ref_doclist = parentfields = None + + # get ref_doclist + if self.doc.purpose in return_map: + for fieldname, val in return_map[self.doc.purpose].items(): + if self.doc.fields.get(fieldname): + ref_doclist = webnotes.get_doclist(val[0], self.doc.fields[fieldname]) + parentfields = val[1] + + if ref_doclist: + # validate docstatus + if ref_doclist[0].docstatus != 1: + webnotes.msgprint(_(ref_doclist[0].doctype) + ' "' + ref_doclist[0].name + '": ' + + _("Status should be Submitted"), raise_exception=webnotes.InvalidStatusError) + + + # update stock check + if ref_doclist[0].doctype == "Sales Invoice" and (cint(ref_doclist[0].is_pos) != 1 \ + or cint(ref_doclist[0].update_stock) != 1): + webnotes.msgprint(_(ref_doclist[0].doctype) + ' "' + ref_doclist[0].name + '": ' + + _("Is POS and Update Stock should be checked."), + raise_exception=NotUpdateStockError) + + # posting date check + ref_posting_datetime = "%s %s" % (cstr(ref_doclist[0].posting_date), + cstr(ref_doclist[0].posting_time)) + this_posting_datetime = "%s %s" % (cstr(self.doc.posting_date), + cstr(self.doc.posting_time)) + if this_posting_datetime < ref_posting_datetime: + from webnotes.utils.dateutils import datetime_in_user_format + webnotes.msgprint(_("Posting Date Time cannot be before") + + ": " + datetime_in_user_format(ref_posting_datetime), + raise_exception=True) + + stock_items = get_stock_items_for_return(ref_doclist, parentfields) - if ref_doctype and ref_docname: for item in self.doclist.get({"parentfield": "mtn_details"}): - ref_exists = webnotes.conn.sql("""select name from `tab%s` - where parent = %s and item_code = %s and docstatus=1""" % - (ref_doctype + " Item", '%s', '%s'), (ref_docname, item.item_code)) - - if not ref_exists: - msgprint(_("Item: '") + item.item_code + _("' does not exists in ") + - ref_doctype + ": " + ref_docname, raise_exception=1) - + # validate if item exists in the ref doclist and that it is a stock item + if item.item_code not in stock_items: + msgprint(_("Item") + ': "' + item.item_code + _("\" does not exist in ") + + ref_doclist[0].doctype + ": " + ref_doclist[0].name, + raise_exception=webnotes.DoesNotExistError) + + # validate quantity <= ref item's qty + ref_item = ref_doclist.getone({"item_code": item.item_code}) + self.validate_value("transfer_qty", "<=", ref_item.qty, item) + def update_serial_no(self, is_submit): """Create / Update Serial No""" from stock.utils import get_valid_serial_nos @@ -288,6 +318,7 @@ class DocType(AccountsController): self.add_to_values(d, cstr(d.s_warehouse), -flt(d.transfer_qty), is_cancelled) if cstr(d.t_warehouse): self.add_to_values(d, cstr(d.t_warehouse), flt(d.transfer_qty), is_cancelled) + get_obj('Stock Ledger', 'Stock Ledger').update_stock(self.values, self.doc.amended_from and 'Yes' or 'No') @@ -607,4 +638,75 @@ def get_production_order_details(production_order): result = webnotes.conn.sql("""select bom_no, ifnull(qty, 0) - ifnull(produced_qty, 0) as fg_completed_qty, use_multi_level_bom from `tabProduction Order` where name = %s""", production_order, as_dict=1) - return result and result[0] or {} \ No newline at end of file + return result and result[0] or {} + +def query_sales_return_doc(doctype, txt, searchfield, start, page_len, filters): + conditions = "" + if doctype == "Sales Invoice": + conditions = "and is_pos=1 and update_stock=1" + + return webnotes.conn.sql("""select name, customer, customer_name + from `tab%s` where docstatus = 1 + and (`%s` like %%(txt)s or `customer` like %%(txt)s) %s + order by name, customer, customer_name + limit %s""" % (doctype, searchfield, conditions, "%(start)s, %(page_len)s"), + {"txt": "%%%s%%" % txt, "start": start, "page_len": page_len}, as_list=True) + +def query_purchase_return_doc(doctype, txt, searchfield, start, page_len, filters): + return webnotes.conn.sql("""select name, supplier, supplier_name + from `tab%s` where docstatus = 1 + and (`%s` like %%(txt)s or `supplier` like %%(txt)s) + order by name, supplier, supplier_name + limit %s""" % (doctype, searchfield, "%(start)s, %(page_len)s"), + {"txt": "%%%s%%" % txt, "start": start, "page_len": page_len}, as_list=True) + +def query_return_item(doctype, txt, searchfield, start, page_len, filters): + txt = txt.replace("%", "") + + for fieldname, val in return_map[filters["purpose"]].items(): + if filters.get(fieldname): + ref_doclist = webnotes.get_doclist(val[0], filters[fieldname]) + parentfields = val[1] + + stock_items = get_stock_items_for_return(ref_doclist, parentfields) + + result = [] + for item in ref_doclist.get({"parentfield": ["in", parentfields]}): + if item.item_code in stock_items: + item.item_name = cstr(item.item_name) + item.description = cstr(item.description) + if (txt in item.item_code) or (txt in item.item_name) or (txt in item.description): + val = [ + item.item_code, + (len(item.item_name) > 40) and (item.item_name[:40] + "...") or item.item_name, + (len(item.description) > 40) and (item.description[:40] + "...") or \ + item.description + ] + if val not in result: + result.append(val) + + return result[start:start+page_len] + +def get_stock_items_for_return(ref_doclist, parentfields): + """return item codes filtered from doclist, which are stock items""" + if isinstance(parentfields, basestring): + parentfields = [parentfields] + + all_items = list(set([d.item_code for d in + ref_doclist.get({"parentfield": ["in", parentfields]})])) + stock_items = webnotes.conn.sql_list("""select name from `tabItem` + where is_stock_item='Yes' and name in (%s)""" % (", ".join(["%s"] * len(all_items))), + tuple(all_items)) + + return stock_items + +return_map = { + "Sales Return": { + # [Ref DocType, [Item tables' parentfields]] + "delivery_note_no": ["Delivery Note", ["delivery_note_details", "packing_details"]], + "sales_invoice_no": ["Sales Invoice", ["entries", "packing_details"]] + }, + "Purchase Return": { + "purchase_receipt_no": ["Purchase Receipt", ["purchase_receipt_details"]] + } +} \ 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 21d15f7e23..78f051fe27 100644 --- a/stock/doctype/stock_entry/test_stock_entry.py +++ b/stock/doctype/stock_entry/test_stock_entry.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals import webnotes, unittest +from webnotes.utils import flt class TestStockEntry(unittest.TestCase): def test_auto_material_request(self): @@ -22,7 +23,7 @@ class TestStockEntry(unittest.TestCase): self.assertTrue(mr_name) - def test_material_receipt_gl_entry(self): + def atest_material_receipt_gl_entry(self): webnotes.conn.sql("delete from `tabStock Ledger Entry`") webnotes.defaults.set_global_default("auto_inventory_accounting", 1) @@ -45,7 +46,7 @@ class TestStockEntry(unittest.TestCase): webnotes.defaults.set_global_default("auto_inventory_accounting", 0) - def test_material_issue_gl_entry(self): + def atest_material_issue_gl_entry(self): webnotes.conn.sql("delete from `tabStock Ledger Entry`") webnotes.defaults.set_global_default("auto_inventory_accounting", 1) @@ -80,7 +81,7 @@ class TestStockEntry(unittest.TestCase): self.assertEquals(expected_sle[i][1], sle.warehouse) self.assertEquals(expected_sle[i][2], sle.actual_qty) - def check_gl_entries(self, voucher_type, voucher_no, expected_gl_entries): + def acheck_gl_entries(self, voucher_type, voucher_no, expected_gl_entries): # check gl entries gl_entries = webnotes.conn.sql("""select account, debit, credit @@ -92,6 +93,125 @@ class TestStockEntry(unittest.TestCase): self.assertEquals(expected_gl_entries[i][0], gle.account) self.assertEquals(expected_gl_entries[i][1], gle.debit) self.assertEquals(expected_gl_entries[i][2], gle.credit) + + def test_sales_invoice_return_of_non_packing_item(self): + from stock.doctype.stock_entry.stock_entry import NotUpdateStockError + + from accounts.doctype.sales_invoice.test_sales_invoice \ + import test_records as sales_invoice_test_records + + # invalid sales invoice as update stock not checked + si = webnotes.bean(copy=sales_invoice_test_records[1]) + si.insert() + si.submit() + + se = webnotes.bean(copy=test_records[0]) + se.doc.purpose = "Sales Return" + se.doc.sales_invoice_no = si.doc.name + se.doclist[1].qty = 2.0 + self.assertRaises(NotUpdateStockError, se.insert) + + webnotes.conn.sql("delete from `tabStock Ledger Entry`") + webnotes.conn.sql("""delete from `tabBin`""") + material_receipt = webnotes.bean(copy=test_records[0]) + material_receipt.insert() + material_receipt.submit() + + # check currency available qty in bin + actual_qty_0 = flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", + "warehouse": "_Test Warehouse"}, "actual_qty")) + + # insert a pos invoice with update stock + si = webnotes.bean(copy=sales_invoice_test_records[1]) + si.doc.is_pos = si.doc.update_stock = 1 + si.doclist[1].warehouse = "_Test Warehouse" + si.insert() + si.submit() + + # check available bin qty after invoice submission + actual_qty_1 = flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", + "warehouse": "_Test Warehouse"}, "actual_qty")) + self.assertEquals(actual_qty_0 - 5, actual_qty_1) + + # check if item is validated + se = webnotes.bean(copy=test_records[0]) + se.doc.purpose = "Sales Return" + se.doc.sales_invoice_no = si.doc.name + se.doc.posting_date = "2013-03-10" + se.doclist[1].item_code = "_Test Item Home Desktop 100" + se.doclist[1].qty = 2.0 + se.doclist[1].transfer_qty = 2.0 + + # check if stock entry gets submitted + self.assertRaises(webnotes.DoesNotExistError, se.insert) + + # try again + se = webnotes.bean(copy=test_records[0]) + se.doc.purpose = "Sales Return" + se.doc.posting_date = "2013-03-10" + se.doc.sales_invoice_no = si.doc.name + se.doclist[1].qty = 2.0 + se.doclist[1].transfer_qty = 2.0 + se.insert() + + se.submit() + + # check if available qty is increased + actual_qty_2 = flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", + "warehouse": "_Test Warehouse"}, "actual_qty")) + self.assertEquals(actual_qty_1 + 2, actual_qty_2) + + def test_sales_invoice_return_of_packing_item(self): + webnotes.conn.sql("delete from `tabStock Ledger Entry`") + webnotes.conn.sql("""delete from `tabBin`""") + material_receipt = webnotes.bean(copy=test_records[0]) + material_receipt.insert() + material_receipt.submit() + + # check currency available qty in bin + actual_qty_0 = flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", + "warehouse": "_Test Warehouse"}, "actual_qty")) + + from accounts.doctype.sales_invoice.test_sales_invoice \ + import test_records as sales_invoice_test_records + + # insert a pos invoice with update stock + si = webnotes.bean(copy=sales_invoice_test_records[1]) + si.doc.is_pos = si.doc.update_stock = 1 + si.doclist[1].item_code = "_Test Sales BOM Item" + si.doclist[1].warehouse = "_Test Warehouse" + si.insert() + si.submit() + + # check available bin qty after invoice submission + actual_qty_1 = flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", + "warehouse": "_Test Warehouse"}, "actual_qty")) + self.assertEquals(actual_qty_0 - 25, actual_qty_1) + + se = webnotes.bean(copy=test_records[0]) + se.doc.purpose = "Sales Return" + se.doc.posting_date = "2013-03-10" + se.doc.sales_invoice_no = si.doc.name + se.doclist[1].qty = 20.0 + se.doclist[1].transfer_qty = 20.0 + se.insert() + + se.submit() + + # check if available qty is increased + actual_qty_2 = flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", + "warehouse": "_Test Warehouse"}, "actual_qty")) + self.assertEquals(actual_qty_1 + 20, actual_qty_2) + + + # def test_delivery_note_return_of_non_packing_item(self): + # pass + # + # def test_delivery_note_return_of_packing_item(self): + # pass + # + # def test_purchase_receipt_return(self): + # pass test_records = [ [ diff --git a/stock/doctype/stock_ledger/stock_ledger.py b/stock/doctype/stock_ledger/stock_ledger.py index 5dff992ae4..fcb4a54a47 100644 --- a/stock/doctype/stock_ledger/stock_ledger.py +++ b/stock/doctype/stock_ledger/stock_ledger.py @@ -209,12 +209,13 @@ class DocType: if v.get("actual_qty"): sle_id = self.make_entry(v) - + args = v.copy() args.update({ "sle_id": sle_id, "is_amended": is_amended }) + get_obj('Warehouse', v["warehouse"]).update_bin(args) diff --git a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py index d1fe3d95b2..3089a57081 100644 --- a/stock/doctype/stock_ledger_entry/stock_ledger_entry.py +++ b/stock/doctype/stock_ledger_entry/stock_ledger_entry.py @@ -39,7 +39,7 @@ class DocType: self.check_stock_frozen_date() self.scrub_posting_time() self.doc.fiscal_year = get_fiscal_year(self.doc.posting_date)[0] - + #check for item quantity available in stock def actual_amt_check(self): if self.doc.batch_no: diff --git a/stock/stock_ledger.py b/stock/stock_ledger.py index 883ced7f71..f15866d46d 100644 --- a/stock/stock_ledger.py +++ b/stock/stock_ledger.py @@ -36,6 +36,7 @@ def update_entries_after(args, verbose=1): } """ previous_sle = get_sle_before_datetime(args) + qty_after_transaction = flt(previous_sle.get("qty_after_transaction")) valuation_rate = flt(previous_sle.get("valuation_rate")) stock_queue = json.loads(previous_sle.get("stock_queue") or "[]") @@ -43,7 +44,7 @@ def update_entries_after(args, verbose=1): entries_to_fix = get_sle_after_datetime(previous_sle or \ {"item_code": args["item_code"], "warehouse": args["warehouse"]}, for_update=True) - + valuation_method = get_valuation_method(args["item_code"]) for sle in entries_to_fix: @@ -127,7 +128,7 @@ def get_stock_ledger_entries(args, conditions=None, order="desc", limit=None, fo if not args.get("posting_date"): args["posting_date"] = "1900-01-01" if not args.get("posting_time"): - args["posting_time"] = "12:00" + args["posting_time"] = "00:00" return webnotes.conn.sql("""select * from `tabStock Ledger Entry` where item_code = %%(item_code)s From ee3d5cc621ae99ebeedb29f8d97a986a94c024db Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 13 Mar 2013 12:58:54 +0530 Subject: [PATCH 02/19] added validate posting time method --- utilities/transaction_base.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/utilities/transaction_base.py b/utilities/transaction_base.py index 905e98f4bc..2dc8c6a2d7 100644 --- a/utilities/transaction_base.py +++ b/utilities/transaction_base.py @@ -16,7 +16,7 @@ from __future__ import unicode_literals import webnotes -from webnotes.utils import load_json, cstr, flt +from webnotes.utils import load_json, cstr, flt, now_datetime from webnotes.model.doc import addchild from webnotes.model.controller import DocListController @@ -246,4 +246,8 @@ class TransactionBase(DocListController): [d.update({"doctype":"Communication"}) for d in comm_list] self.doclist.extend(webnotes.doclist([webnotes.doc(fielddata=d) \ - for d in comm_list])) \ No newline at end of file + for d in comm_list])) + + 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 From 47428c2d92d49153f95086246d22c2cba001dcaf Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Wed, 13 Mar 2013 15:30:05 +0530 Subject: [PATCH 03/19] more test cases for stock entry --- stock/doctype/stock_entry/test_stock_entry.py | 152 +++++++++++------- 1 file changed, 93 insertions(+), 59 deletions(-) diff --git a/stock/doctype/stock_entry/test_stock_entry.py b/stock/doctype/stock_entry/test_stock_entry.py index 3cd285d045..caf3291534 100644 --- a/stock/doctype/stock_entry/test_stock_entry.py +++ b/stock/doctype/stock_entry/test_stock_entry.py @@ -160,7 +160,21 @@ class TestStockEntry(unittest.TestCase): self.assertEquals(expected_gl_entries[i][1], gle.debit) self.assertEquals(expected_gl_entries[i][2], gle.credit) - def test_sales_invoice_return_of_non_packing_item(self): + def _clear_stock(self): + webnotes.conn.sql("delete from `tabStock Ledger Entry`") + webnotes.conn.sql("""delete from `tabBin`""") + + def _insert_material_receipt(self): + self._clear_stock() + material_receipt = webnotes.bean(copy=test_records[0]) + material_receipt.insert() + material_receipt.submit() + + def _get_actual_qty(self): + return flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", + "warehouse": "_Test Warehouse"}, "actual_qty")) + + def _test_sales_invoice_return(self, item_code, delivered_qty, returned_qty): from stock.doctype.stock_entry.stock_entry import NotUpdateStockError from accounts.doctype.sales_invoice.test_sales_invoice \ @@ -174,39 +188,36 @@ class TestStockEntry(unittest.TestCase): se = webnotes.bean(copy=test_records[0]) se.doc.purpose = "Sales Return" se.doc.sales_invoice_no = si.doc.name - se.doclist[1].qty = 2.0 + se.doclist[1].qty = returned_qty + se.doclist[1].transfer_qty = returned_qty self.assertRaises(NotUpdateStockError, se.insert) - webnotes.conn.sql("delete from `tabStock Ledger Entry`") - webnotes.conn.sql("""delete from `tabBin`""") - material_receipt = webnotes.bean(copy=test_records[0]) - material_receipt.insert() - material_receipt.submit() + self._insert_material_receipt() # check currency available qty in bin - actual_qty_0 = flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", - "warehouse": "_Test Warehouse"}, "actual_qty")) + actual_qty_0 = self._get_actual_qty() # insert a pos invoice with update stock si = webnotes.bean(copy=sales_invoice_test_records[1]) si.doc.is_pos = si.doc.update_stock = 1 si.doclist[1].warehouse = "_Test Warehouse" + si.doclist[1].item_code = item_code si.insert() si.submit() # check available bin qty after invoice submission - actual_qty_1 = flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", - "warehouse": "_Test Warehouse"}, "actual_qty")) - self.assertEquals(actual_qty_0 - 5, actual_qty_1) + actual_qty_1 = self._get_actual_qty() + + self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1) # check if item is validated se = webnotes.bean(copy=test_records[0]) se.doc.purpose = "Sales Return" se.doc.sales_invoice_no = si.doc.name se.doc.posting_date = "2013-03-10" - se.doclist[1].item_code = "_Test Item Home Desktop 100" - se.doclist[1].qty = 2.0 - se.doclist[1].transfer_qty = 2.0 + se.doclist[1].item_code = "_Test Item Home Desktop 200" + se.doclist[1].qty = returned_qty + se.doclist[1].transfer_qty = returned_qty # check if stock entry gets submitted self.assertRaises(webnotes.DoesNotExistError, se.insert) @@ -216,68 +227,91 @@ class TestStockEntry(unittest.TestCase): se.doc.purpose = "Sales Return" se.doc.posting_date = "2013-03-10" se.doc.sales_invoice_no = si.doc.name - se.doclist[1].qty = 2.0 - se.doclist[1].transfer_qty = 2.0 + se.doclist[1].qty = returned_qty + se.doclist[1].transfer_qty = returned_qty + # in both cases item code remains _Test Item when returning se.insert() se.submit() # check if available qty is increased - actual_qty_2 = flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", - "warehouse": "_Test Warehouse"}, "actual_qty")) - self.assertEquals(actual_qty_1 + 2, actual_qty_2) + actual_qty_2 = self._get_actual_qty() + + self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2) + + def test_sales_invoice_return_of_non_packing_item(self): + self._test_sales_invoice_return("_Test Item", 5, 2) def test_sales_invoice_return_of_packing_item(self): - webnotes.conn.sql("delete from `tabStock Ledger Entry`") - webnotes.conn.sql("""delete from `tabBin`""") - material_receipt = webnotes.bean(copy=test_records[0]) - material_receipt.insert() - material_receipt.submit() + self._test_sales_invoice_return("_Test Sales BOM Item", 25, 20) - # check currency available qty in bin - actual_qty_0 = flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", - "warehouse": "_Test Warehouse"}, "actual_qty")) + def _test_delivery_note_return(self, item_code, delivered_qty, returned_qty): + self._insert_material_receipt() - from accounts.doctype.sales_invoice.test_sales_invoice \ - import test_records as sales_invoice_test_records - - # insert a pos invoice with update stock - si = webnotes.bean(copy=sales_invoice_test_records[1]) - si.doc.is_pos = si.doc.update_stock = 1 - si.doclist[1].item_code = "_Test Sales BOM Item" - si.doclist[1].warehouse = "_Test Warehouse" - si.insert() - si.submit() + actual_qty_0 = self._get_actual_qty() - # check available bin qty after invoice submission - actual_qty_1 = flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", - "warehouse": "_Test Warehouse"}, "actual_qty")) - self.assertEquals(actual_qty_0 - 25, actual_qty_1) + # insert and submit delivery note + from stock.doctype.delivery_note.test_delivery_note \ + import test_records as delivery_note_test_records + dn = webnotes.bean(copy=delivery_note_test_records[0]) + dn.doclist[1].item_code = item_code + dn.insert() + dn.submit() + actual_qty_1 = self._get_actual_qty() + + self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1) + + # insert and submit stock entry for sales return se = webnotes.bean(copy=test_records[0]) se.doc.purpose = "Sales Return" - se.doc.posting_date = "2013-03-10" - se.doc.sales_invoice_no = si.doc.name - se.doclist[1].qty = 20.0 - se.doclist[1].transfer_qty = 20.0 - se.insert() + se.doc.delivery_note_no = dn.doc.name + se.doc.posting_date = "2013-03-01" + se.doclist[1].qty = se.doclist[1].transfer_qty = returned_qty + se.insert() se.submit() - # check if available qty is increased - actual_qty_2 = flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", - "warehouse": "_Test Warehouse"}, "actual_qty")) - self.assertEquals(actual_qty_1 + 20, actual_qty_2) + actual_qty_2 = self._get_actual_qty() + self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2) + def test_delivery_note_return_of_non_packing_item(self): + self._test_delivery_note_return("_Test Item", 5, 2) + + def test_delivery_note_return_of_packing_item(self): + self._test_delivery_note_return("_Test Sales BOM Item", 25, 20) + + def test_purchase_receipt_return(self): + self._clear_stock() + + actual_qty_0 = self._get_actual_qty() + + from stock.doctype.purchase_receipt.test_purchase_receipt \ + import test_records as purchase_receipt_test_records + + # submit purchase receipt + pr = webnotes.bean(copy=purchase_receipt_test_records[0]) + pr.insert() + pr.submit() + + actual_qty_1 = self._get_actual_qty() + + self.assertEquals(actual_qty_0 + 10, actual_qty_1) + + # submit purchase return + se = webnotes.bean(copy=test_records[0]) + se.doc.purpose = "Purchase Return" + se.doc.purchase_receipt_no = pr.doc.name + se.doc.posting_date = "2013-03-01" + se.doclist[1].qty = se.doclist[1].transfer_qty = 5 + se.doclist[1].s_warehouse = "_Test Warehouse" + se.insert() + se.submit() + + actual_qty_2 = self._get_actual_qty() + + self.assertEquals(actual_qty_1 - 5, actual_qty_2) - # def test_delivery_note_return_of_non_packing_item(self): - # pass - # - # def test_delivery_note_return_of_packing_item(self): - # pass - # - # def test_purchase_receipt_return(self): - # pass test_records = [ [ From 87052b366b91f25549559982ddba22cfbcc726b3 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 15 Mar 2013 11:32:40 +0530 Subject: [PATCH 04/19] validate over-return of stock for sales purchase return --- stock/doctype/stock_entry/stock_entry.js | 34 +++++++ stock/doctype/stock_entry/stock_entry.py | 88 ++++++++++++------- stock/doctype/stock_entry/test_stock_entry.py | 17 ++++ 3 files changed, 109 insertions(+), 30 deletions(-) diff --git a/stock/doctype/stock_entry/stock_entry.js b/stock/doctype/stock_entry/stock_entry.js index 010b27040d..158184486f 100644 --- a/stock/doctype/stock_entry/stock_entry.js +++ b/stock/doctype/stock_entry/stock_entry.js @@ -66,6 +66,17 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ if (this.frm.doc.docstatus==1) { this.show_stock_ledger(); } + + if(this.frm.doc.docstatus === 1 && wn.boot.profile.can_create("Journal Voucher")) { + if(this.frm.doc.purpose === "Sales Return") { + this.frm.add_custom_button("Make Credit Note", this.make_return_jv); + this.add_excise_button(); + } else if(this.frm.doc.purpose === "Purchase Return") { + this.frm.add_custom_button("Make Debit Note", this.make_return_jv); + this.add_excise_button(); + } + } + }, on_submit: function() { @@ -143,6 +154,29 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ } } }, + + add_excise_button: function() { + if(wn.boot.control_panel.country === "India") + this.frm.add_custom_button("Make Excise Invoice", function() { + var excise = wn.model.make_new_doc_and_get_name('Journal Voucher'); + excise = locals['Journal Voucher'][excise]; + excise.voucher_type = 'Excise Voucher'; + loaddoc('Journal Voucher', excise.name); + }); + }, + + make_return_jv: function() { + this.frm.call({ + method: "make_return_jv", + args: { + stock_entry: this.frm.doc.name + }, + callback: function(r) { + console.log(r); + loaddoc("Journal Voucher", r.message); + } + }); + }, }); diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index 38ab5ba7e4..80756b40ed 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -29,6 +29,7 @@ import json sql = webnotes.conn.sql class NotUpdateStockError(webnotes.ValidationError): pass +class StockOverReturnError(webnotes.ValidationError): pass from controllers.accounts_controller import AccountsController @@ -278,32 +279,24 @@ class DocType(AccountsController): def validate_return_reference_doc(self): """validate item with reference doc""" - ref_doclist = parentfields = None + ref = get_return_reference_details(self.doc.fields) - # get ref_doclist - if self.doc.purpose in return_map: - for fieldname, val in return_map[self.doc.purpose].items(): - if self.doc.fields.get(fieldname): - ref_doclist = webnotes.get_doclist(val[0], self.doc.fields[fieldname]) - parentfields = val[1] - - if ref_doclist: + if ref.doclist: # validate docstatus - if ref_doclist[0].docstatus != 1: - webnotes.msgprint(_(ref_doclist[0].doctype) + ' "' + ref_doclist[0].name + '": ' + if ref.doclist[0].docstatus != 1: + webnotes.msgprint(_(ref.doclist[0].doctype) + ' "' + ref.doclist[0].name + '": ' + _("Status should be Submitted"), raise_exception=webnotes.InvalidStatusError) - # update stock check - if ref_doclist[0].doctype == "Sales Invoice" and (cint(ref_doclist[0].is_pos) != 1 \ - or cint(ref_doclist[0].update_stock) != 1): - webnotes.msgprint(_(ref_doclist[0].doctype) + ' "' + ref_doclist[0].name + '": ' + if ref.doclist[0].doctype == "Sales Invoice" and (cint(ref.doclist[0].is_pos) != 1 \ + or cint(ref.doclist[0].update_stock) != 1): + webnotes.msgprint(_(ref.doclist[0].doctype) + ' "' + ref.doclist[0].name + '": ' + _("Is POS and Update Stock should be checked."), raise_exception=NotUpdateStockError) # posting date check - ref_posting_datetime = "%s %s" % (cstr(ref_doclist[0].posting_date), - cstr(ref_doclist[0].posting_time)) + ref_posting_datetime = "%s %s" % (cstr(ref.doclist[0].posting_date), + cstr(ref.doclist[0].posting_time)) this_posting_datetime = "%s %s" % (cstr(self.doc.posting_date), cstr(self.doc.posting_time)) if this_posting_datetime < ref_posting_datetime: @@ -312,18 +305,27 @@ class DocType(AccountsController): + ": " + datetime_in_user_format(ref_posting_datetime), raise_exception=True) - stock_items = get_stock_items_for_return(ref_doclist, parentfields) + stock_items = get_stock_items_for_return(ref.doclist, ref.parentfields) + already_returned_item_qty = self.get_already_returned_item_qty(ref.fieldname) for item in self.doclist.get({"parentfield": "mtn_details"}): # validate if item exists in the ref doclist and that it is a stock item if item.item_code not in stock_items: msgprint(_("Item") + ': "' + item.item_code + _("\" does not exist in ") + - ref_doclist[0].doctype + ": " + ref_doclist[0].name, + ref.doclist[0].doctype + ": " + ref.doclist[0].name, raise_exception=webnotes.DoesNotExistError) - # validate quantity <= ref item's qty - ref_item = ref_doclist.getone({"item_code": item.item_code}) - self.validate_value("transfer_qty", "<=", ref_item.qty, item) + # validate quantity <= ref item's qty - qty already returned + ref_item = ref.doclist.getone({"item_code": item.item_code}) + returnable_qty = ref_item.qty - flt(already_returned_item_qty.get(item.item_code)) + self.validate_value("transfer_qty", "<=", returnable_qty, item, + raise_exception=StockOverReturnError) + + def get_already_returned_item_qty(self, ref_fieldname): + return dict(webnotes.conn.sql("""select item_code, sum(transfer_qty) as qty + from `tabStock Entry Detail` where parent in ( + select name from `tabStock Entry` where `%s`=%s and docstatus=1) + group by item_code""" % (ref_fieldname, "%s"), (self.doc.fields.get(ref_fieldname),))) def update_serial_no(self, is_submit): """Create / Update Serial No""" @@ -670,7 +672,7 @@ class DocType(AccountsController): + " " + _("Row #") + (" %d %s " % (mreq_item.idx, _("of"))) + _("Material Request") + (" - %s" % item.material_request), raise_exception=webnotes.MappingMismatchError) - + @webnotes.whitelist() def get_production_order_details(production_order): result = webnotes.conn.sql("""select bom_no, @@ -700,16 +702,13 @@ def query_purchase_return_doc(doctype, txt, searchfield, start, page_len, filter def query_return_item(doctype, txt, searchfield, start, page_len, filters): txt = txt.replace("%", "") - - for fieldname, val in return_map[filters["purpose"]].items(): - if filters.get(fieldname): - ref_doclist = webnotes.get_doclist(val[0], filters[fieldname]) - parentfields = val[1] + + ref = get_return_reference_details(filters) - stock_items = get_stock_items_for_return(ref_doclist, parentfields) + stock_items = get_stock_items_for_return(ref.doclist, ref.parentfields) result = [] - for item in ref_doclist.get({"parentfield": ["in", parentfields]}): + for item in ref.doclist.get({"parentfield": ["in", ref.parentfields]}): if item.item_code in stock_items: item.item_name = cstr(item.item_name) item.description = cstr(item.description) @@ -738,6 +737,20 @@ def get_stock_items_for_return(ref_doclist, parentfields): return stock_items +def get_return_reference_details(args): + ref = webnotes._dict() + + # get ref_doclist + if args["purpose"] in return_map: + for fieldname, val in return_map[args["purpose"]].items(): + if args.get(fieldname): + ref.fieldname = fieldname + ref.doclist = webnotes.get_doclist(val[0], args[fieldname]) + ref.parentfields = val[1] + break + + return ref + return_map = { "Sales Return": { # [Ref DocType, [Item tables' parentfields]] @@ -748,3 +761,18 @@ return_map = { "purchase_receipt_no": ["Purchase Receipt", ["purchase_receipt_details"]] } } + +def make_return_jv(stock_entry): + jv = webnotes.bean({ + "doctype": "Journal Voucher", + "__islocal": 1 + }) + + se = webnotes.bean("Stock Entry", stock_entry) + + if not webnotes.response.get("docs"): + webnotes.response["docs"] = [] + + webnotes.response["docs"] = jv.doclist + + return jv.doc.name \ 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 caf3291534..c0f8f28240 100644 --- a/stock/doctype/stock_entry/test_stock_entry.py +++ b/stock/doctype/stock_entry/test_stock_entry.py @@ -312,6 +312,23 @@ class TestStockEntry(unittest.TestCase): self.assertEquals(actual_qty_1 - 5, actual_qty_2) + return pr.doc.name + + def test_over_stock_return(self): + from stock.doctype.stock_entry.stock_entry import StockOverReturnError + + # out of 10, 5 gets returned + pr_docname = self.test_purchase_receipt_return() + + # submit purchase return - return another 6 qtys so that exception is raised + se = webnotes.bean(copy=test_records[0]) + se.doc.purpose = "Purchase Return" + se.doc.purchase_receipt_no = pr_docname + se.doc.posting_date = "2013-03-01" + se.doclist[1].qty = se.doclist[1].transfer_qty = 6 + se.doclist[1].s_warehouse = "_Test Warehouse" + + self.assertRaises(StockOverReturnError, se.insert) test_records = [ [ From 1524c2a5b6f2a2643aa4f564891be514b2d519f3 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 15 Mar 2013 17:42:45 +0530 Subject: [PATCH 05/19] create return jv --- stock/doctype/stock_entry/stock_entry.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index 80756b40ed..d5764fa54e 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -769,6 +769,19 @@ def make_return_jv(stock_entry): }) se = webnotes.bean("Stock Entry", stock_entry) + ref = get_return_reference_details(se.doc.fields) + + for se_item in se.doclist.get({"parentfield": "mtn_details"}): + # find item in ref.doclist + ref_item = ref.doclist.getone({"item_code": se_item.item_code}) + + # add row for customer/supplier account + + # find income account and value and add corresponding rows + + # find tax account and value and add corresponding rows + + pass if not webnotes.response.get("docs"): webnotes.response["docs"] = [] From 6230aa9292a4a2362b9ba05a129d9a235e23b0b9 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Sat, 16 Mar 2013 19:05:11 +0530 Subject: [PATCH 06/19] make return jv for sales return --- stock/doctype/stock_entry/stock_entry.py | 142 ++++++++++++++++++++--- 1 file changed, 125 insertions(+), 17 deletions(-) diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index d5764fa54e..dc67b9f441 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -25,6 +25,7 @@ from webnotes import msgprint, _ from stock.utils import get_incoming_rate from stock.stock_ledger import get_previous_sle import json +from accounts.utils import get_balance_on sql = webnotes.conn.sql @@ -762,30 +763,137 @@ return_map = { } } +@webnotes.whitelist() def make_return_jv(stock_entry): - jv = webnotes.bean({ - "doctype": "Journal Voucher", - "__islocal": 1 - }) - se = webnotes.bean("Stock Entry", stock_entry) + if not se.doc.purpose in ["Sales Return", "Purchase Return"]: + return + ref = get_return_reference_details(se.doc.fields) - for se_item in se.doclist.get({"parentfield": "mtn_details"}): - # find item in ref.doclist - ref_item = ref.doclist.getone({"item_code": se_item.item_code}) - - # add row for customer/supplier account - - # find income account and value and add corresponding rows - - # find tax account and value and add corresponding rows - - pass + if ref.doclist[0].doctype == "Delivery Note": + result = make_return_jv_from_delivery_note(se, ref) + elif ref.doclist[0].doctype == "Sales Invoice": + result = make_return_jv_from_sales_invoice(se, ref) + elif ref.doclist[0].doctype == "Purchase Receipt": + result = make_return_jv_from_purchase_receipt(se, ref) + + # create jv doclist and fetch balance for each unique row item if not webnotes.response.get("docs"): webnotes.response["docs"] = [] webnotes.response["docs"] = jv.doclist - return jv.doc.name \ No newline at end of file + return jv.doc.name + +def make_return_jv_from_sales_invoice(se, ref): + # customer account entry + parent = { + "account": ref.doclist[0].debit_to, + "credit": 0.0, + "against_invoice": ref.doclist[0].name, + } + + # income account entries + children = {} + for se_item in se.doclist.get({"parentfield": "mtn_details"}): + # find item in ref.doclist + ref_item = ref.doclist.getone({"item_code": se_item.item_code}) + + account, debit = get_sales_account_and_amount_from_item(ref.doclist, ref_item, + se_item.transfer_qty) + + if account not in children: + children[account] = 0 + children[account] += debit + parent["credit"] += debit + + # find tax account and value and add corresponding rows + + return [parent] + [{"account": account, "debit": debit} for account, debit in children.items()] + +def get_sales_account_and_amount_from_item(doclist, ref_item, transfer_qty): + account = debit = None + if not ref_item.income_account: + if ref_item.parent_item: + parent_item = doclist.getone({"item_code": ref_item.parent_item}) + packing_ratio = parent_item.qty / ref_item.qty + + debit = parent_item.basic_rate * transfer_qty * packing_ratio + account = parent_item.income_account + else: + debit = ref_item.basic_rate * transfer_qty + account = ref_item.income_account + + return account, debit + +def make_return_jv_from_delivery_note(se, ref): + invoices_against_delivery = get_invoice_list("Sales Invoice Item", "delivery_note", + ref.doclist[0].name) + + if not invoices_against_delivery: + item_codes = [item.item_code for item in se.doclist.get({"parentfield": "mtn_details"})] + sales_orders_against_delivery = [d.prev_docname for d in + ref.doclist.get({"prev_doctype": "Sales Order"}) + if d.prev_docname and d.item_code in item_codes] + + invoices_against_delivery = get_invoice_list("Sales Order Item", "sales_order", + sales_orders_against_delivery) + + against_invoice = {} + + for se_item in se.doclist.get({"parentfield": "mtn_details"}): + pending = se_item.transfer_qty + for sales_invoice in invoices_against_delivery: + si_doclist = webnotes.get_doclist("Sales Invoice", sales_invoice) + ref_item = si_doclist.get({"item_code": se_item.item_code}) + if not ref_item: + continue + + ref_item = ref_item[0] + + if ref_item.qty < pending: + transfer_qty = ref_item.qty + pending -= ref_item.qty + else: + transfer_qty = pending + pending = 0 + + account, debit = get_sales_account_and_amount_from_item(si_doclist, ref_item, + transfer_qty) + + if si_doclist[0].name not in against_invoice: + against_invoice[sales_invoice] = { + "parent": {"account": si_doclist[0].debit_to, "credit": 0}, + "children": {} + } + + against_invoice[sales_invoice]["parent"]["credit"] += debit + + if account not in against_invoice[sales_invoice]["children"]: + against_invoice[sales_invoice]["children"][account] = 0 + + against_invoice[sales_invoice]["children"][account] += debit + + # find tax account and value and add corresponding rows + + if pending <= 0: + break + + result = [] + for sales_invoice, opts in against_invoice.items(): + result += [opts["parent"]] + [{"account": account, "debit": debit} + for account, debit in opts["children"].items()] + return result + +def get_invoice_list(doctype, link_field, value): + if isinstance(value, basestring): + value = [value] + + return webnotes.conn.sql_list("""select distinct parent from `tab%s` + where docstatus = 1 and `%s` in (%s)""" % (doctype, link_field, + ", ".join(["%s"]*len(value))), tuple(value)) + +def make_return_jv_from_purchase_receipt(se, ref): + pass From ab7b7c2974b635d37f7b8d0f28cfa050566ec4e9 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Mon, 18 Mar 2013 17:37:31 +0530 Subject: [PATCH 07/19] completed sales purchase return as part of stock entry --- stock/doctype/delivery_note/delivery_note.py | 2 +- stock/doctype/stock_entry/stock_entry.js | 21 +- stock/doctype/stock_entry/stock_entry.py | 122 +++++++-- stock/doctype/stock_entry/test_stock_entry.py | 257 +++++++++++++++++- 4 files changed, 364 insertions(+), 38 deletions(-) diff --git a/stock/doctype/delivery_note/delivery_note.py b/stock/doctype/delivery_note/delivery_note.py index 229ec40a54..46c6ee4bd4 100644 --- a/stock/doctype/delivery_note/delivery_note.py +++ b/stock/doctype/delivery_note/delivery_note.py @@ -133,7 +133,7 @@ class DocType(SellingController): super(DocType, self).validate() import utilities - utilities.validate_status(self.doc.status, ["Draft", "submitted", "Cancelled"]) + utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Cancelled"]) self.so_required() self.validate_fiscal_year() diff --git a/stock/doctype/stock_entry/stock_entry.js b/stock/doctype/stock_entry/stock_entry.js index 158184486f..0b27d99bad 100644 --- a/stock/doctype/stock_entry/stock_entry.js +++ b/stock/doctype/stock_entry/stock_entry.js @@ -60,6 +60,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ }, refresh: function() { + var me = this; erpnext.hide_naming_series(); this.toggle_related_fields(this.frm.doc); this.toggle_enable_bom(); @@ -67,12 +68,13 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ this.show_stock_ledger(); } - if(this.frm.doc.docstatus === 1 && wn.boot.profile.can_create("Journal Voucher")) { + if(this.frm.doc.docstatus === 1 && + wn.boot.profile.can_create.indexOf("Journal Voucher")!==-1) { if(this.frm.doc.purpose === "Sales Return") { - this.frm.add_custom_button("Make Credit Note", this.make_return_jv); + this.frm.add_custom_button("Make Credit Note", function() { me.make_return_jv(); }); this.add_excise_button(); } else if(this.frm.doc.purpose === "Purchase Return") { - this.frm.add_custom_button("Make Debit Note", this.make_return_jv); + this.frm.add_custom_button("Make Debit Note", function() { me.make_return_jv(); }); this.add_excise_button(); } } @@ -172,8 +174,17 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({ stock_entry: this.frm.doc.name }, callback: function(r) { - console.log(r); - loaddoc("Journal Voucher", r.message); + if(!r.exc) { + var jv_name = wn.model.make_new_doc_and_get_name('Journal Voucher'); + var jv = locals["Journal Voucher"][jv_name]; + $.extend(jv, r.message[0]); + $.each(r.message.slice(1), function(i, jvd) { + var child = wn.model.add_child(jv, "Journal Voucher Detail", "entries"); + $.extend(child, jvd); + }); + loaddoc("Journal Voucher", jv_name); + } + } }); }, diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index dc67b9f441..131e9ffcd4 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -25,7 +25,6 @@ from webnotes import msgprint, _ from stock.utils import get_incoming_rate from stock.stock_ledger import get_previous_sle import json -from accounts.utils import get_balance_on sql = webnotes.conn.sql @@ -297,7 +296,7 @@ class DocType(AccountsController): # posting date check ref_posting_datetime = "%s %s" % (cstr(ref.doclist[0].posting_date), - cstr(ref.doclist[0].posting_time)) + cstr(ref.doclist[0].posting_time) or "00:00:00") this_posting_datetime = "%s %s" % (cstr(self.doc.posting_date), cstr(self.doc.posting_time)) if this_posting_datetime < ref_posting_datetime: @@ -779,13 +778,30 @@ def make_return_jv(stock_entry): result = make_return_jv_from_purchase_receipt(se, ref) # create jv doclist and fetch balance for each unique row item + jv_list = [{ + "__islocal": 1, + "doctype": "Journal Voucher", + "posting_date": se.doc.posting_date, + "voucher_type": se.doc.purpose == "Sales Return" and "Credit Note" or "Debit Note", + "fiscal_year": se.doc.fiscal_year, + "company": se.doc.company + }] - if not webnotes.response.get("docs"): - webnotes.response["docs"] = [] - - webnotes.response["docs"] = jv.doclist - - return jv.doc.name + from accounts.utils import get_balance_on + for r in result: + jv_list.append({ + "__islocal": 1, + "doctype": "Journal Voucher Detail", + "parentfield": "entries", + "account": r.get("account"), + "debit": r.get("debit"), + "credit": r.get("credit"), + "against_invoice": r.get("against_invoice"), + "against_voucher": r.get("against_voucher"), + "balance": get_balance_on(r.get("account"), se.doc.posting_date) + }) + + return jv_list def make_return_jv_from_sales_invoice(se, ref): # customer account entry @@ -833,12 +849,10 @@ def make_return_jv_from_delivery_note(se, ref): ref.doclist[0].name) if not invoices_against_delivery: - item_codes = [item.item_code for item in se.doclist.get({"parentfield": "mtn_details"})] - sales_orders_against_delivery = [d.prev_docname for d in - ref.doclist.get({"prev_doctype": "Sales Order"}) - if d.prev_docname and d.item_code in item_codes] - - invoices_against_delivery = get_invoice_list("Sales Order Item", "sales_order", + sales_orders_against_delivery = [d.prevdoc_docname for d in + ref.doclist.get({"prevdoc_doctype": "Sales Order"}) if d.prevdoc_docname] + + invoices_against_delivery = get_invoice_list("Sales Invoice Item", "sales_order", sales_orders_against_delivery) against_invoice = {} @@ -846,8 +860,10 @@ def make_return_jv_from_delivery_note(se, ref): for se_item in se.doclist.get({"parentfield": "mtn_details"}): pending = se_item.transfer_qty for sales_invoice in invoices_against_delivery: - si_doclist = webnotes.get_doclist("Sales Invoice", sales_invoice) - ref_item = si_doclist.get({"item_code": se_item.item_code}) + si = webnotes.bean("Sales Invoice", sales_invoice) + si.run_method("make_packing_list") + ref_item = si.doclist.get({"item_code": se_item.item_code}) + if not ref_item: continue @@ -860,12 +876,12 @@ def make_return_jv_from_delivery_note(se, ref): transfer_qty = pending pending = 0 - account, debit = get_sales_account_and_amount_from_item(si_doclist, ref_item, + account, debit = get_sales_account_and_amount_from_item(si.doclist, ref_item, transfer_qty) - if si_doclist[0].name not in against_invoice: + if si.doclist[0].name not in against_invoice: against_invoice[sales_invoice] = { - "parent": {"account": si_doclist[0].debit_to, "credit": 0}, + "parent": {"account": si.doclist[0].debit_to, "credit": 0}, "children": {} } @@ -883,17 +899,79 @@ def make_return_jv_from_delivery_note(se, ref): result = [] for sales_invoice, opts in against_invoice.items(): - result += [opts["parent"]] + [{"account": account, "debit": debit} + parent = opts["parent"] + parent.update({"against_invoice": sales_invoice}) + children = [{"account": account, "debit": debit} for account, debit in opts["children"].items()] + result += [parent] + children return result def get_invoice_list(doctype, link_field, value): if isinstance(value, basestring): value = [value] - + return webnotes.conn.sql_list("""select distinct parent from `tab%s` where docstatus = 1 and `%s` in (%s)""" % (doctype, link_field, ", ".join(["%s"]*len(value))), tuple(value)) def make_return_jv_from_purchase_receipt(se, ref): - pass + invoice_against_receipt = get_invoice_list("Purchase Invoice Item", "purchase_receipt", + ref.doclist[0].name) + + if not invoice_against_receipt: + purchase_orders_against_receipt = [d.prevdoc_docname for d in + ref.doclist.get({"prevdoc_doctype": "Purchase Order"}) if d.prevdoc_docname] + + invoice_against_receipt = get_invoice_list("Purchase Invoice Item", "purchase_order", + purchase_orders_against_receipt) + + against_voucher = {} + + for se_item in se.doclist.get({"parentfield": "mtn_details"}): + pending = se_item.transfer_qty + for purchase_invoice in invoice_against_receipt: + pi = webnotes.bean("Purchase Invoice", purchase_invoice) + ref_item = pi.doclist.get({"item_code": se_item.item_code}) + + if not ref_item: + continue + + ref_item = ref_item[0] + + if ref_item.qty < pending: + transfer_qty = ref_item.qty + pending -= ref_item.qty + else: + transfer_qty = pending + pending = 0 + + credit = ref_item.rate * transfer_qty + account = ref_item.expense_head + + if pi.doclist[0].name not in against_voucher: + against_voucher[purchase_invoice] = { + "parent": {"account": pi.doclist[0].credit_to, "debit": 0}, + "children": {} + } + + against_voucher[purchase_invoice]["parent"]["debit"] += credit + + if account not in against_voucher[purchase_invoice]["children"]: + against_voucher[purchase_invoice]["children"][account] = 0 + + against_voucher[purchase_invoice]["children"][account] += credit + + # find tax account and value and add corresponding rows + + if pending <= 0: + break + + result = [] + for purchase_invoice, opts in against_voucher.items(): + parent = opts["parent"] + parent.update({"against_voucher": purchase_invoice}) + children = [{"account": account, "credit": credit} + for account, credit in opts["children"].items()] + result += [parent] + children + return result + \ 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 c0f8f28240..049b0e66c8 100644 --- a/stock/doctype/stock_entry/test_stock_entry.py +++ b/stock/doctype/stock_entry/test_stock_entry.py @@ -9,6 +9,9 @@ class TestStockEntry(unittest.TestCase): def test_auto_material_request(self): webnotes.conn.sql("""delete from `tabMaterial Request Item`""") webnotes.conn.sql("""delete from `tabMaterial Request`""") + self._clear_stock() + + webnotes.conn.set_value("Global Defaults", None, "auto_indent", True) st1 = webnotes.bean(copy=test_records[0]) st1.insert() @@ -166,9 +169,14 @@ class TestStockEntry(unittest.TestCase): def _insert_material_receipt(self): self._clear_stock() - material_receipt = webnotes.bean(copy=test_records[0]) - material_receipt.insert() - material_receipt.submit() + se1 = webnotes.bean(copy=test_records[0]) + se1.insert() + se1.submit() + + se2 = webnotes.bean(copy=test_records[0]) + se2.doclist[1].item_code = "_Test Item Home Desktop 100" + se2.insert() + se2.submit() def _get_actual_qty(self): return flt(webnotes.conn.get_value("Bin", {"item_code": "_Test Item", @@ -238,6 +246,8 @@ class TestStockEntry(unittest.TestCase): actual_qty_2 = self._get_actual_qty() self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2) + + return se def test_sales_invoice_return_of_non_packing_item(self): self._test_sales_invoice_return("_Test Item", 5, 2) @@ -248,11 +258,12 @@ class TestStockEntry(unittest.TestCase): def _test_delivery_note_return(self, item_code, delivered_qty, returned_qty): self._insert_material_receipt() - actual_qty_0 = self._get_actual_qty() - - # insert and submit delivery note from stock.doctype.delivery_note.test_delivery_note \ import test_records as delivery_note_test_records + + actual_qty_0 = self._get_actual_qty() + + # make a delivery note based on this invoice dn = webnotes.bean(copy=delivery_note_test_records[0]) dn.doclist[1].item_code = item_code dn.insert() @@ -262,11 +273,26 @@ class TestStockEntry(unittest.TestCase): self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1) + si_doclist = webnotes.map_doclist([ + ["Delivery Note", "Sales Invoice"], + ["Delivery Note Item", "Sales Invoice Item"], + ["Sales Taxes and Charges", "Sales Taxes and Charges"], + ["Sales Team", "Sales Team"]], dn.doc.name) + + si = webnotes.bean(si_doclist) + si.doc.posting_date = dn.doc.posting_date + si.doc.debit_to = "_Test Customer - _TC" + for d in si.doclist.get({"parentfield": "entries"}): + d.income_account = "Sales - _TC" + d.cost_center = "_Test Cost Center - _TC" + si.insert() + si.submit() + # insert and submit stock entry for sales return se = webnotes.bean(copy=test_records[0]) se.doc.purpose = "Sales Return" se.doc.delivery_note_no = dn.doc.name - se.doc.posting_date = "2013-03-01" + se.doc.posting_date = "2013-03-10" se.doclist[1].qty = se.doclist[1].transfer_qty = returned_qty se.insert() @@ -275,12 +301,115 @@ class TestStockEntry(unittest.TestCase): actual_qty_2 = self._get_actual_qty() self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2) + return se + def test_delivery_note_return_of_non_packing_item(self): self._test_delivery_note_return("_Test Item", 5, 2) def test_delivery_note_return_of_packing_item(self): self._test_delivery_note_return("_Test Sales BOM Item", 25, 20) + def _test_sales_return_jv(self, se, returned_value): + from stock.doctype.stock_entry.stock_entry import make_return_jv + jv_list = make_return_jv(se.doc.name) + + self.assertEqual(len(jv_list), 3) + self.assertEqual(jv_list[0].get("voucher_type"), "Credit Note") + self.assertEqual(jv_list[0].get("posting_date"), se.doc.posting_date) + self.assertEqual(jv_list[1].get("account"), "_Test Customer - _TC") + self.assertEqual(jv_list[2].get("account"), "Sales - _TC") + self.assertTrue(jv_list[1].get("against_invoice")) + + # debit == credit + debit = sum([flt(d.get("debit")) for d in jv_list]) + credit = sum([flt(d.get("credit")) for d in jv_list]) + self.assertEqual(debit, credit) + + # validate value of debit + self.assertEqual(debit, returned_value) + + def test_make_return_jv_for_sales_invoice_non_packing_item(self): + se = self._test_sales_invoice_return("_Test Item", 5, 2) + self._test_sales_return_jv(se, 1000) + + def test_make_return_jv_for_sales_invoice_packing_item(self): + se = self._test_sales_invoice_return("_Test Sales BOM Item", 25, 20) + self._test_sales_return_jv(se, 2000) + + def test_make_return_jv_for_delivery_note_non_packing_item(self): + se = self._test_delivery_note_return("_Test Item", 5, 2) + self._test_sales_return_jv(se, 200) + + se = self._test_delivery_note_return_against_sales_order("_Test Item", 5, 2) + self._test_sales_return_jv(se, 200) + + def test_make_return_jv_for_delivery_note_packing_item(self): + se = self._test_delivery_note_return("_Test Sales BOM Item", 25, 20) + self._test_sales_return_jv(se, 400) + + se = self._test_delivery_note_return_against_sales_order("_Test Sales BOM Item", 25, 20) + self._test_sales_return_jv(se, 400) + + def _test_delivery_note_return_against_sales_order(self, item_code, delivered_qty, returned_qty): + self._insert_material_receipt() + + from selling.doctype.sales_order.test_sales_order \ + import test_records as sales_order_test_records + + actual_qty_0 = self._get_actual_qty() + + so = webnotes.bean(copy=sales_order_test_records[0]) + so.doclist[1].item_code = item_code + so.doclist[1].qty = 5.0 + so.insert() + so.submit() + + dn_doclist = webnotes.map_doclist([ + ["Sales Order", "Delivery Note"], + ["Sales Order Item", "Delivery Note Item"], + ["Sales Taxes and Charges", "Sales Taxes and Charges"], + ["Sales Team", "Sales Team"]], so.doc.name) + + dn = webnotes.bean(dn_doclist) + dn.doc.status = "Draft" + dn.doc.posting_date = so.doc.delivery_date + dn.insert() + dn.submit() + + actual_qty_1 = self._get_actual_qty() + + self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1) + + si_doclist = webnotes.map_doclist([ + ["Sales Order", "Sales Invoice"], + ["Sales Order Item", "Sales Invoice Item"], + ["Sales Taxes and Charges", "Sales Taxes and Charges"], + ["Sales Team", "Sales Team"]], so.doc.name) + + si = webnotes.bean(si_doclist) + si.doc.posting_date = dn.doc.posting_date + si.doc.debit_to = "_Test Customer - _TC" + for d in si.doclist.get({"parentfield": "entries"}): + d.income_account = "Sales - _TC" + d.cost_center = "_Test Cost Center - _TC" + si.insert() + si.submit() + + # insert and submit stock entry for sales return + se = webnotes.bean(copy=test_records[0]) + se.doc.purpose = "Sales Return" + se.doc.delivery_note_no = dn.doc.name + se.doc.posting_date = "2013-03-10" + se.doclist[1].qty = se.doclist[1].transfer_qty = returned_qty + + se.insert() + se.submit() + + actual_qty_2 = self._get_actual_qty() + self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2) + + return se + def test_purchase_receipt_return(self): self._clear_stock() @@ -298,6 +427,24 @@ class TestStockEntry(unittest.TestCase): self.assertEquals(actual_qty_0 + 10, actual_qty_1) + pi_doclist = webnotes.map_doclist([ + ["Purchase Receipt", "Purchase Invoice"], + ["Purchase Receipt Item", "Purchase Invoice Item"], + ["Purchase Taxes and Charges", "Purchase Taxes and Charges"]], pr.doc.name) + + pi = webnotes.bean(pi_doclist) + pi.doc.posting_date = pr.doc.posting_date + pi.doc.credit_to = "_Test Supplier - _TC" + for d in pi.doclist.get({"parentfield": "entries"}): + d.expense_head = "_Test Account Cost for Goods Sold - _TC" + d.cost_center = "_Test Cost Center - _TC" + for d in pi.doclist.get({"parentfield": "purchase_tax_details"}): + d.cost_center = "_Test Cost Center - _TC" + + pi.run_method("calculate_taxes_and_totals") + pi.insert() + pi.submit() + # submit purchase return se = webnotes.bean(copy=test_records[0]) se.doc.purpose = "Purchase Return" @@ -312,13 +459,13 @@ class TestStockEntry(unittest.TestCase): self.assertEquals(actual_qty_1 - 5, actual_qty_2) - return pr.doc.name + return se, pr.doc.name def test_over_stock_return(self): from stock.doctype.stock_entry.stock_entry import StockOverReturnError # out of 10, 5 gets returned - pr_docname = self.test_purchase_receipt_return() + prev_se, pr_docname = self.test_purchase_receipt_return() # submit purchase return - return another 6 qtys so that exception is raised se = webnotes.bean(copy=test_records[0]) @@ -329,7 +476,97 @@ class TestStockEntry(unittest.TestCase): se.doclist[1].s_warehouse = "_Test Warehouse" self.assertRaises(StockOverReturnError, se.insert) - + + def _test_purchase_return_jv(self, se, returned_value): + from stock.doctype.stock_entry.stock_entry import make_return_jv + jv_list = make_return_jv(se.doc.name) + + self.assertEqual(len(jv_list), 3) + self.assertEqual(jv_list[0].get("voucher_type"), "Debit Note") + self.assertEqual(jv_list[0].get("posting_date"), se.doc.posting_date) + self.assertEqual(jv_list[1].get("account"), "_Test Supplier - _TC") + self.assertEqual(jv_list[2].get("account"), "_Test Account Cost for Goods Sold - _TC") + self.assertTrue(jv_list[1].get("against_voucher")) + + # debit == credit + debit = sum([flt(d.get("debit")) for d in jv_list]) + credit = sum([flt(d.get("credit")) for d in jv_list]) + self.assertEqual(debit, credit) + + # validate value of credit + self.assertEqual(credit, returned_value) + + def test_make_return_jv_for_purchase_receipt(self): + se, pr_name = self.test_purchase_receipt_return() + self._test_purchase_return_jv(se, 250) + + se, pr_name = self._test_purchase_return_return_against_purchase_order() + self._test_purchase_return_jv(se, 250) + + def _test_purchase_return_return_against_purchase_order(self): + self._clear_stock() + + actual_qty_0 = self._get_actual_qty() + + from buying.doctype.purchase_order.test_purchase_order \ + import test_records as purchase_order_test_records + + # submit purchase receipt + po = webnotes.bean(copy=purchase_order_test_records[0]) + po.doc.is_subcontracted = None + po.doclist[1].item_code = "_Test Item" + po.doclist[1].import_rate = 50 + po.insert() + po.submit() + + pr_doclist = webnotes.map_doclist([ + ["Purchase Order", "Purchase Receipt"], + ["Purchase Order Item", "Purchase Receipt Item"], + ["Purchase Taxes and Charges", "Purchase Taxes and Charges"]], po.doc.name) + + pr = webnotes.bean(pr_doclist) + pr.doc.posting_date = po.doc.transaction_date + pr.insert() + pr.submit() + + actual_qty_1 = self._get_actual_qty() + + self.assertEquals(actual_qty_0 + 10, actual_qty_1) + + pi_doclist = webnotes.map_doclist([ + ["Purchase Order", "Purchase Invoice"], + ["Purchase Order Item", "Purchase Invoice Item"], + ["Purchase Taxes and Charges", "Purchase Taxes and Charges"]], po.doc.name) + + pi = webnotes.bean(pi_doclist) + pi.doc.posting_date = pr.doc.posting_date + pi.doc.credit_to = "_Test Supplier - _TC" + for d in pi.doclist.get({"parentfield": "entries"}): + d.expense_head = "_Test Account Cost for Goods Sold - _TC" + d.cost_center = "_Test Cost Center - _TC" + for d in pi.doclist.get({"parentfield": "purchase_tax_details"}): + d.cost_center = "_Test Cost Center - _TC" + + pi.run_method("calculate_taxes_and_totals") + pi.insert() + pi.submit() + + # submit purchase return + se = webnotes.bean(copy=test_records[0]) + se.doc.purpose = "Purchase Return" + se.doc.purchase_receipt_no = pr.doc.name + se.doc.posting_date = "2013-03-01" + se.doclist[1].qty = se.doclist[1].transfer_qty = 5 + se.doclist[1].s_warehouse = "_Test Warehouse" + se.insert() + se.submit() + + actual_qty_2 = self._get_actual_qty() + + self.assertEquals(actual_qty_1 - 5, actual_qty_2) + + return se, pr.doc.name + test_records = [ [ { From 080f9098c01d81d3c413a3e56c28692c5025ecdb Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Mon, 18 Mar 2013 17:57:59 +0530 Subject: [PATCH 08/19] deprecated sales and purchase return tool --- accounts/page/accounts_home/accounts_home.js | 6 - buying/page/buying_home/buying_home.js | 6 - home/page/latest_updates/latest_updates.js | 1 + .../p06_remove_sales_purchase_return_tool.py | 5 + patches/patch_list.py | 1 + .../__init__.py | 1 - .../locale/_messages_doc.json | 13 - .../locale/ar-doc.json | 13 - .../locale/de-doc.json | 13 - .../locale/es-doc.json | 13 - .../locale/fr-doc.json | 13 - .../locale/hi-doc.json | 13 - .../locale/hr-doc.json | 13 - .../locale/nl-doc.json | 13 - .../locale/pt-BR-doc.json | 13 - .../locale/pt-doc.json | 13 - .../locale/sr-doc.json | 13 - .../locale/ta-doc.json | 13 - .../locale/th-doc.json | 13 - .../sales_and_purchase_return_item.py | 22 -- .../sales_and_purchase_return_item.txt | 110 --------- selling/page/selling_home/selling_home.js | 6 - .../__init__.py | 1 - .../locale/_messages_doc.json | 21 -- .../locale/ar-doc.json | 21 -- .../locale/de-doc.json | 21 -- .../locale/es-doc.json | 21 -- .../locale/fr-doc.json | 21 -- .../locale/hi-doc.json | 21 -- .../locale/hr-doc.json | 21 -- .../locale/nl-doc.json | 21 -- .../locale/pt-BR-doc.json | 21 -- .../locale/pt-doc.json | 21 -- .../locale/sr-doc.json | 21 -- .../locale/ta-doc.json | 21 -- .../locale/th-doc.json | 21 -- .../sales_and_purchase_return_tool.js | 229 ------------------ .../sales_and_purchase_return_tool.py | 71 ------ .../sales_and_purchase_return_tool.txt | 191 --------------- stock/page/stock_home/stock_home.js | 6 - 40 files changed, 7 insertions(+), 1091 deletions(-) create mode 100644 patches/march_2013/p06_remove_sales_purchase_return_tool.py delete mode 100644 selling/doctype/sales_and_purchase_return_item/__init__.py delete mode 100644 selling/doctype/sales_and_purchase_return_item/locale/_messages_doc.json delete mode 100644 selling/doctype/sales_and_purchase_return_item/locale/ar-doc.json delete mode 100644 selling/doctype/sales_and_purchase_return_item/locale/de-doc.json delete mode 100644 selling/doctype/sales_and_purchase_return_item/locale/es-doc.json delete mode 100644 selling/doctype/sales_and_purchase_return_item/locale/fr-doc.json delete mode 100644 selling/doctype/sales_and_purchase_return_item/locale/hi-doc.json delete mode 100644 selling/doctype/sales_and_purchase_return_item/locale/hr-doc.json delete mode 100644 selling/doctype/sales_and_purchase_return_item/locale/nl-doc.json delete mode 100644 selling/doctype/sales_and_purchase_return_item/locale/pt-BR-doc.json delete mode 100644 selling/doctype/sales_and_purchase_return_item/locale/pt-doc.json delete mode 100644 selling/doctype/sales_and_purchase_return_item/locale/sr-doc.json delete mode 100644 selling/doctype/sales_and_purchase_return_item/locale/ta-doc.json delete mode 100644 selling/doctype/sales_and_purchase_return_item/locale/th-doc.json delete mode 100644 selling/doctype/sales_and_purchase_return_item/sales_and_purchase_return_item.py delete mode 100644 selling/doctype/sales_and_purchase_return_item/sales_and_purchase_return_item.txt delete mode 100644 stock/doctype/sales_and_purchase_return_tool/__init__.py delete mode 100644 stock/doctype/sales_and_purchase_return_tool/locale/_messages_doc.json delete mode 100644 stock/doctype/sales_and_purchase_return_tool/locale/ar-doc.json delete mode 100644 stock/doctype/sales_and_purchase_return_tool/locale/de-doc.json delete mode 100644 stock/doctype/sales_and_purchase_return_tool/locale/es-doc.json delete mode 100644 stock/doctype/sales_and_purchase_return_tool/locale/fr-doc.json delete mode 100644 stock/doctype/sales_and_purchase_return_tool/locale/hi-doc.json delete mode 100644 stock/doctype/sales_and_purchase_return_tool/locale/hr-doc.json delete mode 100644 stock/doctype/sales_and_purchase_return_tool/locale/nl-doc.json delete mode 100644 stock/doctype/sales_and_purchase_return_tool/locale/pt-BR-doc.json delete mode 100644 stock/doctype/sales_and_purchase_return_tool/locale/pt-doc.json delete mode 100644 stock/doctype/sales_and_purchase_return_tool/locale/sr-doc.json delete mode 100644 stock/doctype/sales_and_purchase_return_tool/locale/ta-doc.json delete mode 100644 stock/doctype/sales_and_purchase_return_tool/locale/th-doc.json delete mode 100644 stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.js delete mode 100644 stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.py delete mode 100644 stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.txt diff --git a/accounts/page/accounts_home/accounts_home.js b/accounts/page/accounts_home/accounts_home.js index f2faf93785..403d7bdb3f 100644 --- a/accounts/page/accounts_home/accounts_home.js +++ b/accounts/page/accounts_home/accounts_home.js @@ -63,12 +63,6 @@ wn.module_page["Accounts"] = [ "doctype": "Period Closing Voucher", description: "Close Balance Sheet and book Profit or Loss." }, - { - "route":"Form/Sales and Purchase Return Tool/Sales and Purchase Return Tool", - "label": wn._("Sales and Purchase Return Tool"), - description: wn._("Manage sales or purchase returns"), - "doctype": "Sales and Purchase Return Tool" - }, { "page":"voucher-import-tool", "label": wn._("Voucher Import Tool"), diff --git a/buying/page/buying_home/buying_home.js b/buying/page/buying_home/buying_home.js index 922e7acefa..2df5f6fb07 100644 --- a/buying/page/buying_home/buying_home.js +++ b/buying/page/buying_home/buying_home.js @@ -80,12 +80,6 @@ wn.module_page["Buying"] = [ title: wn._("Tools"), icon: "icon-wrench", items: [ - { - "route":"Form/Sales and Purchase Return Tool/Sales and Purchase Return Tool", - "label":wn._("Purchase Returns"), - "description":wn._("Helper for managing return of goods (sales or purchase)"), - doctype: "Sales and Purchase Return Tool" - }, ] }, { diff --git a/home/page/latest_updates/latest_updates.js b/home/page/latest_updates/latest_updates.js index 84db37287f..183352ce04 100644 --- a/home/page/latest_updates/latest_updates.js +++ b/home/page/latest_updates/latest_updates.js @@ -1,4 +1,5 @@ erpnext.updates = [ + ["19th March", ["Sales and Purchase Return Tool deprecated. Use Stock Entry instead."]], ["12th March", ["Updates to website module. Added more options in Style Settings and Website Settings."]], ["5th March", ["Refactored Upload Attendance Tool"]], ["4th March", ["Lead organization added in Quotation classic/spartan/modern print format"]], diff --git a/patches/march_2013/p06_remove_sales_purchase_return_tool.py b/patches/march_2013/p06_remove_sales_purchase_return_tool.py new file mode 100644 index 0000000000..e907e4a1c2 --- /dev/null +++ b/patches/march_2013/p06_remove_sales_purchase_return_tool.py @@ -0,0 +1,5 @@ +import webnotes + +def execute(): + webnotes.delete_doc("DocType", "Sales and Purchase Return Item") + webnotes.delete_doc("DocType", "Sales and Purchase Return Tool") \ No newline at end of file diff --git a/patches/patch_list.py b/patches/patch_list.py index 1120848535..236ef45fd2 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -213,4 +213,5 @@ patch_list = [ "execute:webnotes.reload_doc('hr', 'search_criteria', 'monthly_attendance_details')", "patches.march_2013.p04_pos_update_stock_check", "patches.march_2013.p05_payment_reconciliation", + "patches.march_2013.p06_remove_sales_purchase_return_tool", ] \ No newline at end of file diff --git a/selling/doctype/sales_and_purchase_return_item/__init__.py b/selling/doctype/sales_and_purchase_return_item/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/selling/doctype/sales_and_purchase_return_item/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/selling/doctype/sales_and_purchase_return_item/locale/_messages_doc.json b/selling/doctype/sales_and_purchase_return_item/locale/_messages_doc.json deleted file mode 100644 index 5129542747..0000000000 --- a/selling/doctype/sales_and_purchase_return_item/locale/_messages_doc.json +++ /dev/null @@ -1,13 +0,0 @@ -[ - "Selling", - "Description", - "Sales and Purchase Return Item", - "Qty", - "Serial No", - "Rate", - "Detail Name", - "Batch No", - "Returned Qty", - "Item Code", - "UOM" -] \ No newline at end of file diff --git a/selling/doctype/sales_and_purchase_return_item/locale/ar-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/ar-doc.json deleted file mode 100644 index 79de9e8203..0000000000 --- a/selling/doctype/sales_and_purchase_return_item/locale/ar-doc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Batch No": "\u0644\u0627 \u062f\u0641\u0639\u0629", - "Description": "\u0648\u0635\u0641", - "Detail Name": "\u0627\u0644\u0627\u0633\u0645", - "Item Code": "\u0627\u0644\u0628\u0646\u062f \u0627\u0644\u0631\u0645\u0632", - "Qty": "\u0627\u0644\u0643\u0645\u064a\u0629", - "Rate": "\u0645\u0639\u062f\u0644", - "Returned Qty": "\u0639\u0627\u062f \u0627\u0644\u0643\u0645\u064a\u0629", - "Sales and Purchase Return Item": "\u0645\u0628\u064a\u0639\u0627\u062a \u0648\u0634\u0631\u0627\u0621 \u0627\u0644\u0633\u0644\u0639\u0629 \u0627\u0644\u0639\u0648\u062f\u0629", - "Selling": "\u0628\u064a\u0639", - "Serial No": "\u0627\u0644\u0645\u0633\u0644\u0633\u0644 \u0644\u0627", - "UOM": "UOM" -} \ No newline at end of file diff --git a/selling/doctype/sales_and_purchase_return_item/locale/de-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/de-doc.json deleted file mode 100644 index bfcbf4e9ea..0000000000 --- a/selling/doctype/sales_and_purchase_return_item/locale/de-doc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Batch No": "Batch No", - "Description": "Beschreibung", - "Detail Name": "Detail Name", - "Item Code": "Item Code", - "Qty": "Menge", - "Rate": "Rate", - "Returned Qty": "Kehrte Menge", - "Sales and Purchase Return Item": "Sales and Purchase Zur\u00fcck Artikel", - "Selling": "Verkauf", - "Serial No": "Serial In", - "UOM": "UOM" -} \ No newline at end of file diff --git a/selling/doctype/sales_and_purchase_return_item/locale/es-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/es-doc.json deleted file mode 100644 index 189f5e9203..0000000000 --- a/selling/doctype/sales_and_purchase_return_item/locale/es-doc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Batch No": "Lote n \u00ba", - "Description": "Descripci\u00f3n", - "Detail Name": "Detalle Nombre", - "Item Code": "C\u00f3digo del art\u00edculo", - "Qty": "Cantidad", - "Rate": "Velocidad", - "Returned Qty": "Cantidad devuelta", - "Sales and Purchase Return Item": "Venta y Compra de art\u00edculo de vuelta", - "Selling": "De venta", - "Serial No": "N\u00famero de orden", - "UOM": "UOM" -} \ No newline at end of file diff --git a/selling/doctype/sales_and_purchase_return_item/locale/fr-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/fr-doc.json deleted file mode 100644 index 5064cd702a..0000000000 --- a/selling/doctype/sales_and_purchase_return_item/locale/fr-doc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Batch No": "Aucun lot", - "Description": "Description", - "Detail Name": "Nom de d\u00e9tails", - "Item Code": "Code de l'article", - "Qty": "Qt\u00e9", - "Rate": "Taux", - "Returned Qty": "Quantit\u00e9 retourn\u00e9e", - "Sales and Purchase Return Item": "Vente et achat du lot Retour", - "Selling": "Vente", - "Serial No": "N \u00b0 de s\u00e9rie", - "UOM": "Emballage" -} \ No newline at end of file diff --git a/selling/doctype/sales_and_purchase_return_item/locale/hi-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/hi-doc.json deleted file mode 100644 index 283b26642d..0000000000 --- a/selling/doctype/sales_and_purchase_return_item/locale/hi-doc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Batch No": "\u0915\u094b\u0908 \u092c\u0948\u091a", - "Description": "\u0935\u093f\u0935\u0930\u0923", - "Detail Name": "\u0935\u093f\u0938\u094d\u0924\u093e\u0930 \u0938\u0947 \u0928\u093e\u092e", - "Item Code": "\u0906\u0907\u091f\u092e \u0915\u094b\u0921", - "Qty": "\u092e\u093e\u0924\u094d\u0930\u093e", - "Rate": "\u0926\u0930", - "Returned Qty": "\u0935\u093e\u092a\u0938 \u0906 \u0917\u090f \u092e\u093e\u0924\u094d\u0930\u093e", - "Sales and Purchase Return Item": "\u092c\u093f\u0915\u094d\u0930\u0940 \u0914\u0930 \u0916\u0930\u0940\u0926 \u0915\u0947 \u092e\u0926 \u0935\u093e\u092a\u0938\u0940", - "Selling": "\u0935\u093f\u0915\u094d\u0930\u092f", - "Serial No": "\u0928\u0939\u0940\u0902 \u0938\u0940\u0930\u093f\u092f\u0932", - "UOM": "UOM" -} \ No newline at end of file diff --git a/selling/doctype/sales_and_purchase_return_item/locale/hr-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/hr-doc.json deleted file mode 100644 index 6d5ba064c2..0000000000 --- a/selling/doctype/sales_and_purchase_return_item/locale/hr-doc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Batch No": "Hrpa Ne", - "Description": "Opis", - "Detail Name": "Detalj Ime", - "Item Code": "Stavka \u0160ifra", - "Qty": "Kol", - "Rate": "Stopa", - "Returned Qty": "Vra\u0107eno Kol", - "Sales and Purchase Return Item": "Prodaja i kupnja Povratak Stavka", - "Selling": "Prodaja", - "Serial No": "Serijski br", - "UOM": "UOM" -} \ No newline at end of file diff --git a/selling/doctype/sales_and_purchase_return_item/locale/nl-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/nl-doc.json deleted file mode 100644 index 8fe31bea89..0000000000 --- a/selling/doctype/sales_and_purchase_return_item/locale/nl-doc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Batch No": "Batch nr.", - "Description": "Beschrijving", - "Detail Name": "Detail Naam", - "Item Code": "Artikelcode", - "Qty": "Aantal", - "Rate": "Tarief", - "Returned Qty": "Geretourneerde Aantal", - "Sales and Purchase Return Item": "Verkoop en Inkoop Return Item", - "Selling": "Selling", - "Serial No": "Serienummer", - "UOM": "Verpakking" -} \ No newline at end of file diff --git a/selling/doctype/sales_and_purchase_return_item/locale/pt-BR-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/pt-BR-doc.json deleted file mode 100644 index 3cc5b3441e..0000000000 --- a/selling/doctype/sales_and_purchase_return_item/locale/pt-BR-doc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Batch No": "N\u00ba do Lote", - "Description": "Descri\u00e7\u00e3o", - "Detail Name": "Nome do Detalhe", - "Item Code": "C\u00f3digo do Item", - "Qty": "Qtde.", - "Rate": "Taxa", - "Returned Qty": "Qtde. retornada", - "Sales and Purchase Return Item": "Item de retorno de compra e venda", - "Selling": "Vendas", - "Serial No": "N\u00ba de S\u00e9rie", - "UOM": "UDM" -} \ No newline at end of file diff --git a/selling/doctype/sales_and_purchase_return_item/locale/pt-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/pt-doc.json deleted file mode 100644 index 56340bc041..0000000000 --- a/selling/doctype/sales_and_purchase_return_item/locale/pt-doc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Batch No": "No lote", - "Description": "Descri\u00e7\u00e3o", - "Detail Name": "Nome detalhes", - "Item Code": "C\u00f3digo do artigo", - "Qty": "Qty", - "Rate": "Taxa", - "Returned Qty": "Qtde voltou", - "Sales and Purchase Return Item": "Vendas e item retorno de compra", - "Selling": "Vendendo", - "Serial No": "N \u00ba de S\u00e9rie", - "UOM": "UOM" -} \ No newline at end of file diff --git a/selling/doctype/sales_and_purchase_return_item/locale/sr-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/sr-doc.json deleted file mode 100644 index e507094727..0000000000 --- a/selling/doctype/sales_and_purchase_return_item/locale/sr-doc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Batch No": "\u0413\u0440\u0443\u043f\u043d\u043e \u041d\u0435\u043c\u0430", - "Description": "\u041e\u043f\u0438\u0441", - "Detail Name": "\u0414\u0435\u0442\u0430\u0459 \u0418\u043c\u0435", - "Item Code": "\u0428\u0438\u0444\u0440\u0430", - "Qty": "\u041a\u043e\u043b", - "Rate": "\u0421\u0442\u043e\u043f\u0430", - "Returned Qty": "\u0412\u0440\u0430\u045b\u0435\u043d\u0438 \u041a\u043e\u043b", - "Sales and Purchase Return Item": "\u041f\u0440\u043e\u0434\u0430\u0458\u0430 \u0438 \u043a\u0443\u043f\u043e\u0432\u0438\u043d\u0430 \u041f\u043e\u0432\u0440\u0430\u0442\u0430\u043a \u0430\u0443\u043a\u0446\u0438\u0458\u0438", - "Selling": "\u041f\u0440\u043e\u0434\u0430\u0458\u0430", - "Serial No": "\u0421\u0435\u0440\u0438\u0458\u0441\u043a\u0438 \u0431\u0440\u043e\u0458", - "UOM": "\u0423\u041e\u041c" -} \ No newline at end of file diff --git a/selling/doctype/sales_and_purchase_return_item/locale/ta-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/ta-doc.json deleted file mode 100644 index c60a0814c2..0000000000 --- a/selling/doctype/sales_and_purchase_return_item/locale/ta-doc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Batch No": "\u0ba4\u0bc6\u0bbe\u0b95\u0bc1\u0ba4\u0bbf \u0b87\u0bb2\u0bcd\u0bb2\u0bc8", - "Description": "\u0bb5\u0bbf\u0bb3\u0b95\u0bcd\u0b95\u0bae\u0bcd", - "Detail Name": "\u0bb5\u0bbf\u0bb0\u0bbf\u0bb5\u0bbe\u0b95 \u0baa\u0bc6\u0baf\u0bb0\u0bcd", - "Item Code": "\u0b89\u0bb0\u0bc1\u0baa\u0bcd\u0baa\u0b9f\u0bbf\u0baf\u0bc8 \u0b95\u0bc7\u0bbe\u0b9f\u0bcd", - "Qty": "\u0b85\u0bb3\u0bb5\u0bc1", - "Rate": "\u0bb5\u0bbf\u0bb2\u0bc8", - "Returned Qty": "\u0ba4\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa\u0bbf \u0b85\u0bb3\u0bb5\u0bc1", - "Sales and Purchase Return Item": "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 \u0bae\u0bb1\u0bcd\u0bb1\u0bc1\u0bae\u0bcd \u0b95\u0bc6\u0bbe\u0bb3\u0bcd\u0bae\u0bc1\u0ba4\u0bb2\u0bcd \u0ba4\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa \u0b89\u0bb0\u0bc1\u0baa\u0bcd\u0baa\u0b9f\u0bbf", - "Selling": "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8", - "Serial No": "\u0b87\u0bb2\u0bcd\u0bb2\u0bc8 \u0ba4\u0bc6\u0bbe\u0b9f\u0bb0\u0bcd", - "UOM": "\u0bae\u0bc6\u0bbe\u0bb1\u0b9f\u0bcd\u0b9f\u0bc1\u0bb5 \u0baa\u0bb2\u0bcd\u0b95\u0bb2\u0bc8\u0b95\u0bb4\u0b95\u0bae\u0bcd" -} \ No newline at end of file diff --git a/selling/doctype/sales_and_purchase_return_item/locale/th-doc.json b/selling/doctype/sales_and_purchase_return_item/locale/th-doc.json deleted file mode 100644 index b47f740a3a..0000000000 --- a/selling/doctype/sales_and_purchase_return_item/locale/th-doc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "Batch No": "\u0e0a\u0e38\u0e14\u0e44\u0e21\u0e48\u0e21\u0e35", - "Description": "\u0e25\u0e31\u0e01\u0e29\u0e13\u0e30", - "Detail Name": "\u0e0a\u0e37\u0e48\u0e2d\u0e23\u0e32\u0e22\u0e25\u0e30\u0e40\u0e2d\u0e35\u0e22\u0e14", - "Item Code": "\u0e23\u0e2b\u0e31\u0e2a\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32", - "Qty": "\u0e08\u0e33\u0e19\u0e27\u0e19", - "Rate": "\u0e2d\u0e31\u0e15\u0e23\u0e32", - "Returned Qty": "\u0e08\u0e33\u0e19\u0e27\u0e19\u0e01\u0e25\u0e31\u0e1a", - "Sales and Purchase Return Item": "\u0e01\u0e32\u0e23\u0e02\u0e32\u0e22\u0e41\u0e25\u0e30\u0e01\u0e32\u0e23\u0e0b\u0e37\u0e49\u0e2d\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32\u0e01\u0e25\u0e31\u0e1a", - "Selling": "\u0e02\u0e32\u0e22", - "Serial No": "\u0e2d\u0e19\u0e38\u0e01\u0e23\u0e21\u0e44\u0e21\u0e48\u0e21\u0e35", - "UOM": "UOM" -} \ No newline at end of file diff --git a/selling/doctype/sales_and_purchase_return_item/sales_and_purchase_return_item.py b/selling/doctype/sales_and_purchase_return_item/sales_and_purchase_return_item.py deleted file mode 100644 index 7f48feb2eb..0000000000 --- a/selling/doctype/sales_and_purchase_return_item/sales_and_purchase_return_item.py +++ /dev/null @@ -1,22 +0,0 @@ -# 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 - -class DocType: - def __init__(self, d, dl): - self.doc, self.doclist = d, dl \ No newline at end of file diff --git a/selling/doctype/sales_and_purchase_return_item/sales_and_purchase_return_item.txt b/selling/doctype/sales_and_purchase_return_item/sales_and_purchase_return_item.txt deleted file mode 100644 index 4f844b3158..0000000000 --- a/selling/doctype/sales_and_purchase_return_item/sales_and_purchase_return_item.txt +++ /dev/null @@ -1,110 +0,0 @@ -[ - { - "creation": "2013-02-22 01:27:52", - "docstatus": 0, - "modified": "2013-03-07 07:03:30", - "modified_by": "Administrator", - "owner": "wasim@webnotestech.com" - }, - { - "doctype": "DocType", - "istable": 1, - "module": "Selling", - "name": "__common__" - }, - { - "doctype": "DocField", - "name": "__common__", - "parent": "Sales and Purchase Return Item", - "parentfield": "fields", - "parenttype": "DocType", - "permlevel": 0 - }, - { - "doctype": "DocType", - "name": "Sales and Purchase Return Item" - }, - { - "doctype": "DocField", - "fieldname": "item_code", - "fieldtype": "Link", - "label": "Item Code", - "oldfieldname": "item_code", - "oldfieldtype": "Link", - "options": "Item", - "read_only": 1, - "reqd": 1 - }, - { - "doctype": "DocField", - "fieldname": "description", - "fieldtype": "Data", - "label": "Description", - "oldfieldname": "description", - "oldfieldtype": "Data", - "print_width": "300px", - "read_only": 1, - "width": "300px" - }, - { - "doctype": "DocField", - "fieldname": "uom", - "fieldtype": "Link", - "label": "UOM", - "oldfieldname": "uom", - "oldfieldtype": "Link", - "options": "UOM", - "read_only": 1, - "search_index": 0 - }, - { - "doctype": "DocField", - "fieldname": "rate", - "fieldtype": "Currency", - "label": "Rate", - "oldfieldname": "rate", - "oldfieldtype": "Currency", - "options": "Company:company:default_currency", - "read_only": 1 - }, - { - "doctype": "DocField", - "fieldname": "qty", - "fieldtype": "Data", - "label": "Qty", - "oldfieldname": "qty", - "oldfieldtype": "Data", - "read_only": 1 - }, - { - "doctype": "DocField", - "fieldname": "returned_qty", - "fieldtype": "Data", - "label": "Returned Qty", - "oldfieldname": "returned_qty", - "oldfieldtype": "Data", - "reqd": 1 - }, - { - "doctype": "DocField", - "fieldname": "serial_no", - "fieldtype": "Small Text", - "label": "Serial No" - }, - { - "doctype": "DocField", - "fieldname": "batch_no", - "fieldtype": "Data", - "label": "Batch No" - }, - { - "doctype": "DocField", - "fieldname": "detail_name", - "fieldtype": "Data", - "hidden": 1, - "label": "Detail Name", - "oldfieldname": "detail_name", - "oldfieldtype": "Data", - "read_only": 1 - } -] \ No newline at end of file diff --git a/selling/page/selling_home/selling_home.js b/selling/page/selling_home/selling_home.js index 7af9b71eb7..994bb4a555 100644 --- a/selling/page/selling_home/selling_home.js +++ b/selling/page/selling_home/selling_home.js @@ -120,12 +120,6 @@ wn.module_page["Selling"] = [ title: wn._("Tools"), icon: "icon-wrench", items: [ - { - "route":"Form/Sales and Purchase Return Tool/Sales and Purchase Return Tool", - "label":wn._("Sales Returns"), - "description":wn._("Helper for managing return of goods (sales or purchase)"), - doctype: "Sales and Purchase Return Tool" - }, { "route":"Form/SMS Center/SMS Center", "label":wn._("SMS Center"), diff --git a/stock/doctype/sales_and_purchase_return_tool/__init__.py b/stock/doctype/sales_and_purchase_return_tool/__init__.py deleted file mode 100644 index baffc48825..0000000000 --- a/stock/doctype/sales_and_purchase_return_tool/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from __future__ import unicode_literals diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/_messages_doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/_messages_doc.json deleted file mode 100644 index 979f20fc1e..0000000000 --- a/stock/doctype/sales_and_purchase_return_tool/locale/_messages_doc.json +++ /dev/null @@ -1,21 +0,0 @@ -[ - "Make Credit Note", - "Make Excise Invoice", - "Sales Return", - "Get Items", - "Delivery Note No", - "Company", - "Customer/Supplier", - "Sales and Purchase Return Tool", - "Make Debit Note", - "Cust/Supp Address", - "Sales Invoice No", - "Make Stock Entry", - "Purchase Receipt No", - "Purchase Return", - "Sales and Purchase Return Items", - "Return Date", - "Cust/Supp Name", - "Return Type", - "Stock" -] \ No newline at end of file diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/ar-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/ar-doc.json deleted file mode 100644 index d11ece6797..0000000000 --- a/stock/doctype/sales_and_purchase_return_tool/locale/ar-doc.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "Company": "\u0634\u0631\u0643\u0629", - "Cust/Supp Address": "\u0627\u0644\u0632\u0628\u0648\u0646 / \u0627\u0644\u0645\u0644\u062d\u0642 \u0627\u0644\u0639\u0646\u0648\u0627\u0646", - "Cust/Supp Name": "\u0627\u0644\u0632\u0628\u0648\u0646 / \u0627\u0644\u0645\u0644\u062d\u0642 \u0627\u0633\u0645", - "Customer/Supplier": "\u0627\u0644\u0639\u0645\u064a\u0644 / \u0645\u0632\u0648\u062f", - "Delivery Note No": "\u0645\u0644\u0627\u062d\u0638\u0629 \u0644\u0627 \u062a\u0633\u0644\u064a\u0645", - "Get Items": "\u0627\u0644\u062d\u0635\u0648\u0644 \u0639\u0644\u0649 \u0627\u0644\u0639\u0646\u0627\u0635\u0631", - "Make Credit Note": "\u062c\u0639\u0644 \u0627\u0644\u0627\u0626\u062a\u0645\u0627\u0646\u064a", - "Make Debit Note": "\u0645\u0644\u0627\u062d\u0638\u0629 \u062c\u0639\u0644 \u0627\u0644\u062e\u0635\u0645", - "Make Excise Invoice": "\u062c\u0639\u0644 \u0627\u0644\u0641\u0627\u062a\u0648\u0631\u0629 \u0627\u0644\u0645\u0643\u0648\u0633", - "Make Stock Entry": "\u062c\u0639\u0644 \u0627\u0644\u062f\u062e\u0648\u0644 \u0644\u0644\u0633\u0647\u0645", - "Purchase Receipt No": "\u0644\u0627 \u0634\u0631\u0627\u0621 \u0627\u0633\u062a\u0644\u0627\u0645", - "Purchase Return": "\u0634\u0631\u0627\u0621 \u0627\u0644\u0639\u0648\u062f\u0629", - "Return Date": "\u0627\u0644\u0639\u0648\u062f\u0629 \u062a\u0627\u0631\u064a\u062e", - "Return Type": "\u0627\u0644\u0639\u0648\u062f\u0629 \u0646\u0648\u0639", - "Sales Invoice No": "\u0641\u0627\u062a\u0648\u0631\u0629 \u0645\u0628\u064a\u0639\u0627\u062a \u0644\u0627", - "Sales Return": "\u0645\u0628\u064a\u0639\u0627\u062a \u0627\u0644\u0639\u0648\u062f\u0629", - "Sales and Purchase Return Items": "\u0645\u0627\u062f\u0629 \u0639\u0627\u0626\u062f \u0627\u0644\u0645\u0628\u064a\u0639\u0627\u062a \u0648\u0627\u0644\u0645\u0634\u062a\u0631\u064a\u0627\u062a", - "Sales and Purchase Return Tool": "\u0645\u0628\u064a\u0639\u0627\u062a \u0648\u0634\u0631\u0627\u0621 \u0623\u062f\u0627\u0629 \u0627\u0644\u0639\u0648\u062f\u0629", - "Stock": "\u0627\u0644\u0623\u0648\u0631\u0627\u0642 \u0627\u0644\u0645\u0627\u0644\u064a\u0629" -} \ No newline at end of file diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/de-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/de-doc.json deleted file mode 100644 index 9bd8c9af40..0000000000 --- a/stock/doctype/sales_and_purchase_return_tool/locale/de-doc.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "Company": "Firma", - "Cust/Supp Address": "Cust / Supp Adresse", - "Cust/Supp Name": "Cust / Supp Namen", - "Customer/Supplier": "Kunde / Lieferant", - "Delivery Note No": "Lieferschein Nein", - "Get Items": "Holen Artikel", - "Make Credit Note": "Machen Gutschrift", - "Make Debit Note": "Machen Lastschrift", - "Make Excise Invoice": "Machen Excise Rechnung", - "Make Stock Entry": "Machen Eintrag Stock", - "Purchase Receipt No": "Kaufbeleg", - "Purchase Return": "Kauf zur\u00fcckgeben", - "Return Date": "Zur\u00fcck Datum", - "Return Type": "R\u00fcckgabetyp", - "Sales Invoice No": "Sales Invoice In", - "Sales Return": "Umsatzrendite", - "Sales and Purchase Return Items": "Verkauf und Kauf zur\u00fccksenden Artikel", - "Sales and Purchase Return Tool": "Sales and Purchase Return-Tool", - "Stock": "Lager" -} \ No newline at end of file diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/es-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/es-doc.json deleted file mode 100644 index ac4404951b..0000000000 --- a/stock/doctype/sales_and_purchase_return_tool/locale/es-doc.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "Company": "Empresa", - "Cust/Supp Address": "Cust / Supp Direcci\u00f3n", - "Cust/Supp Name": "Cust / Supp Nombre", - "Customer/Supplier": "Cliente / Proveedor", - "Delivery Note No": "Entrega Nota No", - "Get Items": "Obtener elementos", - "Make Credit Note": "Hacer Nota de Cr\u00e9dito", - "Make Debit Note": "Hacer Nota de D\u00e9bito", - "Make Excise Invoice": "Hacer Factura Impuestos Especiales", - "Make Stock Entry": "Hacer de la entrada", - "Purchase Receipt No": "No recibo de compra", - "Purchase Return": "Comprar Volver", - "Return Date": "Fecha de regreso", - "Return Type": "Devuelto", - "Sales Invoice No": "Ventas factura n \u00ba", - "Sales Return": "Ventas Retorno", - "Sales and Purchase Return Items": "Ventas y comprar art\u00edculos de Retorno", - "Sales and Purchase Return Tool": "Herramienta de ventas y devoluci\u00f3n de compra", - "Stock": "Valores" -} \ No newline at end of file diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/fr-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/fr-doc.json deleted file mode 100644 index c3fc153a39..0000000000 --- a/stock/doctype/sales_and_purchase_return_tool/locale/fr-doc.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "Company": "Entreprise", - "Cust/Supp Address": "Cust / Supp Adresse", - "Cust/Supp Name": "Cust / Supp Nom", - "Customer/Supplier": "Client / Fournisseur", - "Delivery Note No": "Remarque Aucune livraison", - "Get Items": "Obtenir les \u00e9l\u00e9ments", - "Make Credit Note": "Assurez note de cr\u00e9dit", - "Make Debit Note": "Assurez note de d\u00e9bit", - "Make Excise Invoice": "Assurez facture d'accise", - "Make Stock Entry": "Assurez Entr\u00e9e Stock", - "Purchase Receipt No": "Achetez un accus\u00e9 de r\u00e9ception", - "Purchase Return": "Achat de retour", - "Return Date": "Date de retour", - "Return Type": "Retour Type", - "Sales Invoice No": "Aucune facture de vente", - "Sales Return": "Ventes de retour", - "Sales and Purchase Return Items": "Ventes et articles de retour d'achat", - "Sales and Purchase Return Tool": "Outil de vente et de retour d'achat", - "Stock": "Stock" -} \ No newline at end of file diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/hi-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/hi-doc.json deleted file mode 100644 index b407775aa4..0000000000 --- a/stock/doctype/sales_and_purchase_return_tool/locale/hi-doc.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "Company": "\u0915\u0902\u092a\u0928\u0940", - "Cust/Supp Address": "Cust / Supp \u092a\u0924\u093e", - "Cust/Supp Name": "Cust / Supp \u0928\u093e\u092e", - "Customer/Supplier": "\u0917\u094d\u0930\u093e\u0939\u0915 / \u0906\u092a\u0942\u0930\u094d\u0924\u093f\u0915\u0930\u094d\u0924\u093e", - "Delivery Note No": "\u0921\u093f\u0932\u093f\u0935\u0930\u0940 \u0928\u094b\u091f", - "Get Items": "\u0906\u0907\u091f\u092e \u092a\u093e\u0928\u0947 \u0915\u0947 \u0932\u093f\u090f", - "Make Credit Note": "\u0915\u094d\u0930\u0947\u0921\u093f\u091f \u0928\u094b\u091f", - "Make Debit Note": "\u0921\u0947\u092c\u093f\u091f \u0928\u094b\u091f", - "Make Excise Invoice": "\u0909\u0924\u094d\u092a\u093e\u0926 \u0936\u0941\u0932\u094d\u0915 \u091a\u093e\u0932\u093e\u0928", - "Make Stock Entry": "\u0938\u094d\u091f\u0949\u0915 \u090f\u0902\u091f\u094d\u0930\u0940", - "Purchase Receipt No": "\u0930\u0938\u0940\u0926 \u0916\u0930\u0940\u0926 \u0928\u0939\u0940\u0902", - "Purchase Return": "\u0915\u094d\u0930\u092f \u0935\u093e\u092a\u0938\u0940", - "Return Date": "\u0924\u093f\u0925\u093f \u0932\u094c\u091f\u0947\u0902", - "Return Type": "\u092a\u094d\u0930\u0915\u093e\u0930 \u0932\u094c\u091f\u0947\u0902", - "Sales Invoice No": "\u092c\u093f\u0915\u094d\u0930\u0940 \u091a\u093e\u0932\u093e\u0928 \u0928\u0939\u0940\u0902", - "Sales Return": "\u092c\u093f\u0915\u094d\u0930\u0940 \u0932\u094c\u091f\u0947\u0902", - "Sales and Purchase Return Items": "\u092c\u093f\u0915\u094d\u0930\u0940 \u0914\u0930 \u0916\u0930\u0940\u0926 \u0915\u0947 \u0930\u093f\u091f\u0930\u094d\u0928 \u0906\u0907\u091f\u092e", - "Sales and Purchase Return Tool": "\u092c\u093f\u0915\u094d\u0930\u0940 \u0914\u0930 \u0916\u0930\u0940\u0926 \u0915\u0947 \u0930\u093f\u091f\u0930\u094d\u0928 \u091f\u0942\u0932", - "Stock": "\u0938\u094d\u091f\u0949\u0915" -} \ No newline at end of file diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/hr-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/hr-doc.json deleted file mode 100644 index aa579a9565..0000000000 --- a/stock/doctype/sales_and_purchase_return_tool/locale/hr-doc.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "Company": "Dru\u0161tvo", - "Cust/Supp Address": "Cust / Supp Adresa", - "Cust/Supp Name": "Cust / Supp Ime", - "Customer/Supplier": "Kupac / Dobavlja\u010d", - "Delivery Note No": "Dostava Napomena Ne", - "Get Items": "Nabavite artikle", - "Make Credit Note": "Napravite Credit Note", - "Make Debit Note": "Napravite tere\u0107enju", - "Make Excise Invoice": "Napravite tro\u0161arinama fakture", - "Make Stock Entry": "Napravite Stock Entry", - "Purchase Receipt No": "Ra\u010dun kupnje Ne", - "Purchase Return": "Kupnja Povratak", - "Return Date": "Povratak Datum", - "Return Type": "Povratak Vid", - "Sales Invoice No": "Prodaja Ra\u010dun br", - "Sales Return": "Prodaje Povratak", - "Sales and Purchase Return Items": "Prodaja i kupnja Povratak Stavke", - "Sales and Purchase Return Tool": "Prodaja i kupnja Povratak Tool", - "Stock": "Zaliha" -} \ No newline at end of file diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/nl-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/nl-doc.json deleted file mode 100644 index fd586c1e18..0000000000 --- a/stock/doctype/sales_and_purchase_return_tool/locale/nl-doc.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "Company": "Vennootschap", - "Cust/Supp Address": "Cust / Supp Adres", - "Cust/Supp Name": "Cust / Supp Naam", - "Customer/Supplier": "Klant / leverancier", - "Delivery Note No": "Levering aantekening", - "Get Items": "Get Items", - "Make Credit Note": "Maak Creditnota", - "Make Debit Note": "Maak debetnota", - "Make Excise Invoice": "Maak Accijnzen Factuur", - "Make Stock Entry": "Maak Stock Entry", - "Purchase Receipt No": "Aankoopbewijs Geen", - "Purchase Return": "Aankoop Return", - "Return Date": "Keer terug Datum", - "Return Type": "Terug Type", - "Sales Invoice No": "Verkoop Factuur nr.", - "Sales Return": "Verkoop Terug", - "Sales and Purchase Return Items": "Verkoop en Inkoop Return Items", - "Sales and Purchase Return Tool": "Verkoop en Inkoop Return Tool", - "Stock": "Voorraad" -} \ No newline at end of file diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/pt-BR-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/pt-BR-doc.json deleted file mode 100644 index f218bfa7c8..0000000000 --- a/stock/doctype/sales_and_purchase_return_tool/locale/pt-BR-doc.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "Company": "Empresa", - "Cust/Supp Address": "Endere\u00e7o do Cliente/Fornecedor", - "Cust/Supp Name": "Nome do Cliente/Fornecedor", - "Customer/Supplier": "Cliente / Fornecedor", - "Delivery Note No": "N\u00ba da Guia de Remessa", - "Get Items": "Obter itens", - "Make Credit Note": "Fazer Nota de Cr\u00e9dito", - "Make Debit Note": "Fazer Nota de D\u00e9bito", - "Make Excise Invoice": "Fazer fatura de imposto", - "Make Stock Entry": "Fazer lan\u00e7amento de estoque", - "Purchase Receipt No": "N\u00ba do Recibo de Compra", - "Purchase Return": "Devolu\u00e7\u00e3o de Compra", - "Return Date": "Data de retorno", - "Return Type": "Tipo de retorno", - "Sales Invoice No": "N\u00ba da Nota Fiscal de Venda", - "Sales Return": "Retorno de Vendas", - "Sales and Purchase Return Items": "Itens de retorno de compra e venda", - "Sales and Purchase Return Tool": "Ferramenta de retorno de compra e venda", - "Stock": "Estoque" -} \ No newline at end of file diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/pt-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/pt-doc.json deleted file mode 100644 index ce3685ed1c..0000000000 --- a/stock/doctype/sales_and_purchase_return_tool/locale/pt-doc.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "Company": "Companhia", - "Cust/Supp Address": "Cust / Supp Endere\u00e7o", - "Cust/Supp Name": "Cust / Supp Nome", - "Customer/Supplier": "Cliente / Fornecedor", - "Delivery Note No": "Nota de Entrega N\u00e3o", - "Get Items": "Obter itens", - "Make Credit Note": "Fa\u00e7a Nota de Cr\u00e9dito", - "Make Debit Note": "Fa\u00e7a Nota de D\u00e9bito", - "Make Excise Invoice": "Fa\u00e7a fatura Excise", - "Make Stock Entry": "Fa\u00e7a entrada de material", - "Purchase Receipt No": "Compra recibo N\u00e3o", - "Purchase Return": "Voltar comprar", - "Return Date": "Data de regresso", - "Return Type": "Tipo de retorno", - "Sales Invoice No": "Vendas factura n", - "Sales Return": "Vendas Retorno", - "Sales and Purchase Return Items": "Vendas e itens de retorno de Compra", - "Sales and Purchase Return Tool": "Ferramenta de vendas e retorno de compra", - "Stock": "Estoque" -} \ No newline at end of file diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/sr-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/sr-doc.json deleted file mode 100644 index 4903a9fab0..0000000000 --- a/stock/doctype/sales_and_purchase_return_tool/locale/sr-doc.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "Company": "\u041a\u043e\u043c\u043f\u0430\u043d\u0438\u0458\u0430", - "Cust/Supp Address": "\u041a\u043e\u0440\u0438\u0441\u043d\u0438\u0447\u043a\u0430 / \u0421\u0443\u043f\u043f \u0410\u0434\u0440\u0435\u0441\u0430", - "Cust/Supp Name": "\u041a\u043e\u0440\u0438\u0441\u043d\u0438\u0447\u043a\u0430 / \u0421\u0443\u043f\u043f \u0418\u043c\u0435", - "Customer/Supplier": "\u041a\u043e\u0440\u0438\u0441\u043d\u0438\u0447\u043a\u0438 / \u0414\u043e\u0431\u0430\u0432\u0459\u0430\u0447", - "Delivery Note No": "\u0418\u0441\u043f\u043e\u0440\u0443\u043a\u0430 \u041d\u0430\u043f\u043e\u043c\u0435\u043d\u0430 \u041d\u0435", - "Get Items": "\u0413\u0435\u0442 \u0441\u0442\u0430\u0432\u043a\u0435", - "Make Credit Note": "\u041d\u0430\u043f\u0440\u0430\u0432\u0438\u0442\u0435 \u041d\u043e\u0442\u0435 \u0426\u0440\u0435\u0434\u0438\u0442", - "Make Debit Note": "\u041d\u0430\u043f\u0440\u0430\u0432\u0438\u0442\u0435 \u0437\u0430\u0434\u0443\u0436\u0435\u045a\u0443", - "Make Excise Invoice": "\u041d\u0430\u043f\u0440\u0430\u0432\u0438\u0442\u0435 \u0430\u043a\u0446\u0438\u0437\u0430\u043c\u0430 \u0444\u0430\u043a\u0442\u0443\u0440\u0443", - "Make Stock Entry": "\u041d\u0430\u043f\u0440\u0430\u0432\u0438\u0442\u0435 \u0443\u043d\u043e\u0441 \u0421\u0442\u043e\u0446\u043a", - "Purchase Receipt No": "\u041a\u0443\u043f\u043e\u0432\u0438\u043d\u0430 \u041f\u0440\u0438\u0458\u0435\u043c \u041d\u0435\u043c\u0430", - "Purchase Return": "\u041a\u0443\u043f\u043e\u0432\u0438\u043d\u0430 \u0420\u0435\u0442\u0443\u0440\u043d", - "Return Date": "\u0420\u0435\u0442\u0443\u0440\u043d \u0414\u0430\u0442\u0435", - "Return Type": "\u041f\u043e\u0432\u0440\u0430\u0442\u0430\u043a \u0412\u0438\u0434", - "Sales Invoice No": "\u041f\u0440\u043e\u0434\u0430\u0458\u0430 \u0420\u0430\u0447\u0443\u043d \u041d\u0435\u043c\u0430", - "Sales Return": "\u041f\u0440\u043e\u0434\u0430\u0458\u0430 \u0420\u0435\u0442\u0443\u0440\u043d", - "Sales and Purchase Return Items": "\u041f\u0440\u043e\u0434\u0430\u0458\u0430 \u0438 \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u0438 \u041f\u043e\u0432\u0440\u0430\u0442\u0430\u043a \u041a\u0443\u043f\u043e\u0432\u0438\u043d\u0430", - "Sales and Purchase Return Tool": "\u041f\u0440\u043e\u0434\u0430\u0458\u0430 \u0438 \u043a\u0443\u043f\u043e\u0432\u0438\u043d\u0430 \u0430\u043b\u0430\u0442\u0430 \u041f\u043e\u0432\u0440\u0430\u0442\u0430\u043a", - "Stock": "\u0417\u0430\u043b\u0438\u0445\u0430" -} \ No newline at end of file diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/ta-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/ta-doc.json deleted file mode 100644 index 4d1ddc3a3f..0000000000 --- a/stock/doctype/sales_and_purchase_return_tool/locale/ta-doc.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "Company": "\u0ba8\u0bbf\u0bb1\u0bc1\u0bb5\u0ba9\u0bae\u0bcd", - "Cust/Supp Address": "Cust / \u0b9a\u0baa\u0bcd \u0bae\u0bc1\u0b95\u0bb5\u0bb0\u0bbf", - "Cust/Supp Name": "Cust / \u0b9a\u0baa\u0bcd \u0baa\u0bc6\u0baf\u0bb0\u0bcd", - "Customer/Supplier": "\u0bb5\u0bbe\u0b9f\u0bbf\u0b95\u0bcd\u0b95\u0bc8\u0baf\u0bbe\u0bb3\u0bb0\u0bcd / \u0b9a\u0baa\u0bcd\u0bb3\u0bc8\u0baf\u0bb0\u0bcd", - "Delivery Note No": "\u0b9f\u0bc6\u0bb2\u0bbf\u0bb5\u0bb0\u0bbf \u0b95\u0bc1\u0bb1\u0bbf\u0baa\u0bcd\u0baa\u0bc1 \u0b87\u0bb2\u0bcd\u0bb2\u0bc8", - "Get Items": "\u0baa\u0bc6\u0bbe\u0bb0\u0bc1\u0b9f\u0bcd\u0b95\u0bb3\u0bcd \u0b95\u0bbf\u0b9f\u0bc8\u0b95\u0bcd\u0b95\u0bc1\u0bae\u0bcd", - "Make Credit Note": "\u0b95\u0b9f\u0ba9\u0bcd \u0b95\u0bc1\u0bb1\u0bbf\u0baa\u0bcd\u0baa\u0bc1 \u0b9a\u0bc6\u0baf\u0bcd\u0baf", - "Make Debit Note": "\u0baa\u0bb1\u0bcd\u0bb1\u0bc1 \u0b95\u0bc1\u0bb1\u0bbf\u0baa\u0bcd\u0baa\u0bc1 \u0b9a\u0bc6\u0baf\u0bcd\u0baf", - "Make Excise Invoice": "\u0bae\u0ba4\u0bc1\u0bb5\u0bb0\u0bbf \u0bb5\u0bbf\u0bb2\u0bc8\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0bbf\u0baf\u0bb2\u0bcd \u0bb5\u0bc8\u0b95\u0bcd\u0b95", - "Make Stock Entry": "\u0baa\u0b99\u0bcd\u0b95\u0bc1 \u0ba8\u0bc1\u0bb4\u0bc8\u0bb5\u0bc1 \u0b9a\u0bc6\u0baf\u0bcd\u0baf", - "Purchase Receipt No": "\u0b87\u0bb2\u0bcd\u0bb2\u0bc8 \u0b9a\u0bc0\u0b9f\u0bcd\u0b9f\u0bc1 \u0bb5\u0bbe\u0b99\u0bcd\u0b95", - "Purchase Return": "\u0ba4\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa \u0bb5\u0bbe\u0b99\u0bcd\u0b95", - "Return Date": "\u0ba4\u0bc7\u0ba4\u0bbf \u0ba4\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa\u0bbf", - "Return Type": "\u0bb5\u0b95\u0bc8 \u0ba4\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa", - "Sales Invoice No": "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 \u0bb5\u0bbf\u0bb2\u0bc8\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0bbf\u0baf\u0bb2\u0bcd \u0b87\u0bb2\u0bcd\u0bb2\u0bc8", - "Sales Return": "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 Return", - "Sales and Purchase Return Items": "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 \u0bae\u0bb1\u0bcd\u0bb1\u0bc1\u0bae\u0bcd \u0b95\u0bc6\u0bbe\u0bb3\u0bcd\u0bae\u0bc1\u0ba4\u0bb2\u0bcd \u0ba4\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa \u0b89\u0bb0\u0bc1\u0baa\u0bcd\u0baa\u0b9f\u0bbf\u0b95\u0bb3\u0bcd", - "Sales and Purchase Return Tool": "\u0bb5\u0bbf\u0bb1\u0bcd\u0baa\u0ba9\u0bc8 \u0bae\u0bb1\u0bcd\u0bb1\u0bc1\u0bae\u0bcd \u0b95\u0bc6\u0bbe\u0bb3\u0bcd\u0bae\u0bc1\u0ba4\u0bb2\u0bcd \u0ba4\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa \u0b95\u0bb0\u0bc1\u0bb5\u0bbf", - "Stock": "\u0baa\u0b99\u0bcd\u0b95\u0bc1" -} \ No newline at end of file diff --git a/stock/doctype/sales_and_purchase_return_tool/locale/th-doc.json b/stock/doctype/sales_and_purchase_return_tool/locale/th-doc.json deleted file mode 100644 index 732dfd75ca..0000000000 --- a/stock/doctype/sales_and_purchase_return_tool/locale/th-doc.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "Company": "\u0e1a\u0e23\u0e34\u0e29\u0e31\u0e17", - "Cust/Supp Address": "\u0e17\u0e35\u0e48\u0e2d\u0e22\u0e39\u0e48 cust / Supp", - "Cust/Supp Name": "\u0e0a\u0e37\u0e48\u0e2d cust / Supp", - "Customer/Supplier": "\u0e25\u0e39\u0e01\u0e04\u0e49\u0e32 / \u0e1c\u0e39\u0e49\u0e1c\u0e25\u0e34\u0e15", - "Delivery Note No": "\u0e2b\u0e21\u0e32\u0e22\u0e40\u0e2b\u0e15\u0e38\u0e08\u0e31\u0e14\u0e2a\u0e48\u0e07\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32\u0e44\u0e21\u0e48\u0e21\u0e35", - "Get Items": "\u0e23\u0e31\u0e1a\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32", - "Make Credit Note": "\u0e43\u0e2b\u0e49\u0e08\u0e14\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e40\u0e04\u0e23\u0e14\u0e34\u0e15", - "Make Debit Note": "\u0e43\u0e2b\u0e49\u0e08\u0e14\u0e1a\u0e31\u0e19\u0e17\u0e36\u0e01\u0e40\u0e14\u0e1a\u0e34\u0e15", - "Make Excise Invoice": "\u0e17\u0e33\u0e43\u0e2b\u0e49\u0e43\u0e1a\u0e41\u0e08\u0e49\u0e07\u0e2b\u0e19\u0e35\u0e49\u0e2a\u0e23\u0e23\u0e1e\u0e2a\u0e32\u0e21\u0e34\u0e15", - "Make Stock Entry": "\u0e17\u0e33\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32", - "Purchase Receipt No": "\u0e43\u0e1a\u0e40\u0e2a\u0e23\u0e47\u0e08\u0e23\u0e31\u0e1a\u0e40\u0e07\u0e34\u0e19\u0e0b\u0e37\u0e49\u0e2d\u0e44\u0e21\u0e48\u0e21\u0e35", - "Purchase Return": "\u0e0b\u0e37\u0e49\u0e2d\u0e01\u0e25\u0e31\u0e1a", - "Return Date": "\u0e01\u0e25\u0e31\u0e1a\u0e27\u0e31\u0e19\u0e17\u0e35\u0e48", - "Return Type": "\u0e01\u0e25\u0e31\u0e1a\u0e0a\u0e19\u0e34\u0e14", - "Sales Invoice No": "\u0e02\u0e32\u0e22\u0e43\u0e1a\u0e41\u0e08\u0e49\u0e07\u0e2b\u0e19\u0e35\u0e49\u0e44\u0e21\u0e48\u0e21\u0e35", - "Sales Return": "\u0e02\u0e32\u0e22\u0e01\u0e25\u0e31\u0e1a", - "Sales and Purchase Return Items": "\u0e01\u0e32\u0e23\u0e02\u0e32\u0e22\u0e41\u0e25\u0e30\u0e01\u0e32\u0e23\u0e0b\u0e37\u0e49\u0e2d\u0e23\u0e32\u0e22\u0e01\u0e32\u0e23\u0e22\u0e49\u0e2d\u0e19\u0e01\u0e25\u0e31\u0e1a", - "Sales and Purchase Return Tool": "\u0e01\u0e32\u0e23\u0e02\u0e32\u0e22\u0e41\u0e25\u0e30\u0e01\u0e32\u0e23\u0e0b\u0e37\u0e49\u0e2d\u0e40\u0e04\u0e23\u0e37\u0e48\u0e2d\u0e07\u0e21\u0e37\u0e2d\u0e22\u0e49\u0e2d\u0e19\u0e01\u0e25\u0e31\u0e1a", - "Stock": "\u0e04\u0e25\u0e31\u0e07\u0e2a\u0e34\u0e19\u0e04\u0e49\u0e32" -} \ No newline at end of file diff --git a/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.js b/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.js deleted file mode 100644 index 2dd2e71cb1..0000000000 --- a/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.js +++ /dev/null @@ -1,229 +0,0 @@ -// 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 . - -cur_frm.add_fetch("delivery_note_no", "company", "company"); -cur_frm.add_fetch("sales_invoice_no", "company", "company"); -cur_frm.add_fetch("purchase_receipt_no", "company", "company"); - -// Onload -//------------------------------- -cur_frm.cscript.onload = function(doc,dt,dn){ - if(!doc.return_date) set_multiple(dt,dn,{return_date:get_today()}); - doc.delivery_note_no = ''; - doc.purchase_receipt_no = ''; - doc.sales_invoice_no = ''; - doc.return_type =''; - refresh_many(['delivery_note_no', 'sales_invoice_no', 'purchase_receipt_no', 'return_type']); -} - -// Link field query -//-------------------------------- -cur_frm.fields_dict.delivery_note_no.get_query = function(doc) { - return 'SELECT DISTINCT `tabDelivery Note`.name FROM `tabDelivery Note` WHERE `tabDelivery Note`.docstatus = 1 AND `tabDelivery Note`.%(key)s LIKE "%s" ORDER BY `tabDelivery Note`.name desc LIMIT 50'; -} - -cur_frm.fields_dict.sales_invoice_no.get_query = function(doc) { - return 'SELECT DISTINCT `tabSales Invoice`.name FROM `tabSales Invoice` WHERE `tabSales Invoice`.docstatus = 1 AND `tabSales Invoice`.%(key)s LIKE "%s" ORDER BY `tabSales Invoice`.name desc LIMIT 50'; -} - -cur_frm.fields_dict.purchase_receipt_no.get_query = function(doc) { - return 'SELECT DISTINCT `tabPurchase Receipt`.name FROM `tabPurchase Receipt` WHERE `tabPurchase Receipt`.docstatus = 1 AND `tabPurchase Receipt`.%(key)s LIKE "%s" ORDER BY `tabPurchase Receipt`.name desc LIMIT 50'; -} - -// Hide/unhide based on return type -//---------------------------------- -cur_frm.cscript.return_type = function(doc, cdt, cdn) { - var cp = wn.control_panel; - hide_field(['purchase_receipt_no', 'delivery_note_no', 'sales_invoice_no', 'return_details', 'get_items', 'make_excise_invoice', 'make_stock_entry', 'make_debit_note', 'make_credit_note']); - - if(doc.return_type == 'Sales Return') { - unhide_field(['delivery_note_no', 'sales_invoice_no', 'get_items', 'return_details', 'make_credit_note', 'make_stock_entry']); - - if(cp.country == 'India') { unhide_field(['make_excise_invoice']); } - - } else if(doc.return_type == 'Purchase Return') { - unhide_field(['purchase_receipt_no', 'get_items', 'return_details', 'make_debit_note', 'make_stock_entry']); - - if(cp.country == 'India') { unhide_field(['make_excise_invoice']);} - } - - cur_frm.cscript.clear_fields(doc); -} - -// Create item table -//------------------------------- -cur_frm.cscript.get_items = function(doc, cdt, cdn) { - flag = 0 - if(doc.return_type == 'Sales Return') { - if (doc.delivery_note_no && doc.sales_invoice_no) { - msgprint("You can not enter both Delivery Note No and Sales Invoice No. Please enter any one."); - flag = 1; - } else if (!doc.delivery_note_no && !doc.sales_invoice_no) { - msgprint("Please enter Delivery Note No or Sales Invoice No to proceed"); - flag = 1; - } - } else if (doc.return_type == 'Purchase Return' && !doc.purchase_receipt_no) { - msgprint("Please enter Purchase Receipt No to proceed"); - flag = 1; - } - if (!flag) - $c_obj(make_doclist(doc.doctype, doc.name),'pull_item_details','', function(r, rt) { - refresh_many(['return_details', 'cust_supp', 'cust_supp_name', 'cust_supp_address']); - }); -} - -// Clear fields -//------------------------------- -cur_frm.cscript.clear_fields = function(doc) { - doc.purchase_receipt_no, doc.delivery_note_no, doc.sales_invoice_no = '', '', ''; - var cl = getchildren('Sales and Purchase Return Item', doc.name, 'return_details') - if(cl.length) $c_obj(make_doclist(doc.doctype, doc.name),'clear_return_table','', function(r, rt) {refresh_field('return_details')}); - refresh_many(['delivery_note_no', 'sales_invoice_no', 'purchase_receipt_no', 'return_details']); -} - -// Make Stock Entry -//------------------------------- -cur_frm.cscript.make_stock_entry = function(doc, cdt, cdn) { - var cl = getchildren('Sales and Purchase Return Item', doc.name, 'return_details'); - if (!cl.length) - msgprint("Item table can not be blank. Please click on 'Get Items'."); - else if (!cur_frm.cscript.validate_returned_qty(cl)) { - se = cur_frm.cscript.map_parent_fields(doc,cdt,cdn); - cur_frm.cscript.map_child_fields(cl, se); - loaddoc('Stock Entry', se.name); - } -} - -// Validate returned qty -//--------------------------- -cur_frm.cscript.validate_returned_qty = function(cl) { - flag = 0 - for(var i = 0; i cl[i].qty) { - msgprint("Returned Qty can not be greater than qty. Please check for item: " + cl[i].item_code); - flag = 1 - } - } - return flag -} - - -// map parent fields of stock entry -//---------------------------------- -cur_frm.cscript.map_parent_fields = function(doc, cdt, cdn) { - var se = wn.model.make_new_doc_and_get_name('Stock Entry'); - se = locals['Stock Entry'][se]; - se.posting_date = dateutil.obj_to_str(new Date()); - se.transfer_date = dateutil.obj_to_str(new Date()); - se.fiscal_year = sys_defaults.fiscal_year; - se.purpose = doc.return_type; - se.remarks = doc.return_type + ' of ' + (doc.delivery_note_no || doc.sales_invoice_no || doc.purchase_receipt_no); - if(doc.return_type == 'Sales Return'){ - se.delivery_note_no = doc.delivery_note_no; - se.sales_invoice_no = doc.sales_invoice_no; - se.customer = doc.cust_supp_name; - se.customer_name = doc.cust_supp_name; - se.customer_address = doc.cust_supp_address; - } - else if(doc.return_type == 'Purchase Return'){ - se.purchase_receipt_no = doc.purchase_receipt_no; - se.supplier = doc.cust_supp_name; - se.supplier_name = doc.cust_supp_name; - se.supplier_address = doc.cust_supp_address; - } - return se -} - -// map child fields of stock entry -//--------------------------------- -cur_frm.cscript.map_child_fields = function(cl, se) { - for(var i = 0; i. - -from __future__ import unicode_literals -import webnotes - -from webnotes.utils import flt -from webnotes.model import db_exists -from webnotes.model.doc import addchild -from webnotes.model.bean import copy_doclist - -sql = webnotes.conn.sql - - -class DocType : - def __init__(self, doc, doclist=[]): - self.doc = doc - self.doclist = doclist - - # Pull Item Details - # --------------------------- - def pull_item_details(self): - if self.doc.return_type == 'Sales Return': - if self.doc.delivery_note_no: - det = sql("select t1.name, t1.item_code, t1.description, t1.qty, t1.uom, t2.export_rate * t3.conversion_rate, t3.customer, t3.customer_name, t3.customer_address, t2.serial_no, t2.batch_no from `tabDelivery Note Packing Item` t1, `tabDelivery Note Item` t2, `tabDelivery Note` t3 where t1.parent = t3.name and t2.parent = t3.name and t1.parent_detail_docname = t2.name and t3.name = '%s' and t3.docstatus = 1" % self.doc.delivery_note_no) - elif self.doc.sales_invoice_no: - det = sql("select t1.name, t1.item_code, t1.description, t1.qty, t1.stock_uom, t1.export_rate * t2.conversion_rate, t2.customer, t2.customer_name, t2.customer_address, t1.serial_no from `tabSales Invoice Item` t1, `tabSales Invoice` t2 where t1.parent = t2.name and t2.name = '%s' and t2.docstatus = 1" % self.doc.sales_invoice_no) - elif self.doc.return_type == 'Purchase Return' and self.doc.purchase_receipt_no: - det = sql("select t1.name, t1.item_code, t1.description, t1.received_qty, t1.uom, t1.purchase_rate, t2.supplier, t2.supplier_name, t2.supplier_address, t1.serial_no, t1.batch_no from `tabPurchase Receipt Item` t1, `tabPurchase Receipt` t2 where t1.parent = t2.name and t2.name = '%s' and t2.docstatus = 1" % self.doc.purchase_receipt_no) - - self.doc.cust_supp = det and det[0][6] or '' - self.doc.cust_supp_name = det and det[0][7] or '' - self.doc.cust_supp_address = det and det[0][8] or '' - self.create_item_table(det) - self.doc.save() - - # Create Item Table - # ----------------------------- - def create_item_table(self, det): - self.doclist = self.doc.clear_table(self.doclist, 'return_details', 1) - for i in det: - ch = addchild(self.doc, 'return_details', 'Sales and Purchase Return Item', - self.doclist) - ch.detail_name = i and i[0] or '' - ch.item_code = i and i[1] or '' - ch.description = i and i[2] or '' - ch.qty = i and flt(i[3]) or 0 - ch.uom = i and i[4] or '' - ch.rate = i and flt(i[5]) or 0 - ch.serial_no = i and i[9] or '' - ch.batch_no = (len(i) == 11) and i[10] or '' - ch.save() - - # Clear return table - # -------------------------------- - def clear_return_table(self): - self.doclist = self.doc.clear_table(self.doclist, 'return_details', 1) - self.doc.save() \ No newline at end of file diff --git a/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.txt b/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.txt deleted file mode 100644 index 2daf6ac3f5..0000000000 --- a/stock/doctype/sales_and_purchase_return_tool/sales_and_purchase_return_tool.txt +++ /dev/null @@ -1,191 +0,0 @@ -[ - { - "creation": "2013-01-10 16:34:29", - "docstatus": 0, - "modified": "2013-01-23 16:48:38", - "modified_by": "Administrator", - "owner": "wasim@webnotestech.com" - }, - { - "doctype": "DocType", - "issingle": 1, - "istable": 0, - "module": "Stock", - "name": "__common__" - }, - { - "doctype": "DocField", - "name": "__common__", - "parent": "Sales and Purchase Return Tool", - "parentfield": "fields", - "parenttype": "DocType", - "permlevel": 0 - }, - { - "create": 1, - "doctype": "DocPerm", - "name": "__common__", - "parent": "Sales and Purchase Return Tool", - "parentfield": "permissions", - "parenttype": "DocType", - "permlevel": 0, - "read": 1, - "report": 0, - "submit": 0, - "write": 1 - }, - { - "doctype": "DocType", - "name": "Sales and Purchase Return Tool" - }, - { - "doctype": "DocField", - "fieldname": "return_date", - "fieldtype": "Date", - "label": "Return Date", - "no_copy": 1, - "oldfieldname": "return_date", - "oldfieldtype": "Date", - "reqd": 1 - }, - { - "doctype": "DocField", - "fieldname": "return_type", - "fieldtype": "Select", - "label": "Return Type", - "no_copy": 1, - "oldfieldname": "return_type", - "oldfieldtype": "Select", - "options": "\nSales Return\nPurchase Return", - "reqd": 1 - }, - { - "doctype": "DocField", - "fieldname": "delivery_note_no", - "fieldtype": "Link", - "hidden": 1, - "label": "Delivery Note No", - "no_copy": 1, - "oldfieldname": "delivery_note_no", - "oldfieldtype": "Link", - "options": "Delivery Note", - "reqd": 0 - }, - { - "doctype": "DocField", - "fieldname": "sales_invoice_no", - "fieldtype": "Link", - "hidden": 1, - "label": "Sales Invoice No", - "options": "Sales Invoice" - }, - { - "doctype": "DocField", - "fieldname": "purchase_receipt_no", - "fieldtype": "Link", - "hidden": 1, - "label": "Purchase Receipt No", - "no_copy": 1, - "oldfieldname": "purchase_receipt_no", - "oldfieldtype": "Link", - "options": "Purchase Receipt" - }, - { - "doctype": "DocField", - "fieldname": "company", - "fieldtype": "Link", - "hidden": 1, - "label": "Company", - "options": "Company", - "print_hide": 1 - }, - { - "doctype": "DocField", - "fieldname": "cust_supp", - "fieldtype": "Data", - "hidden": 1, - "label": "Customer/Supplier", - "print_hide": 1, - "read_only": 1 - }, - { - "doctype": "DocField", - "fieldname": "cust_supp_name", - "fieldtype": "Data", - "hidden": 1, - "label": "Cust/Supp Name", - "print_hide": 1, - "read_only": 1 - }, - { - "doctype": "DocField", - "fieldname": "cust_supp_address", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Cust/Supp Address", - "print_hide": 1, - "read_only": 1 - }, - { - "doctype": "DocField", - "fieldname": "get_items", - "fieldtype": "Button", - "hidden": 1, - "label": "Get Items", - "oldfieldtype": "Button" - }, - { - "doctype": "DocField", - "fieldname": "return_details", - "fieldtype": "Table", - "hidden": 1, - "label": "Sales and Purchase Return Items", - "no_copy": 1, - "oldfieldname": "return_details", - "oldfieldtype": "Table", - "options": "Sales and Purchase Return Item", - "read_only": 1 - }, - { - "doctype": "DocField", - "fieldname": "make_stock_entry", - "fieldtype": "Button", - "hidden": 1, - "label": "Make Stock Entry", - "oldfieldtype": "Button" - }, - { - "doctype": "DocField", - "fieldname": "make_excise_invoice", - "fieldtype": "Button", - "hidden": 1, - "label": "Make Excise Invoice", - "oldfieldtype": "Button" - }, - { - "doctype": "DocField", - "fieldname": "make_credit_note", - "fieldtype": "Button", - "hidden": 1, - "label": "Make Credit Note", - "oldfieldtype": "Button" - }, - { - "doctype": "DocField", - "fieldname": "make_debit_note", - "fieldtype": "Button", - "hidden": 1, - "label": "Make Debit Note", - "oldfieldtype": "Button" - }, - { - "amend": 0, - "cancel": 0, - "doctype": "DocPerm", - "role": "Material User" - }, - { - "doctype": "DocPerm", - "role": "Accounts User" - } -] \ No newline at end of file diff --git a/stock/page/stock_home/stock_home.js b/stock/page/stock_home/stock_home.js index a09cae75bd..db77fced0e 100644 --- a/stock/page/stock_home/stock_home.js +++ b/stock/page/stock_home/stock_home.js @@ -95,12 +95,6 @@ wn.module_page["Stock"] = [ description: wn._("Change UOM for an Item."), "doctype": "Stock UOM Replace Utility" }, - { - "route":"Form/Sales and Purchase Return Tool/Sales and Purchase Return Tool", - "label": wn._("Sales and Purchase Return Tool"), - doctype: "Sales and Purchase Return Tool", - description: wn._("Manage sales or purchase returns") - }, ] }, { From 5afe037a5b754b84c98ab2b1b1787d0d519fa93a Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Mon, 18 Mar 2013 17:59:56 +0530 Subject: [PATCH 09/19] deprecate sales and purchase return tool --- accounts/__init__.py | 206 ------------------------------------------- 1 file changed, 206 deletions(-) diff --git a/accounts/__init__.py b/accounts/__init__.py index 707203f500..145ad6b869 100644 --- a/accounts/__init__.py +++ b/accounts/__init__.py @@ -32,209 +32,3 @@ def get_default_bank_account(): WHERE name=%s AND docstatus<2""", company) if res: return res[0][0] - -@webnotes.whitelist() -def get_new_jv_details(): - """ - Get details which will help create new jv on sales/purchase return - """ - doclist = webnotes.form_dict.get('doclist') - fiscal_year = webnotes.form_dict.get('fiscal_year') - if not (isinstance(doclist, basestring) and isinstance(fiscal_year, basestring)): return - - import json - doclist = json.loads(doclist) - doc, children = doclist[0], doclist[1:] - - if doc.get('return_type')=='Sales Return': - if doc.get('sales_invoice_no'): - return get_invoice_details(doc, children, fiscal_year) - elif doc.get('delivery_note_no'): - return get_delivery_note_details(doc, children, fiscal_year) - - elif doc.get('purchase_receipt_no'): - return get_purchase_receipt_details(doc, children, fiscal_year) - - -def get_invoice_details(doc, children, fiscal_year): - """ - Gets details from an invoice to make new jv - Returns [{ - 'account': , - 'balance': , - 'debit': , - 'credit': , - 'against_invoice': , - 'against_payable': - }, { ... }, ...] - """ - if doc.get('return_type')=='Sales Return': - obj = get_obj('Sales Invoice', doc.get('sales_invoice_no'), with_children=1) - else: - obj = get_obj('Purchase Invoice', doc.get('purchase_invoice_no'), with_children=1) - if not obj.doc.docstatus==1: return - - # Build invoice account jv detail record - invoice_rec = get_invoice_account_jv_record(doc, children, fiscal_year, obj) - - # Build item accountwise jv detail records - item_accountwise_list = get_item_accountwise_jv_record(doc, children, fiscal_year, obj) - - return [invoice_rec] + item_accountwise_list - - -def get_invoice_account_jv_record(doc, children, fiscal_year, obj): - """ - Build customer/supplier account jv detail record - """ - # Calculate total return amount - total_amt = sum([(flt(ch.get('rate')) * flt(ch.get('returned_qty'))) for ch in children]) - - ret = {} - - if doc.get('return_type')=='Sales Return': - account = obj.doc.debit_to - ret['against_invoice'] = doc.get('sales_invoice_no') - ret['credit'] = total_amt - else: - account = obj.doc.credit_to - ret['against_voucher'] = doc.get('purchase_invoice_no') - ret['debit'] = total_amt - - ret.update({ - 'account': account, - 'balance': get_balance_on(account, doc.get("return_date")) - }) - - return ret - - -def get_item_accountwise_jv_record(doc, children, fiscal_year, obj): - """ - Build item accountwise jv detail records - """ - if doc.get('return_type')=='Sales Return': - amt_field = 'debit' - ac_field = 'income_account' - else: - amt_field = 'credit' - ac_field = 'expense_head' - - inv_children = dict([[ic.fields.get('item_code'), ic] for ic in obj.doclist if ic.fields.get('item_code')]) - - accwise_list = [] - - for ch in children: - inv_ch = inv_children.get(ch.get('item_code')) - if not inv_ch: continue - - amount = flt(ch.get('rate')) * flt(ch.get('returned_qty')) - - accounts = [[jvd['account'], jvd['cost_center']] for jvd in accwise_list] - - if [inv_ch.fields.get(ac_field), inv_ch.fields.get('cost_center')] not in accounts: - rec = { - 'account': inv_ch.fields.get(ac_field), - 'cost_center': inv_ch.fields.get('cost_center'), - 'balance': get_balance_on(inv_ch.fields.get(ac_field), - doc.get("return_date")) - } - rec[amt_field] = amount - accwise_list.append(rec) - else: - rec = accwise_list[accounts.index([inv_ch.fields.get(ac_field), inv_ch.fields.get('cost_center')])] - rec[amt_field] = rec[amt_field] + amount - - return accwise_list - - -def get_jv_details_from_inv_list(doc, children, fiscal_year, inv_list, jv_details_list): - """ - Get invoice details and make jv detail records - """ - for inv in inv_list: - if not inv[0]: continue - - if doc.get('return_type')=='Sales Return': - doc['sales_invoice_no'] = inv[0] - else: - doc['purchase_invoice_no'] = inv[0] - - jv_details = get_invoice_details(doc, children, fiscal_year) - - if jv_details and len(jv_details)>1: jv_details_list.extend(jv_details) - - return jv_details_list - - -def get_prev_doc_list(obj, prev_doctype): - """ - Returns a list of previous doc's names - """ - prevdoc_list = [] - for ch in obj.doclist: - if ch.fields.get('prevdoc_docname') and ch.fields.get('prevdoc_doctype')==prev_doctype: - prevdoc_list.append(ch.fields.get('prevdoc_docname')) - return prevdoc_list - - -def get_inv_list(table, field, value): - """ - Returns invoice list - """ - if isinstance(value, basestring): - return webnotes.conn.sql("""\ - SELECT DISTINCT parent FROM `%s` - WHERE %s='%s' AND docstatus=1""" % (table, field, value)) - elif isinstance(value, list): - return webnotes.conn.sql("""\ - SELECT DISTINCT parent FROM `%s` - WHERE %s IN ("%s") AND docstatus=1""" % (table, field, '", "'.join(value))) - else: - return [] - - -def get_delivery_note_details(doc, children, fiscal_year): - """ - Gets sales invoice numbers from delivery note details - and returns detail records for jv - """ - jv_details_list = [] - - dn_obj = get_obj('Delivery Note', doc['delivery_note_no'], with_children=1) - - inv_list = get_inv_list('tabSales Invoice Item', 'delivery_note', doc['delivery_note_no']) - - if inv_list: - jv_details_list = get_jv_details_from_inv_list(doc, children, fiscal_year, inv_list, jv_details_list) - - if not (inv_list and jv_details_list): - so_list = get_prev_doc_list(dn_obj, 'Sales Order') - inv_list = get_inv_list('tabSales Invoice Item', 'sales_order', so_list) - if inv_list: - jv_details_list = get_jv_details_from_inv_list(doc, children, fiscal_year, inv_list, jv_details_list) - - return jv_details_list - - -def get_purchase_receipt_details(doc, children, fiscal_year): - """ - Gets purchase invoice numbers from purchase receipt details - and returns detail records for jv - """ - jv_details_list = [] - - pr_obj = get_obj('Purchase Receipt', doc['purchase_receipt_no'], with_children=1) - - inv_list = get_inv_list('tabPurchase Invoice Item', 'purchase_receipt', doc['purchase_receipt_no']) - - if inv_list: - jv_details_list = get_jv_details_from_inv_list(doc, children, fiscal_year, inv_list, jv_details_list) - - if not (inv_list and jv_details_list): - po_list = get_prev_doc_list(pr_obj, 'Purchase Order') - inv_list = get_inv_list('tabPurchase Invoice Item', 'purchase_order', po_list) - if inv_list: - jv_details_list = get_jv_details_from_inv_list(doc, children, fiscal_year, inv_list, jv_details_list) - - return jv_details_list From 839fee3e71c9f740a4ac08947937b03fb6401e50 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Mon, 18 Mar 2013 18:20:09 +0530 Subject: [PATCH 10/19] restrict material_request_type in Material Request form --- stock/doctype/material_request/material_request.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stock/doctype/material_request/material_request.py b/stock/doctype/material_request/material_request.py index 77426762f9..8a899b3a40 100644 --- a/stock/doctype/material_request/material_request.py +++ b/stock/doctype/material_request/material_request.py @@ -105,6 +105,9 @@ class DocType(BuyingController): import utilities utilities.validate_status(self.doc.status, ["Draft", "Submitted", "Stopped", "Cancelled"]) + + # restrict material request type + self.validate_value("material_request_type", "in", ["Purchase", "Transfer"]) # Get Purchase Common Obj pc_obj = get_obj(dt='Purchase Common') From f9e51bbab3f8df8142f525e0be64eb133d755697 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 19 Mar 2013 13:33:51 +0530 Subject: [PATCH 11/19] removed complications from sales purchase return --- stock/doctype/stock_entry/stock_entry.py | 132 ++++++------------ stock/doctype/stock_entry/test_stock_entry.py | 36 ++--- 2 files changed, 53 insertions(+), 115 deletions(-) diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index 131e9ffcd4..edaf63b4e1 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -279,7 +279,7 @@ class DocType(AccountsController): def validate_return_reference_doc(self): """validate item with reference doc""" - ref = get_return_reference_details(self.doc.fields) + ref = get_return_doclist_and_details(self.doc.fields) if ref.doclist: # validate docstatus @@ -703,7 +703,7 @@ def query_purchase_return_doc(doctype, txt, searchfield, start, page_len, filter def query_return_item(doctype, txt, searchfield, start, page_len, filters): txt = txt.replace("%", "") - ref = get_return_reference_details(filters) + ref = get_return_doclist_and_details(filters) stock_items = get_stock_items_for_return(ref.doclist, ref.parentfields) @@ -737,7 +737,7 @@ def get_stock_items_for_return(ref_doclist, parentfields): return stock_items -def get_return_reference_details(args): +def get_return_doclist_and_details(args): ref = webnotes._dict() # get ref_doclist @@ -768,7 +768,7 @@ def make_return_jv(stock_entry): if not se.doc.purpose in ["Sales Return", "Purchase Return"]: return - ref = get_return_reference_details(se.doc.fields) + ref = get_return_doclist_and_details(se.doc.fields) if ref.doclist[0].doctype == "Delivery Note": result = make_return_jv_from_delivery_note(se, ref) @@ -794,8 +794,6 @@ def make_return_jv(stock_entry): "doctype": "Journal Voucher Detail", "parentfield": "entries", "account": r.get("account"), - "debit": r.get("debit"), - "credit": r.get("credit"), "against_invoice": r.get("against_invoice"), "against_voucher": r.get("against_voucher"), "balance": get_balance_on(r.get("account"), se.doc.posting_date) @@ -807,42 +805,32 @@ def make_return_jv_from_sales_invoice(se, ref): # customer account entry parent = { "account": ref.doclist[0].debit_to, - "credit": 0.0, "against_invoice": ref.doclist[0].name, } # income account entries - children = {} + children = [] for se_item in se.doclist.get({"parentfield": "mtn_details"}): # find item in ref.doclist ref_item = ref.doclist.getone({"item_code": se_item.item_code}) - account, debit = get_sales_account_and_amount_from_item(ref.doclist, ref_item, - se_item.transfer_qty) + account = get_sales_account_from_item(ref.doclist, ref_item) if account not in children: - children[account] = 0 - children[account] += debit - parent["credit"] += debit + children.append(account) - # find tax account and value and add corresponding rows + return [parent] + [{"account": account} for account in children] - return [parent] + [{"account": account, "debit": debit} for account, debit in children.items()] - -def get_sales_account_and_amount_from_item(doclist, ref_item, transfer_qty): - account = debit = None +def get_sales_account_from_item(doclist, ref_item): + account = None if not ref_item.income_account: if ref_item.parent_item: parent_item = doclist.getone({"item_code": ref_item.parent_item}) - packing_ratio = parent_item.qty / ref_item.qty - - debit = parent_item.basic_rate * transfer_qty * packing_ratio account = parent_item.income_account else: - debit = ref_item.basic_rate * transfer_qty account = ref_item.income_account - return account, debit + return account def make_return_jv_from_delivery_note(se, ref): invoices_against_delivery = get_invoice_list("Sales Invoice Item", "delivery_note", @@ -854,11 +842,14 @@ def make_return_jv_from_delivery_note(se, ref): invoices_against_delivery = get_invoice_list("Sales Invoice Item", "sales_order", sales_orders_against_delivery) + + if not invoices_against_delivery: + return [] - against_invoice = {} + parent = {} + children = [] for se_item in se.doclist.get({"parentfield": "mtn_details"}): - pending = se_item.transfer_qty for sales_invoice in invoices_against_delivery: si = webnotes.bean("Sales Invoice", sales_invoice) si.run_method("make_packing_list") @@ -866,44 +857,24 @@ def make_return_jv_from_delivery_note(se, ref): if not ref_item: continue - + ref_item = ref_item[0] - if ref_item.qty < pending: - transfer_qty = ref_item.qty - pending -= ref_item.qty - else: - transfer_qty = pending - pending = 0 + account = get_sales_account_from_item(si.doclist, ref_item) - account, debit = get_sales_account_and_amount_from_item(si.doclist, ref_item, - transfer_qty) - - if si.doclist[0].name not in against_invoice: - against_invoice[sales_invoice] = { - "parent": {"account": si.doclist[0].debit_to, "credit": 0}, - "children": {} - } - - against_invoice[sales_invoice]["parent"]["credit"] += debit + if account not in children: + children.append(account) - if account not in against_invoice[sales_invoice]["children"]: - against_invoice[sales_invoice]["children"][account] = 0 + if not parent: + parent = {"account": si.doc.debit_to} + + break - against_invoice[sales_invoice]["children"][account] += debit - - # find tax account and value and add corresponding rows - - if pending <= 0: - break + if len(invoices_against_delivery) == 1: + parent["against_invoice"] = invoices_against_delivery[0] + + result = [parent] + [{"account": account} for account in children] - result = [] - for sales_invoice, opts in against_invoice.items(): - parent = opts["parent"] - parent.update({"against_invoice": sales_invoice}) - children = [{"account": account, "debit": debit} - for account, debit in opts["children"].items()] - result += [parent] + children return result def get_invoice_list(doctype, link_field, value): @@ -925,53 +896,36 @@ def make_return_jv_from_purchase_receipt(se, ref): invoice_against_receipt = get_invoice_list("Purchase Invoice Item", "purchase_order", purchase_orders_against_receipt) - against_voucher = {} + if not invoice_against_receipt: + return [] + + parent = {} + children = [] for se_item in se.doclist.get({"parentfield": "mtn_details"}): - pending = se_item.transfer_qty for purchase_invoice in invoice_against_receipt: pi = webnotes.bean("Purchase Invoice", purchase_invoice) ref_item = pi.doclist.get({"item_code": se_item.item_code}) if not ref_item: continue - + ref_item = ref_item[0] - if ref_item.qty < pending: - transfer_qty = ref_item.qty - pending -= ref_item.qty - else: - transfer_qty = pending - pending = 0 - - credit = ref_item.rate * transfer_qty account = ref_item.expense_head - if pi.doclist[0].name not in against_voucher: - against_voucher[purchase_invoice] = { - "parent": {"account": pi.doclist[0].credit_to, "debit": 0}, - "children": {} - } + if account not in children: + children.append(account) - against_voucher[purchase_invoice]["parent"]["debit"] += credit + if not parent: + parent = {"account": pi.doc.credit_to} - if account not in against_voucher[purchase_invoice]["children"]: - against_voucher[purchase_invoice]["children"][account] = 0 - - against_voucher[purchase_invoice]["children"][account] += credit + break - # find tax account and value and add corresponding rows - - if pending <= 0: - break + if len(invoice_against_receipt) == 1: + parent["against_voucher"] = invoice_against_receipt[0] + + result = [parent] + [{"account": account} for account in children] - result = [] - for purchase_invoice, opts in against_voucher.items(): - parent = opts["parent"] - parent.update({"against_voucher": purchase_invoice}) - children = [{"account": account, "credit": credit} - for account, credit in opts["children"].items()] - result += [parent] + children return result \ 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 049b0e66c8..322fcfac26 100644 --- a/stock/doctype/stock_entry/test_stock_entry.py +++ b/stock/doctype/stock_entry/test_stock_entry.py @@ -309,7 +309,7 @@ class TestStockEntry(unittest.TestCase): def test_delivery_note_return_of_packing_item(self): self._test_delivery_note_return("_Test Sales BOM Item", 25, 20) - def _test_sales_return_jv(self, se, returned_value): + def _test_sales_return_jv(self, se): from stock.doctype.stock_entry.stock_entry import make_return_jv jv_list = make_return_jv(se.doc.name) @@ -320,35 +320,27 @@ class TestStockEntry(unittest.TestCase): self.assertEqual(jv_list[2].get("account"), "Sales - _TC") self.assertTrue(jv_list[1].get("against_invoice")) - # debit == credit - debit = sum([flt(d.get("debit")) for d in jv_list]) - credit = sum([flt(d.get("credit")) for d in jv_list]) - self.assertEqual(debit, credit) - - # validate value of debit - self.assertEqual(debit, returned_value) - def test_make_return_jv_for_sales_invoice_non_packing_item(self): se = self._test_sales_invoice_return("_Test Item", 5, 2) - self._test_sales_return_jv(se, 1000) + self._test_sales_return_jv(se) def test_make_return_jv_for_sales_invoice_packing_item(self): se = self._test_sales_invoice_return("_Test Sales BOM Item", 25, 20) - self._test_sales_return_jv(se, 2000) + self._test_sales_return_jv(se) def test_make_return_jv_for_delivery_note_non_packing_item(self): se = self._test_delivery_note_return("_Test Item", 5, 2) - self._test_sales_return_jv(se, 200) + self._test_sales_return_jv(se) se = self._test_delivery_note_return_against_sales_order("_Test Item", 5, 2) - self._test_sales_return_jv(se, 200) + self._test_sales_return_jv(se) def test_make_return_jv_for_delivery_note_packing_item(self): se = self._test_delivery_note_return("_Test Sales BOM Item", 25, 20) - self._test_sales_return_jv(se, 400) + self._test_sales_return_jv(se) se = self._test_delivery_note_return_against_sales_order("_Test Sales BOM Item", 25, 20) - self._test_sales_return_jv(se, 400) + self._test_sales_return_jv(se) def _test_delivery_note_return_against_sales_order(self, item_code, delivered_qty, returned_qty): self._insert_material_receipt() @@ -477,7 +469,7 @@ class TestStockEntry(unittest.TestCase): self.assertRaises(StockOverReturnError, se.insert) - def _test_purchase_return_jv(self, se, returned_value): + def _test_purchase_return_jv(self, se): from stock.doctype.stock_entry.stock_entry import make_return_jv jv_list = make_return_jv(se.doc.name) @@ -488,20 +480,12 @@ class TestStockEntry(unittest.TestCase): self.assertEqual(jv_list[2].get("account"), "_Test Account Cost for Goods Sold - _TC") self.assertTrue(jv_list[1].get("against_voucher")) - # debit == credit - debit = sum([flt(d.get("debit")) for d in jv_list]) - credit = sum([flt(d.get("credit")) for d in jv_list]) - self.assertEqual(debit, credit) - - # validate value of credit - self.assertEqual(credit, returned_value) - def test_make_return_jv_for_purchase_receipt(self): se, pr_name = self.test_purchase_receipt_return() - self._test_purchase_return_jv(se, 250) + self._test_purchase_return_jv(se) se, pr_name = self._test_purchase_return_return_against_purchase_order() - self._test_purchase_return_jv(se, 250) + self._test_purchase_return_jv(se) def _test_purchase_return_return_against_purchase_order(self): self._clear_stock() From 688b52e14b1554106c34665b4e0c79df5598ca5c Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 19 Mar 2013 13:35:40 +0530 Subject: [PATCH 12/19] increase width of taxes table in print format --- .../sales_taxes_and_charges_master.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js b/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js index 7d441abd78..b1cbbdcbfc 100644 --- a/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js +++ b/accounts/doctype/sales_taxes_and_charges_master/sales_taxes_and_charges_master.js @@ -45,8 +45,7 @@ cur_frm.pformat.other_charges= function(doc){ var make_row = function(title,val,bold){ var bstart = ''; var bend = ''; return ''+(bold?bstart:'')+title+(bold?bend:'')+'' - +'' - +''+format_currency(val, doc.currency)+'' + +''+format_currency(val, doc.currency)+'' +'' } From af6f1ba82ecae66da1fd9b5a81cdb554fd5a778f Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 19 Mar 2013 13:43:49 +0530 Subject: [PATCH 13/19] fixes in sales purchase return for stock entry --- stock/doctype/stock_entry/stock_entry.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index edaf63b4e1..37d55d90cb 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -840,8 +840,9 @@ def make_return_jv_from_delivery_note(se, ref): sales_orders_against_delivery = [d.prevdoc_docname for d in ref.doclist.get({"prevdoc_doctype": "Sales Order"}) if d.prevdoc_docname] - invoices_against_delivery = get_invoice_list("Sales Invoice Item", "sales_order", - sales_orders_against_delivery) + if sales_orders_against_delivery: + invoices_against_delivery = get_invoice_list("Sales Invoice Item", "sales_order", + sales_orders_against_delivery) if not invoices_against_delivery: return [] @@ -893,8 +894,9 @@ def make_return_jv_from_purchase_receipt(se, ref): purchase_orders_against_receipt = [d.prevdoc_docname for d in ref.doclist.get({"prevdoc_doctype": "Purchase Order"}) if d.prevdoc_docname] - invoice_against_receipt = get_invoice_list("Purchase Invoice Item", "purchase_order", - purchase_orders_against_receipt) + if purchase_orders_against_receipt: + invoice_against_receipt = get_invoice_list("Purchase Invoice Item", "purchase_order", + purchase_orders_against_receipt) if not invoice_against_receipt: return [] From f6b06a6b3091190f9e4c0929899dfec447ea08c2 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 19 Mar 2013 15:01:07 +0530 Subject: [PATCH 14/19] fixes in sales purchase return --- stock/doctype/stock_entry/stock_entry.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/stock/doctype/stock_entry/stock_entry.py b/stock/doctype/stock_entry/stock_entry.py index 37d55d90cb..5b90c625a5 100644 --- a/stock/doctype/stock_entry/stock_entry.py +++ b/stock/doctype/stock_entry/stock_entry.py @@ -789,6 +789,8 @@ 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", @@ -846,6 +848,9 @@ def make_return_jv_from_delivery_note(se, ref): if not invoices_against_delivery: return [] + + packing_item_parent_map = dict([[d.item_code, d.parent_item] for d in ref.doclist.get( + {"parentfield": ref.parentfields[1]})]) parent = {} children = [] @@ -853,8 +858,11 @@ def make_return_jv_from_delivery_note(se, ref): for se_item in se.doclist.get({"parentfield": "mtn_details"}): for sales_invoice in invoices_against_delivery: si = webnotes.bean("Sales Invoice", sales_invoice) - si.run_method("make_packing_list") - ref_item = si.doclist.get({"item_code": se_item.item_code}) + + if se_item.item_code in packing_item_parent_map: + ref_item = si.doclist.get({"item_code": packing_item_parent_map[se_item.item_code]}) + else: + ref_item = si.doclist.get({"item_code": se_item.item_code}) if not ref_item: continue From 73091ecac3cbc49343885c5b6557008ee81f6c78 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 19 Mar 2013 15:15:12 +0530 Subject: [PATCH 15/19] shifted return reference fields in stock entry to the main section --- stock/doctype/stock_entry/stock_entry.txt | 98 +++++++++++------------ 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/stock/doctype/stock_entry/stock_entry.txt b/stock/doctype/stock_entry/stock_entry.txt index 2554455764..4509f3ddab 100644 --- a/stock/doctype/stock_entry/stock_entry.txt +++ b/stock/doctype/stock_entry/stock_entry.txt @@ -1,8 +1,8 @@ [ { - "creation": "2013-01-23 19:57:20", + "creation": "2013-03-11 12:34:40", "docstatus": 0, - "modified": "2013-01-28 17:59:20", + "modified": "2013-03-19 15:13:07", "modified_by": "Administrator", "owner": "Administrator" }, @@ -99,6 +99,53 @@ "reqd": 1, "search_index": 0 }, + { + "allow_on_submit": 0, + "depends_on": "eval:doc.purpose==\"Sales Return\"", + "doctype": "DocField", + "fieldname": "delivery_note_no", + "fieldtype": "Link", + "hidden": 1, + "in_filter": 0, + "label": "Delivery Note No", + "no_copy": 1, + "oldfieldname": "delivery_note_no", + "oldfieldtype": "Link", + "options": "Delivery Note", + "print_hide": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 1 + }, + { + "depends_on": "eval:doc.purpose==\"Sales Return\"", + "doctype": "DocField", + "fieldname": "sales_invoice_no", + "fieldtype": "Link", + "hidden": 1, + "label": "Sales Invoice No", + "no_copy": 1, + "options": "Sales Invoice", + "print_hide": 1 + }, + { + "allow_on_submit": 0, + "depends_on": "eval:doc.purpose==\"Purchase Return\"", + "doctype": "DocField", + "fieldname": "purchase_receipt_no", + "fieldtype": "Link", + "hidden": 1, + "in_filter": 0, + "label": "Purchase Receipt No", + "no_copy": 1, + "oldfieldname": "purchase_receipt_no", + "oldfieldtype": "Link", + "options": "Purchase Receipt", + "print_hide": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 1 + }, { "doctype": "DocField", "fieldname": "col2", @@ -273,42 +320,6 @@ "reqd": 0, "search_index": 0 }, - { - "allow_on_submit": 0, - "depends_on": "eval:doc.purpose==\"Sales Return\"", - "doctype": "DocField", - "fieldname": "delivery_note_no", - "fieldtype": "Link", - "hidden": 1, - "in_filter": 0, - "label": "Delivery Note No", - "no_copy": 1, - "oldfieldname": "delivery_note_no", - "oldfieldtype": "Link", - "options": "Delivery Note", - "print_hide": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 1 - }, - { - "allow_on_submit": 0, - "depends_on": "eval:doc.purpose==\"Purchase Return\"", - "doctype": "DocField", - "fieldname": "purchase_receipt_no", - "fieldtype": "Link", - "hidden": 1, - "in_filter": 0, - "label": "Purchase Receipt No", - "no_copy": 1, - "oldfieldname": "purchase_receipt_no", - "oldfieldtype": "Link", - "options": "Purchase Receipt", - "print_hide": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 1 - }, { "doctype": "DocField", "fieldname": "cb1", @@ -339,17 +350,6 @@ "reqd": 0, "search_index": 0 }, - { - "depends_on": "eval:doc.purpose==\"Sales Return\"", - "doctype": "DocField", - "fieldname": "sales_invoice_no", - "fieldtype": "Link", - "hidden": 1, - "label": "Sales Invoice No", - "no_copy": 1, - "options": "Sales Invoice", - "print_hide": 1 - }, { "depends_on": "eval:(doc.purpose==\"Sales Return\" || doc.purpose==\"Purchase Return\")", "doctype": "DocField", From 3e967ab9b6ff26ddb89cebb546e5f28daae35d3a Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 19 Mar 2013 16:22:22 +0530 Subject: [PATCH 16/19] hide Reference section break when using Sales or Purchase Return --- stock/doctype/stock_entry/stock_entry.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stock/doctype/stock_entry/stock_entry.txt b/stock/doctype/stock_entry/stock_entry.txt index 4509f3ddab..ecbd9c6b72 100644 --- a/stock/doctype/stock_entry/stock_entry.txt +++ b/stock/doctype/stock_entry/stock_entry.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-11 12:34:40", "docstatus": 0, - "modified": "2013-03-19 15:13:07", + "modified": "2013-03-19 15:33:14", "modified_by": "Administrator", "owner": "Administrator" }, @@ -271,6 +271,7 @@ "print_hide": 1 }, { + "depends_on": "eval:doc.purpose!==\"Sales Return\" || doc.purpose!===\"Purchase Return\"", "doctype": "DocField", "fieldname": "sb1", "fieldtype": "Section Break", From a2b3eb17e3abe2c9391161a757ee0d82622a4c87 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 19 Mar 2013 17:48:50 +0530 Subject: [PATCH 17/19] fix in depends on of stock entry --- stock/doctype/stock_entry/stock_entry.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stock/doctype/stock_entry/stock_entry.txt b/stock/doctype/stock_entry/stock_entry.txt index ecbd9c6b72..af703989cc 100644 --- a/stock/doctype/stock_entry/stock_entry.txt +++ b/stock/doctype/stock_entry/stock_entry.txt @@ -2,7 +2,7 @@ { "creation": "2013-03-11 12:34:40", "docstatus": 0, - "modified": "2013-03-19 15:33:14", + "modified": "2013-03-19 17:48:29", "modified_by": "Administrator", "owner": "Administrator" }, @@ -271,7 +271,7 @@ "print_hide": 1 }, { - "depends_on": "eval:doc.purpose!==\"Sales Return\" || doc.purpose!===\"Purchase Return\"", + "depends_on": "eval:(doc.purpose!==\"Sales Return\" || doc.purpose!==\"Purchase Return\")", "doctype": "DocField", "fieldname": "sb1", "fieldtype": "Section Break", From 9bddd836045d028087d2480e299e52a29003317f Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 19 Mar 2013 18:40:35 +0530 Subject: [PATCH 18/19] fix in global defaults --- setup/doctype/global_defaults/global_defaults.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/doctype/global_defaults/global_defaults.py b/setup/doctype/global_defaults/global_defaults.py index 6f3ab4a71d..8d94a03aa5 100644 --- a/setup/doctype/global_defaults/global_defaults.py +++ b/setup/doctype/global_defaults/global_defaults.py @@ -43,6 +43,7 @@ keydict = { 'maintain_same_rate' : 'maintain_same_rate', 'session_expiry': 'session_expiry', 'disable_rounded_total': 'disable_rounded_total', + "update_stock": "update_stock", } class DocType: From e31d64ffe1ab2845aa389ffa6fafca45fefa7ddb Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Tue, 19 Mar 2013 18:42:29 +0530 Subject: [PATCH 19/19] save global defaults --- patches/patch_list.py | 1 + 1 file changed, 1 insertion(+) diff --git a/patches/patch_list.py b/patches/patch_list.py index 236ef45fd2..9c0d9b8199 100644 --- a/patches/patch_list.py +++ b/patches/patch_list.py @@ -214,4 +214,5 @@ patch_list = [ "patches.march_2013.p04_pos_update_stock_check", "patches.march_2013.p05_payment_reconciliation", "patches.march_2013.p06_remove_sales_purchase_return_tool", + "execute:webnotes.bean('Global Defaults').save()" ] \ No newline at end of file