mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-31 18:59:08 +00:00
Removed Sales/Purchase Return option from Stock Entry
This commit is contained in:
@@ -81,20 +81,19 @@ class SerialNo(StockController):
|
|||||||
def set_status(self, last_sle):
|
def set_status(self, last_sle):
|
||||||
if last_sle:
|
if last_sle:
|
||||||
if last_sle.voucher_type == "Stock Entry":
|
if last_sle.voucher_type == "Stock Entry":
|
||||||
document_type = frappe.db.get_value("Stock Entry", last_sle.voucher_no,
|
document_type = frappe.db.get_value("Stock Entry", last_sle.voucher_no, "purpose")
|
||||||
"purpose")
|
|
||||||
else:
|
else:
|
||||||
document_type = last_sle.voucher_type
|
document_type = last_sle.voucher_type
|
||||||
|
|
||||||
if last_sle.actual_qty > 0:
|
if last_sle.actual_qty > 0:
|
||||||
if document_type == "Sales Return":
|
if document_type in ("Delivery Note", "Sales Invoice", "Sales Return"):
|
||||||
self.status = "Sales Returned"
|
self.status = "Sales Returned"
|
||||||
else:
|
else:
|
||||||
self.status = "Available"
|
self.status = "Available"
|
||||||
else:
|
else:
|
||||||
if document_type == "Purchase Return":
|
if document_type in ("Purchase Receipt", "Purchase Invoice", "Purchase Return"):
|
||||||
self.status = "Purchase Returned"
|
self.status = "Purchase Returned"
|
||||||
elif last_sle.voucher_type in ("Delivery Note", "Sales Invoice"):
|
elif document_type in ("Delivery Note", "Sales Invoice"):
|
||||||
self.status = "Delivered"
|
self.status = "Delivered"
|
||||||
else:
|
else:
|
||||||
self.status = "Not Available"
|
self.status = "Not Available"
|
||||||
|
|||||||
@@ -7,20 +7,7 @@ frappe.provide("erpnext.stock");
|
|||||||
erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
||||||
setup: function() {
|
setup: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
|
|
||||||
this.frm.fields_dict.delivery_note_no.get_query = function() {
|
|
||||||
return { query: "erpnext.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 {
|
|
||||||
filters:{ 'docstatus': 1 }
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
this.frm.fields_dict.bom_no.get_query = function() {
|
this.frm.fields_dict.bom_no.get_query = function() {
|
||||||
return {
|
return {
|
||||||
filters:{ 'docstatus': 1 }
|
filters:{ 'docstatus': 1 }
|
||||||
@@ -28,20 +15,7 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.frm.fields_dict.items.grid.get_field('item_code').get_query = function() {
|
this.frm.fields_dict.items.grid.get_field('item_code').get_query = function() {
|
||||||
if(in_list(["Sales Return", "Purchase Return"], me.frm.doc.purpose) &&
|
return erpnext.queries.item({is_stock_item: "Yes"});
|
||||||
me.get_doctype_docname()) {
|
|
||||||
return {
|
|
||||||
query: "erpnext.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"});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.frm.set_query("purchase_order", function() {
|
this.frm.set_query("purchase_order", function() {
|
||||||
@@ -84,19 +58,6 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
|||||||
this.toggle_enable_bom();
|
this.toggle_enable_bom();
|
||||||
this.show_stock_ledger();
|
this.show_stock_ledger();
|
||||||
this.show_general_ledger();
|
this.show_general_ledger();
|
||||||
|
|
||||||
if(this.frm.doc.docstatus === 1 && frappe.boot.user.can_create.indexOf("Journal Entry")!==-1
|
|
||||||
&& this.frm.doc.__onload.credit_debit_note_exists == 0 ) {
|
|
||||||
if(this.frm.doc.purpose === "Sales Return") {
|
|
||||||
this.frm.add_custom_button(__("Make Credit Note"),
|
|
||||||
function() { me.make_return_jv(); }, frappe.boot.doctype_icons["Journal Entry"]);
|
|
||||||
this.add_excise_button();
|
|
||||||
} else if(this.frm.doc.purpose === "Purchase Return") {
|
|
||||||
this.frm.add_custom_button(__("Make Debit Note"),
|
|
||||||
function() { me.make_return_jv(); }, frappe.boot.doctype_icons["Journal Entry"]);
|
|
||||||
this.add_excise_button();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
on_submit: function() {
|
on_submit: function() {
|
||||||
@@ -111,15 +72,10 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
|||||||
var me = this;
|
var me = this;
|
||||||
|
|
||||||
if(cint(frappe.defaults.get_default("auto_accounting_for_stock")) && this.frm.doc.company) {
|
if(cint(frappe.defaults.get_default("auto_accounting_for_stock")) && this.frm.doc.company) {
|
||||||
var account_for = "stock_adjustment_account";
|
|
||||||
|
|
||||||
if (this.frm.doc.purpose == "Purchase Return")
|
|
||||||
account_for = "stock_received_but_not_billed";
|
|
||||||
|
|
||||||
return this.frm.call({
|
return this.frm.call({
|
||||||
method: "erpnext.accounts.utils.get_company_default",
|
method: "erpnext.accounts.utils.get_company_default",
|
||||||
args: {
|
args: {
|
||||||
"fieldname": account_for,
|
"fieldname": "stock_adjustment_account",
|
||||||
"company": this.frm.doc.company
|
"company": this.frm.doc.company
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
@@ -192,35 +148,6 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
|||||||
this.frm.toggle_enable("bom_no", !in_list(["Manufacture", "Material Transfer for Manufacture"], this.frm.doc.purpose));
|
this.frm.toggle_enable("bom_no", !in_list(["Manufacture", "Material Transfer for Manufacture"], this.frm.doc.purpose));
|
||||||
},
|
},
|
||||||
|
|
||||||
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(__("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(__("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(__("Please enter Purchase Receipt No to proceed"));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
add_excise_button: function() {
|
add_excise_button: function() {
|
||||||
if(frappe.boot.sysdefaults.country === "India")
|
if(frappe.boot.sysdefaults.country === "India")
|
||||||
this.frm.add_custom_button(__("Make Excise Invoice"), function() {
|
this.frm.add_custom_button(__("Make Excise Invoice"), function() {
|
||||||
@@ -231,37 +158,16 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
|||||||
}, frappe.boot.doctype_icons["Journal Entry"], "btn-default");
|
}, frappe.boot.doctype_icons["Journal Entry"], "btn-default");
|
||||||
},
|
},
|
||||||
|
|
||||||
make_return_jv: function() {
|
|
||||||
if(this.get_doctype_docname()) {
|
|
||||||
return this.frm.call({
|
|
||||||
method: "make_return_jv",
|
|
||||||
args: {
|
|
||||||
stock_entry: this.frm.doc.name
|
|
||||||
},
|
|
||||||
callback: function(r) {
|
|
||||||
if(!r.exc) {
|
|
||||||
var doclist = frappe.model.sync(r.message);
|
|
||||||
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
items_add: function(doc, cdt, cdn) {
|
items_add: function(doc, cdt, cdn) {
|
||||||
var row = frappe.get_doc(cdt, cdn);
|
var row = frappe.get_doc(cdt, cdn);
|
||||||
this.frm.script_manager.copy_from_first_row("items", row,
|
this.frm.script_manager.copy_from_first_row("items", row, ["expense_account", "cost_center"]);
|
||||||
["expense_account", "cost_center"]);
|
|
||||||
|
|
||||||
if(!row.s_warehouse) row.s_warehouse = this.frm.doc.from_warehouse;
|
if(!row.s_warehouse) row.s_warehouse = this.frm.doc.from_warehouse;
|
||||||
if(!row.t_warehouse) row.t_warehouse = this.frm.doc.to_warehouse;
|
if(!row.t_warehouse) row.t_warehouse = this.frm.doc.to_warehouse;
|
||||||
},
|
},
|
||||||
|
|
||||||
source_mandatory: ["Material Issue", "Material Transfer", "Purchase Return", "Subcontract",
|
source_mandatory: ["Material Issue", "Material Transfer", "Subcontract", "Material Transfer for Manufacture"],
|
||||||
"Material Transfer for Manufacture"],
|
target_mandatory: ["Material Receipt", "Material Transfer", "Subcontract", "Material Transfer for Manufacture"],
|
||||||
target_mandatory: ["Material Receipt", "Material Transfer", "Sales Return", "Subcontract",
|
|
||||||
"Material Transfer for Manufacture"],
|
|
||||||
|
|
||||||
from_warehouse: function(doc) {
|
from_warehouse: function(doc) {
|
||||||
var me = this;
|
var me = this;
|
||||||
@@ -295,92 +201,21 @@ erpnext.stock.StockEntry = erpnext.stock.StockController.extend({
|
|||||||
|
|
||||||
items_on_form_rendered: function(doc, grid_row) {
|
items_on_form_rendered: function(doc, grid_row) {
|
||||||
erpnext.setup_serial_no();
|
erpnext.setup_serial_no();
|
||||||
},
|
|
||||||
|
|
||||||
customer: function() {
|
|
||||||
this.get_party_details({
|
|
||||||
party: this.frm.doc.customer,
|
|
||||||
party_type:"Customer",
|
|
||||||
doctype: this.frm.doc.doctype
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
supplier: function() {
|
|
||||||
this.get_party_details({
|
|
||||||
party: this.frm.doc.supplier,
|
|
||||||
party_type:"Supplier",
|
|
||||||
doctype: this.frm.doc.doctype
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
get_party_details: function(args) {
|
|
||||||
var me = this;
|
|
||||||
frappe.call({
|
|
||||||
method: "erpnext.accounts.party.get_party_details",
|
|
||||||
args: args,
|
|
||||||
callback: function(r) {
|
|
||||||
if(r.message) {
|
|
||||||
me.frm.set_value({
|
|
||||||
"customer_name": r.message["customer_name"],
|
|
||||||
"customer_address": r.message["address_display"]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
delivery_note_no: function() {
|
|
||||||
this.get_party_details_from_against_voucher({
|
|
||||||
ref_dt: "Delivery Note",
|
|
||||||
ref_dn: this.frm.doc.delivery_note_no
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
sales_invoice_no: function() {
|
|
||||||
this.get_party_details_from_against_voucher({
|
|
||||||
ref_dt: "Sales Invoice",
|
|
||||||
ref_dn: this.frm.doc.sales_invoice_no
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
purchase_receipt_no: function() {
|
|
||||||
this.get_party_details_from_against_voucher({
|
|
||||||
ref_dt: "Purchase Receipt",
|
|
||||||
ref_dn: this.frm.doc.purchase_receipt_no
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
get_party_details_from_against_voucher: function(args) {
|
|
||||||
return this.frm.call({
|
|
||||||
method: "erpnext.stock.doctype.stock_entry.stock_entry.get_party_details",
|
|
||||||
args: args,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
cur_frm.script_manager.make(erpnext.stock.StockEntry);
|
cur_frm.script_manager.make(erpnext.stock.StockEntry);
|
||||||
|
|
||||||
cur_frm.cscript.toggle_related_fields = function(doc) {
|
cur_frm.cscript.toggle_related_fields = function(doc) {
|
||||||
disable_from_warehouse = inList(["Material Receipt", "Sales Return"], doc.purpose);
|
cur_frm.toggle_enable("from_warehouse", doc.purpose!='Material Receipt');
|
||||||
disable_to_warehouse = inList(["Material Issue", "Purchase Return"], doc.purpose);
|
cur_frm.toggle_enable("to_warehouse", doc.purpose!='Material Issue');
|
||||||
|
|
||||||
cur_frm.toggle_enable("from_warehouse", !disable_from_warehouse);
|
cur_frm.fields_dict["items"].grid.set_column_disp("s_warehouse", doc.purpose!='Material Receipt');
|
||||||
cur_frm.toggle_enable("to_warehouse", !disable_to_warehouse);
|
cur_frm.fields_dict["items"].grid.set_column_disp("t_warehouse", doc.purpose!='Material Issue');
|
||||||
|
|
||||||
cur_frm.fields_dict["items"].grid.set_column_disp("s_warehouse", !disable_from_warehouse);
|
|
||||||
cur_frm.fields_dict["items"].grid.set_column_disp("t_warehouse", !disable_to_warehouse);
|
|
||||||
|
|
||||||
cur_frm.cscript.toggle_enable_bom();
|
cur_frm.cscript.toggle_enable_bom();
|
||||||
|
|
||||||
if(doc.purpose == 'Purchase Return') {
|
if (doc.purpose == 'Subcontract') {
|
||||||
doc.customer = doc.customer_name = doc.customer_address =
|
|
||||||
doc.delivery_note_no = doc.sales_invoice_no = null;
|
|
||||||
doc.bom_no = doc.production_order = doc.fg_completed_qty = null;
|
|
||||||
} else if(doc.purpose == 'Sales Return') {
|
|
||||||
doc.supplier=doc.supplier_name = doc.supplier_address = doc.purchase_receipt_no=null;
|
|
||||||
doc.bom_no = doc.production_order = doc.fg_completed_qty = null;
|
|
||||||
} else if (doc.purpose == 'Subcontract') {
|
|
||||||
doc.customer = doc.customer_name = doc.customer_address =
|
doc.customer = doc.customer_name = doc.customer_address =
|
||||||
doc.delivery_note_no = doc.sales_invoice_no = null;
|
doc.delivery_note_no = doc.sales_invoice_no = null;
|
||||||
} else {
|
} else {
|
||||||
@@ -388,7 +223,7 @@ cur_frm.cscript.toggle_related_fields = function(doc) {
|
|||||||
doc.delivery_note_no = doc.sales_invoice_no = doc.supplier =
|
doc.delivery_note_no = doc.sales_invoice_no = doc.supplier =
|
||||||
doc.supplier_name = doc.supplier_address = doc.purchase_receipt_no = null;
|
doc.supplier_name = doc.supplier_address = doc.purchase_receipt_no = null;
|
||||||
}
|
}
|
||||||
if(in_list(["Material Receipt", "Sales Return", "Purchase Return"], doc.purpose)) {
|
if(doc.purpose == "Material Receipt") {
|
||||||
cur_frm.set_value("from_bom", 0);
|
cur_frm.set_value("from_bom", 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -505,8 +340,6 @@ cur_frm.cscript.uom = function(doc, cdt, cdn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.validate = function(doc, cdt, cdn) {
|
cur_frm.cscript.validate = function(doc, cdt, cdn) {
|
||||||
if($.inArray(cur_frm.doc.purpose, ["Purchase Return", "Sales Return"])!==-1)
|
|
||||||
validated = cur_frm.cscript.get_doctype_docname() ? true : false;
|
|
||||||
cur_frm.cscript.validate_items(doc);
|
cur_frm.cscript.validate_items(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -526,14 +359,6 @@ cur_frm.cscript.cost_center = function(doc, cdt, cdn) {
|
|||||||
erpnext.utils.copy_value_in_all_row(doc, cdt, cdn, "items", "cost_center");
|
erpnext.utils.copy_value_in_all_row(doc, cdt, cdn, "items", "cost_center");
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.fields_dict.customer.get_query = function(doc, cdt, cdn) {
|
|
||||||
return { query: "erpnext.controllers.queries.customer_query" }
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_frm.fields_dict.supplier.get_query = function(doc, cdt, cdn) {
|
|
||||||
return { query: "erpnext.controllers.queries.supplier_query" }
|
|
||||||
}
|
|
||||||
|
|
||||||
cur_frm.cscript.company = function(doc, cdt, cdn) {
|
cur_frm.cscript.company = function(doc, cdt, cdn) {
|
||||||
if(doc.company) {
|
if(doc.company) {
|
||||||
erpnext.get_fiscal_year(doc.company, doc.posting_date, function() {
|
erpnext.get_fiscal_year(doc.company, doc.posting_date, function() {
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"oldfieldname": "purpose",
|
"oldfieldname": "purpose",
|
||||||
"oldfieldtype": "Select",
|
"oldfieldtype": "Select",
|
||||||
"options": "Material Issue\nMaterial Receipt\nMaterial Transfer\nMaterial Transfer for Manufacture\nManufacture\nRepack\nSubcontract\nSales Return\nPurchase Return",
|
"options": "Material Issue\nMaterial Receipt\nMaterial Transfer\nMaterial Transfer for Manufacture\nManufacture\nRepack\nSubcontract",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
@@ -678,7 +678,7 @@
|
|||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2015-07-13 05:28:26.085266",
|
"modified": "2015-07-17 15:41:00.980883",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Stock Entry",
|
"name": "Stock Entry",
|
||||||
@@ -695,7 +695,7 @@
|
|||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Stock User",
|
"role": "Material User",
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 1,
|
"submit": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
@@ -741,7 +741,7 @@
|
|||||||
"print": 1,
|
"print": 1,
|
||||||
"read": 1,
|
"read": 1,
|
||||||
"report": 1,
|
"report": 1,
|
||||||
"role": "Stock Manager",
|
"role": "Material Manager",
|
||||||
"share": 1,
|
"share": 1,
|
||||||
"submit": 1,
|
"submit": 1,
|
||||||
"write": 1
|
"write": 1
|
||||||
|
|||||||
@@ -4,10 +4,8 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
|
|
||||||
from frappe.utils import cstr, cint, flt, comma_or, get_datetime, getdate
|
|
||||||
|
|
||||||
from frappe import _
|
from frappe import _
|
||||||
|
from frappe.utils import cstr, cint, flt, comma_or, get_datetime, getdate
|
||||||
from erpnext.stock.utils import get_incoming_rate
|
from erpnext.stock.utils import get_incoming_rate
|
||||||
from erpnext.stock.stock_ledger import get_previous_sle, NegativeStockError
|
from erpnext.stock.stock_ledger import get_previous_sle, NegativeStockError
|
||||||
from erpnext.controllers.queries import get_match_cond
|
from erpnext.controllers.queries import get_match_cond
|
||||||
@@ -16,7 +14,6 @@ from erpnext.manufacturing.doctype.bom.bom import validate_bom_no
|
|||||||
from erpnext.accounts.utils import validate_fiscal_year
|
from erpnext.accounts.utils import validate_fiscal_year
|
||||||
|
|
||||||
class NotUpdateStockError(frappe.ValidationError): pass
|
class NotUpdateStockError(frappe.ValidationError): pass
|
||||||
class StockOverReturnError(frappe.ValidationError): pass
|
|
||||||
class IncorrectValuationRateError(frappe.ValidationError): pass
|
class IncorrectValuationRateError(frappe.ValidationError): pass
|
||||||
class DuplicateEntryForProductionOrderError(frappe.ValidationError): pass
|
class DuplicateEntryForProductionOrderError(frappe.ValidationError): pass
|
||||||
class OperationsNotCompleteError(frappe.ValidationError): pass
|
class OperationsNotCompleteError(frappe.ValidationError): pass
|
||||||
@@ -37,13 +34,6 @@ class StockEntry(StockController):
|
|||||||
item.update(get_available_qty(item.item_code,
|
item.update(get_available_qty(item.item_code,
|
||||||
item.s_warehouse))
|
item.s_warehouse))
|
||||||
|
|
||||||
count = frappe.db.exists({
|
|
||||||
"doctype": "Journal Entry",
|
|
||||||
"stock_entry":self.name,
|
|
||||||
"docstatus":1
|
|
||||||
})
|
|
||||||
self.get("__onload").credit_debit_note_exists = 1 if count else 0
|
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.pro_doc = None
|
self.pro_doc = None
|
||||||
if self.production_order:
|
if self.production_order:
|
||||||
@@ -84,16 +74,13 @@ class StockEntry(StockController):
|
|||||||
|
|
||||||
def validate_purpose(self):
|
def validate_purpose(self):
|
||||||
valid_purposes = ["Material Issue", "Material Receipt", "Material Transfer", "Material Transfer for Manufacture",
|
valid_purposes = ["Material Issue", "Material Receipt", "Material Transfer", "Material Transfer for Manufacture",
|
||||||
"Manufacture", "Repack", "Subcontract", "Sales Return", "Purchase Return"]
|
"Manufacture", "Repack", "Subcontract"]
|
||||||
if self.purpose not in valid_purposes:
|
if self.purpose not in valid_purposes:
|
||||||
frappe.throw(_("Purpose must be one of {0}").format(comma_or(valid_purposes)))
|
frappe.throw(_("Purpose must be one of {0}").format(comma_or(valid_purposes)))
|
||||||
|
|
||||||
if self.purpose in ("Manufacture", "Repack", "Sales Return") and not self.difference_account:
|
if self.purpose in ("Manufacture", "Repack") and not self.difference_account:
|
||||||
self.difference_account = frappe.db.get_value("Company", self.company, "default_expense_account")
|
self.difference_account = frappe.db.get_value("Company", self.company, "default_expense_account")
|
||||||
|
|
||||||
if self.purpose in ("Purchase Return") and not self.difference_account:
|
|
||||||
frappe.throw(_("Difference Account mandatory for purpose '{0}'").format(self.purpose))
|
|
||||||
|
|
||||||
def set_transfer_qty(self):
|
def set_transfer_qty(self):
|
||||||
for item in self.get("items"):
|
for item in self.get("items"):
|
||||||
if not flt(item.qty):
|
if not flt(item.qty):
|
||||||
@@ -122,7 +109,7 @@ class StockEntry(StockController):
|
|||||||
if not item.transfer_qty:
|
if not item.transfer_qty:
|
||||||
item.transfer_qty = item.qty * item.conversion_factor
|
item.transfer_qty = item.qty * item.conversion_factor
|
||||||
|
|
||||||
if (self.purpose in ("Material Transfer", "Sales Return", "Purchase Return", "Material Transfer for Manufacture")
|
if (self.purpose in ("Material Transfer", "Material Transfer for Manufacture")
|
||||||
and not item.serial_no
|
and not item.serial_no
|
||||||
and item.item_code in serialized_items):
|
and item.item_code in serialized_items):
|
||||||
frappe.throw(_("Row #{0}: Please specify Serial No for Item {1}").format(item.idx, item.item_code),
|
frappe.throw(_("Row #{0}: Please specify Serial No for Item {1}").format(item.idx, item.item_code),
|
||||||
@@ -131,8 +118,8 @@ class StockEntry(StockController):
|
|||||||
def validate_warehouse(self):
|
def validate_warehouse(self):
|
||||||
"""perform various (sometimes conditional) validations on warehouse"""
|
"""perform various (sometimes conditional) validations on warehouse"""
|
||||||
|
|
||||||
source_mandatory = ["Material Issue", "Material Transfer", "Purchase Return", "Subcontract", "Material Transfer for Manufacture"]
|
source_mandatory = ["Material Issue", "Material Transfer", "Subcontract", "Material Transfer for Manufacture"]
|
||||||
target_mandatory = ["Material Receipt", "Material Transfer", "Sales Return", "Subcontract", "Material Transfer for Manufacture"]
|
target_mandatory = ["Material Receipt", "Material Transfer", "Subcontract", "Material Transfer for Manufacture"]
|
||||||
|
|
||||||
validate_for_manufacture_repack = any([d.bom_no for d in self.get("items")])
|
validate_for_manufacture_repack = any([d.bom_no for d in self.get("items")])
|
||||||
|
|
||||||
@@ -291,8 +278,8 @@ class StockEntry(StockController):
|
|||||||
|
|
||||||
# get incoming rate
|
# get incoming rate
|
||||||
if not d.bom_no:
|
if not d.bom_no:
|
||||||
if not flt(d.incoming_rate) or d.s_warehouse or self.purpose == "Sales Return" or force:
|
if not flt(d.incoming_rate) or d.s_warehouse or force:
|
||||||
incoming_rate = flt(self.get_incoming_rate(args), self.precision("incoming_rate", d))
|
incoming_rate = flt(get_incoming_rate(args), self.precision("incoming_rate", d))
|
||||||
if incoming_rate > 0:
|
if incoming_rate > 0:
|
||||||
d.incoming_rate = incoming_rate
|
d.incoming_rate = incoming_rate
|
||||||
|
|
||||||
@@ -336,27 +323,6 @@ class StockEntry(StockController):
|
|||||||
|
|
||||||
return operation_cost_per_unit + (flt(self.additional_operating_cost) / flt(qty))
|
return operation_cost_per_unit + (flt(self.additional_operating_cost) / flt(qty))
|
||||||
|
|
||||||
def get_incoming_rate(self, args):
|
|
||||||
incoming_rate = 0
|
|
||||||
if self.purpose == "Sales Return":
|
|
||||||
incoming_rate = self.get_incoming_rate_for_sales_return(args)
|
|
||||||
else:
|
|
||||||
incoming_rate = get_incoming_rate(args)
|
|
||||||
|
|
||||||
return incoming_rate
|
|
||||||
|
|
||||||
def get_incoming_rate_for_sales_return(self, args):
|
|
||||||
incoming_rate = 0.0
|
|
||||||
if (self.delivery_note_no or self.sales_invoice_no) and args.get("item_code"):
|
|
||||||
incoming_rate = frappe.db.sql("""select abs(ifnull(stock_value_difference, 0) / actual_qty)
|
|
||||||
from `tabStock Ledger Entry`
|
|
||||||
where voucher_type = %s and voucher_no = %s and item_code = %s limit 1""",
|
|
||||||
((self.delivery_note_no and "Delivery Note" or "Sales Invoice"),
|
|
||||||
self.delivery_note_no or self.sales_invoice_no, args.item_code))
|
|
||||||
incoming_rate = incoming_rate[0][0] if incoming_rate else 0.0
|
|
||||||
|
|
||||||
return incoming_rate
|
|
||||||
|
|
||||||
def validate_purchase_order(self):
|
def validate_purchase_order(self):
|
||||||
"""Throw exception if more raw material is transferred against Purchase Order than in
|
"""Throw exception if more raw material is transferred against Purchase Order than in
|
||||||
the raw materials supplied table"""
|
the raw materials supplied table"""
|
||||||
@@ -403,55 +369,6 @@ class StockEntry(StockController):
|
|||||||
frappe.throw(_("Finished Item {0} must be entered for Manufacture type entry")
|
frappe.throw(_("Finished Item {0} must be entered for Manufacture type entry")
|
||||||
.format(production_item))
|
.format(production_item))
|
||||||
|
|
||||||
def validate_return_reference_doc(self):
|
|
||||||
"""validate item with reference doc"""
|
|
||||||
ref = get_return_doc_and_details(self)
|
|
||||||
|
|
||||||
if ref.doc:
|
|
||||||
# validate docstatus
|
|
||||||
if ref.doc.docstatus != 1:
|
|
||||||
frappe.throw(_("{0} {1} must be submitted").format(ref.doc.doctype, ref.doc.name),
|
|
||||||
frappe.InvalidStatusError)
|
|
||||||
|
|
||||||
# update stock check
|
|
||||||
if ref.doc.doctype == "Sales Invoice" and cint(ref.doc.update_stock) != 1:
|
|
||||||
frappe.throw(_("'Update Stock' for Sales Invoice {0} must be set").format(ref.doc.name), NotUpdateStockError)
|
|
||||||
|
|
||||||
# posting date check
|
|
||||||
ref_posting_datetime = "%s %s" % (ref.doc.posting_date, ref.doc.posting_time or "00:00:00")
|
|
||||||
|
|
||||||
if get_datetime(ref_posting_datetime) < get_datetime(ref_posting_datetime):
|
|
||||||
from frappe.utils.dateutils import datetime_in_user_format
|
|
||||||
frappe.throw(_("Posting timestamp must be after {0}")
|
|
||||||
.format(datetime_in_user_format(ref_posting_datetime)))
|
|
||||||
|
|
||||||
stock_items = get_stock_items_for_return(ref.doc, ref.parentfields)
|
|
||||||
already_returned_item_qty = self.get_already_returned_item_qty(ref.fieldname)
|
|
||||||
|
|
||||||
for item in self.get("items"):
|
|
||||||
# validate if item exists in the ref doc and that it is a stock item
|
|
||||||
if item.item_code not in stock_items:
|
|
||||||
frappe.throw(_("Item {0} does not exist in {1} {2}").format(item.item_code, ref.doc.doctype, ref.doc.name),
|
|
||||||
frappe.DoesNotExistError)
|
|
||||||
|
|
||||||
# validate quantity <= ref item's qty - qty already returned
|
|
||||||
if self.purpose == "Purchase Return":
|
|
||||||
ref_item_qty = sum([flt(d.qty)*flt(d.conversion_factor) for d in ref.doc.get({"item_code": item.item_code})])
|
|
||||||
elif self.purpose == "Sales Return":
|
|
||||||
ref_item_qty = sum([flt(d.qty) for d in ref.doc.get({"item_code": item.item_code})])
|
|
||||||
returnable_qty = ref_item_qty - flt(already_returned_item_qty.get(item.item_code))
|
|
||||||
if not returnable_qty:
|
|
||||||
frappe.throw(_("Item {0} has already been returned").format(item.item_code), StockOverReturnError)
|
|
||||||
elif item.transfer_qty > returnable_qty:
|
|
||||||
frappe.throw(_("Cannot return more than {0} for Item {1}").format(returnable_qty, item.item_code),
|
|
||||||
StockOverReturnError)
|
|
||||||
|
|
||||||
def get_already_returned_item_qty(self, ref_fieldname):
|
|
||||||
return dict(frappe.db.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.get(ref_fieldname),)))
|
|
||||||
|
|
||||||
def update_stock_ledger(self):
|
def update_stock_ledger(self):
|
||||||
sl_entries = []
|
sl_entries = []
|
||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
@@ -514,6 +431,7 @@ class StockEntry(StockController):
|
|||||||
(args.get('item_code')), as_dict = 1)
|
(args.get('item_code')), as_dict = 1)
|
||||||
if not item:
|
if not item:
|
||||||
frappe.throw(_("Item {0} is not active or end of life has been reached").format(args.get("item_code")))
|
frappe.throw(_("Item {0} is not active or end of life has been reached").format(args.get("item_code")))
|
||||||
|
|
||||||
item = item[0]
|
item = item[0]
|
||||||
|
|
||||||
ret = {
|
ret = {
|
||||||
@@ -561,7 +479,7 @@ class StockEntry(StockController):
|
|||||||
|
|
||||||
ret = {
|
ret = {
|
||||||
"actual_qty" : get_previous_sle(args).get("qty_after_transaction") or 0,
|
"actual_qty" : get_previous_sle(args).get("qty_after_transaction") or 0,
|
||||||
"incoming_rate" : self.get_incoming_rate(args)
|
"incoming_rate" : get_incoming_rate(args)
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@@ -738,15 +656,6 @@ class StockEntry(StockController):
|
|||||||
if getdate(self.posting_date) > getdate(expiry_date):
|
if getdate(self.posting_date) > getdate(expiry_date):
|
||||||
frappe.throw(_("Batch {0} of Item {1} has expired.").format(item.batch_no, item.item_code))
|
frappe.throw(_("Batch {0} of Item {1} has expired.").format(item.batch_no, item.item_code))
|
||||||
|
|
||||||
@frappe.whitelist()
|
|
||||||
def get_party_details(ref_dt, ref_dn):
|
|
||||||
if ref_dt in ["Delivery Note", "Sales Invoice"]:
|
|
||||||
res = frappe.db.get_value(ref_dt, ref_dn,
|
|
||||||
["customer", "customer_name", "address_display as customer_address"], as_dict=1)
|
|
||||||
else:
|
|
||||||
res = frappe.db.get_value(ref_dt, ref_dn,
|
|
||||||
["supplier", "supplier_name", "address_display as supplier_address"], as_dict=1)
|
|
||||||
return res or {}
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_production_order_details(production_order):
|
def get_production_order_details(production_order):
|
||||||
@@ -756,264 +665,3 @@ def get_production_order_details(production_order):
|
|||||||
from `tabProduction Order` where name = %s""", production_order, as_dict=1)
|
from `tabProduction Order` where name = %s""", production_order, as_dict=1)
|
||||||
|
|
||||||
return res and res[0] or {}
|
return res and res[0] or {}
|
||||||
|
|
||||||
def query_sales_return_doc(doctype, txt, searchfield, start, page_len, filters):
|
|
||||||
conditions = ""
|
|
||||||
if doctype == "Sales Invoice":
|
|
||||||
conditions = "and update_stock=1"
|
|
||||||
|
|
||||||
return frappe.db.sql("""select name, customer, customer_name
|
|
||||||
from `tab%s` where docstatus = 1
|
|
||||||
and (`%s` like %%(txt)s
|
|
||||||
or `customer` like %%(txt)s) %s %s
|
|
||||||
order by name, customer, customer_name
|
|
||||||
limit %s""" % (doctype, searchfield, conditions,
|
|
||||||
get_match_cond(doctype), "%(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 frappe.db.sql("""select name, supplier, supplier_name
|
|
||||||
from `tab%s` where docstatus = 1
|
|
||||||
and (`%s` like %%(txt)s
|
|
||||||
or `supplier` like %%(txt)s) %s
|
|
||||||
order by name, supplier, supplier_name
|
|
||||||
limit %s""" % (doctype, searchfield, get_match_cond(doctype),
|
|
||||||
"%(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("%", "")
|
|
||||||
|
|
||||||
ref = get_return_doc_and_details(filters)
|
|
||||||
|
|
||||||
stock_items = get_stock_items_for_return(ref.doc, ref.parentfields)
|
|
||||||
|
|
||||||
result = []
|
|
||||||
for item in ref.doc.get_all_children():
|
|
||||||
if getattr(item, "item_code", None) 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_doc, parentfields):
|
|
||||||
"""return item codes filtered from doc, which are stock items"""
|
|
||||||
if isinstance(parentfields, basestring):
|
|
||||||
parentfields = [parentfields]
|
|
||||||
|
|
||||||
all_items = list(set([d.item_code for d in
|
|
||||||
ref_doc.get_all_children() if d.get("item_code")]))
|
|
||||||
stock_items = frappe.db.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
|
|
||||||
|
|
||||||
def get_return_doc_and_details(args):
|
|
||||||
ref = frappe._dict()
|
|
||||||
|
|
||||||
# get ref_doc
|
|
||||||
if args.get("purpose") in return_map:
|
|
||||||
for fieldname, val in return_map[args.get("purpose")].items():
|
|
||||||
if args.get(fieldname):
|
|
||||||
ref.fieldname = fieldname
|
|
||||||
ref.doc = frappe.get_doc(val[0], args.get(fieldname))
|
|
||||||
ref.parentfields = val[1]
|
|
||||||
break
|
|
||||||
|
|
||||||
return ref
|
|
||||||
|
|
||||||
return_map = {
|
|
||||||
"Sales Return": {
|
|
||||||
# [Ref DocType, [Item tables' parentfields]]
|
|
||||||
"delivery_note_no": ["Delivery Note", ["items", "packed_items"]],
|
|
||||||
"sales_invoice_no": ["Sales Invoice", ["items", "packed_items"]]
|
|
||||||
},
|
|
||||||
"Purchase Return": {
|
|
||||||
"purchase_receipt_no": ["Purchase Receipt", ["items"]]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
|
||||||
def make_return_jv(stock_entry):
|
|
||||||
se = frappe.get_doc("Stock Entry", stock_entry)
|
|
||||||
if not se.purpose in ["Sales Return", "Purchase Return"]:
|
|
||||||
return
|
|
||||||
|
|
||||||
ref = get_return_doc_and_details(se)
|
|
||||||
|
|
||||||
if ref.doc.doctype == "Delivery Note":
|
|
||||||
result = make_return_jv_from_delivery_note(se, ref)
|
|
||||||
elif ref.doc.doctype == "Sales Invoice":
|
|
||||||
result = make_return_jv_from_sales_invoice(se, ref)
|
|
||||||
elif ref.doc.doctype == "Purchase Receipt":
|
|
||||||
result = make_return_jv_from_purchase_receipt(se, ref)
|
|
||||||
|
|
||||||
# create jv doc and fetch balance for each unique row item
|
|
||||||
jv = frappe.new_doc("Journal Entry")
|
|
||||||
jv.update({
|
|
||||||
"posting_date": se.posting_date,
|
|
||||||
"voucher_type": se.purpose == "Sales Return" and "Credit Note" or "Debit Note",
|
|
||||||
"fiscal_year": se.fiscal_year,
|
|
||||||
"company": se.company,
|
|
||||||
"stock_entry": se.name
|
|
||||||
})
|
|
||||||
|
|
||||||
from erpnext.accounts.utils import get_balance_on
|
|
||||||
for r in result:
|
|
||||||
jv.append("accounts", {
|
|
||||||
"account": r.get("account"),
|
|
||||||
"party_type": r.get("party_type"),
|
|
||||||
"party": r.get("party"),
|
|
||||||
"balance": get_balance_on(r.get("account"), se.posting_date) if r.get("account") else 0
|
|
||||||
})
|
|
||||||
|
|
||||||
return jv
|
|
||||||
|
|
||||||
def make_return_jv_from_sales_invoice(se, ref):
|
|
||||||
# customer account entry
|
|
||||||
parent = {
|
|
||||||
"account": ref.doc.debit_to,
|
|
||||||
"party_type": "Customer",
|
|
||||||
"party": ref.doc.customer
|
|
||||||
}
|
|
||||||
|
|
||||||
# income account entries
|
|
||||||
children = []
|
|
||||||
for se_item in se.get("items"):
|
|
||||||
# find item in ref.doc
|
|
||||||
ref_item = ref.doc.get({"item_code": se_item.item_code})[0]
|
|
||||||
|
|
||||||
account = get_sales_account_from_item(ref.doc, ref_item)
|
|
||||||
|
|
||||||
if account not in children:
|
|
||||||
children.append(account)
|
|
||||||
|
|
||||||
return [parent] + [{"account": account} for account in children]
|
|
||||||
|
|
||||||
def get_sales_account_from_item(doc, ref_item):
|
|
||||||
account = None
|
|
||||||
if not getattr(ref_item, "income_account", None):
|
|
||||||
if ref_item.parent_item:
|
|
||||||
parent_item = doc.get("items", {"item_code": ref_item.parent_item})[0]
|
|
||||||
account = parent_item.income_account
|
|
||||||
else:
|
|
||||||
account = ref_item.income_account
|
|
||||||
|
|
||||||
return account
|
|
||||||
|
|
||||||
def make_return_jv_from_delivery_note(se, ref):
|
|
||||||
invoices_against_delivery = get_invoice_list("Sales Invoice Item", "delivery_note",
|
|
||||||
ref.doc.name)
|
|
||||||
|
|
||||||
if not invoices_against_delivery:
|
|
||||||
sales_orders_against_delivery = [d.against_sales_order for d in ref.doc.get_all_children() if getattr(d, "against_sales_order", None)]
|
|
||||||
|
|
||||||
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 []
|
|
||||||
|
|
||||||
packing_item_parent_map = dict([[d.item_code, d.parent_item] for d in ref.doc.get(ref.parentfields[1])])
|
|
||||||
|
|
||||||
parent = {}
|
|
||||||
children = []
|
|
||||||
|
|
||||||
for se_item in se.get("items"):
|
|
||||||
for sales_invoice in invoices_against_delivery:
|
|
||||||
si = frappe.get_doc("Sales Invoice", sales_invoice)
|
|
||||||
|
|
||||||
if se_item.item_code in packing_item_parent_map:
|
|
||||||
ref_item = si.get({"item_code": packing_item_parent_map[se_item.item_code]})
|
|
||||||
else:
|
|
||||||
ref_item = si.get({"item_code": se_item.item_code})
|
|
||||||
|
|
||||||
if not ref_item:
|
|
||||||
continue
|
|
||||||
|
|
||||||
ref_item = ref_item[0]
|
|
||||||
|
|
||||||
account = get_sales_account_from_item(si, ref_item)
|
|
||||||
|
|
||||||
if account not in children:
|
|
||||||
children.append(account)
|
|
||||||
|
|
||||||
if not parent:
|
|
||||||
parent = {
|
|
||||||
"account": si.debit_to,
|
|
||||||
"party_type": "Customer",
|
|
||||||
"party": si.customer
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
|
|
||||||
result = [parent] + [{"account": account} for account in children]
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def get_invoice_list(doctype, link_field, value):
|
|
||||||
if isinstance(value, basestring):
|
|
||||||
value = [value]
|
|
||||||
|
|
||||||
return frappe.db.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):
|
|
||||||
invoice_against_receipt = get_invoice_list("Purchase Invoice Item", "purchase_receipt",
|
|
||||||
ref.doc.name)
|
|
||||||
|
|
||||||
if not invoice_against_receipt:
|
|
||||||
purchase_orders_against_receipt = [d.prevdoc_docname for d in
|
|
||||||
ref.doc.get("items", {"prevdoc_doctype": "Purchase Order"})
|
|
||||||
if getattr(d, "prevdoc_docname", None)]
|
|
||||||
|
|
||||||
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 []
|
|
||||||
|
|
||||||
parent = {}
|
|
||||||
children = []
|
|
||||||
|
|
||||||
for se_item in se.get("items"):
|
|
||||||
for purchase_invoice in invoice_against_receipt:
|
|
||||||
pi = frappe.get_doc("Purchase Invoice", purchase_invoice)
|
|
||||||
ref_item = pi.get({"item_code": se_item.item_code})
|
|
||||||
|
|
||||||
if not ref_item:
|
|
||||||
continue
|
|
||||||
|
|
||||||
ref_item = ref_item[0]
|
|
||||||
|
|
||||||
account = ref_item.expense_account
|
|
||||||
|
|
||||||
if account not in children:
|
|
||||||
children.append(account)
|
|
||||||
|
|
||||||
if not parent:
|
|
||||||
parent = {
|
|
||||||
"account": pi.credit_to,
|
|
||||||
"party_type": "Supplier",
|
|
||||||
"party": pi.supplier
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
|
|
||||||
result = [parent] + [{"account": account} for account in children]
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|||||||
@@ -303,262 +303,262 @@ class TestStockEntry(unittest.TestCase):
|
|||||||
self.assertEquals(expected_gl_entries[i][1], gle[1])
|
self.assertEquals(expected_gl_entries[i][1], gle[1])
|
||||||
self.assertEquals(expected_gl_entries[i][2], gle[2])
|
self.assertEquals(expected_gl_entries[i][2], gle[2])
|
||||||
|
|
||||||
def _test_sales_invoice_return(self, item_code, delivered_qty, returned_qty):
|
# def _test_sales_invoice_return(self, item_code, delivered_qty, returned_qty):
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
# from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
|
#
|
||||||
si = create_sales_invoice(item_code=item_code, qty=delivered_qty)
|
# si = create_sales_invoice(item_code=item_code, qty=delivered_qty)
|
||||||
|
#
|
||||||
se = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=returned_qty,
|
# se = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=returned_qty,
|
||||||
purpose="Sales Return", sales_invoice_no=si.name, do_not_save=True)
|
# purpose="Sales Return", sales_invoice_no=si.name, do_not_save=True)
|
||||||
self.assertRaises(NotUpdateStockError, se.insert)
|
# self.assertRaises(NotUpdateStockError, se.insert)
|
||||||
|
#
|
||||||
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=200, incoming_rate=100)
|
# make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=200, incoming_rate=100)
|
||||||
|
#
|
||||||
# check currency available qty in bin
|
# # check currency available qty in bin
|
||||||
actual_qty_0 = get_qty_after_transaction()
|
# actual_qty_0 = get_qty_after_transaction()
|
||||||
|
#
|
||||||
# insert a pos invoice with update stock
|
# # insert a pos invoice with update stock
|
||||||
si = create_sales_invoice(update_stock=1, item_code=item_code, qty=5)
|
# si = create_sales_invoice(update_stock=1, item_code=item_code, qty=5)
|
||||||
|
#
|
||||||
# check available bin qty after invoice submission
|
# # check available bin qty after invoice submission
|
||||||
actual_qty_1 = get_qty_after_transaction()
|
# actual_qty_1 = get_qty_after_transaction()
|
||||||
|
#
|
||||||
self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1)
|
# self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1)
|
||||||
|
#
|
||||||
# check if item is validated
|
# # check if item is validated
|
||||||
se = make_stock_entry(item_code="_Test Item Home Desktop 200", target="_Test Warehouse - _TC",
|
# se = make_stock_entry(item_code="_Test Item Home Desktop 200", target="_Test Warehouse - _TC",
|
||||||
qty=returned_qty, purpose="Sales Return", sales_invoice_no=si.name, do_not_save=True)
|
# qty=returned_qty, purpose="Sales Return", sales_invoice_no=si.name, do_not_save=True)
|
||||||
|
#
|
||||||
self.assertRaises(frappe.DoesNotExistError, se.insert)
|
# self.assertRaises(frappe.DoesNotExistError, se.insert)
|
||||||
|
#
|
||||||
# try again
|
# # try again
|
||||||
se = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
|
# se = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
|
||||||
qty=returned_qty, purpose="Sales Return", sales_invoice_no=si.name)
|
# qty=returned_qty, purpose="Sales Return", sales_invoice_no=si.name)
|
||||||
|
#
|
||||||
# check if available qty is increased
|
# # check if available qty is increased
|
||||||
actual_qty_2 = get_qty_after_transaction()
|
# actual_qty_2 = get_qty_after_transaction()
|
||||||
|
#
|
||||||
self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2)
|
# self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2)
|
||||||
|
#
|
||||||
return se
|
# return se
|
||||||
|
#
|
||||||
def test_sales_invoice_return_of_non_packing_item(self):
|
# def test_sales_invoice_return_of_non_packing_item(self):
|
||||||
self._test_sales_invoice_return("_Test Item", 5, 2)
|
# self._test_sales_invoice_return("_Test Item", 5, 2)
|
||||||
|
#
|
||||||
def test_sales_invoice_return_of_packing_item(self):
|
# def test_sales_invoice_return_of_packing_item(self):
|
||||||
self._test_sales_invoice_return("_Test Product Bundle Item", 25, 20)
|
# self._test_sales_invoice_return("_Test Product Bundle Item", 25, 20)
|
||||||
|
#
|
||||||
def _test_delivery_note_return(self, item_code, delivered_qty, returned_qty):
|
# def _test_delivery_note_return(self, item_code, delivered_qty, returned_qty):
|
||||||
from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
|
# from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
|
||||||
|
#
|
||||||
from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
|
# from erpnext.stock.doctype.delivery_note.delivery_note import make_sales_invoice
|
||||||
|
#
|
||||||
make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, incoming_rate=100)
|
# make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC", qty=50, incoming_rate=100)
|
||||||
|
#
|
||||||
actual_qty_0 = get_qty_after_transaction()
|
# actual_qty_0 = get_qty_after_transaction()
|
||||||
# make a delivery note based on this invoice
|
# # make a delivery note based on this invoice
|
||||||
dn = create_delivery_note(item_code="_Test Item",
|
# dn = create_delivery_note(item_code="_Test Item",
|
||||||
warehouse="_Test Warehouse - _TC", qty=delivered_qty)
|
# warehouse="_Test Warehouse - _TC", qty=delivered_qty)
|
||||||
|
#
|
||||||
actual_qty_1 = get_qty_after_transaction()
|
# actual_qty_1 = get_qty_after_transaction()
|
||||||
|
#
|
||||||
self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1)
|
# self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1)
|
||||||
|
#
|
||||||
si = make_sales_invoice(dn.name)
|
# si = make_sales_invoice(dn.name)
|
||||||
si.insert()
|
# si.insert()
|
||||||
si.submit()
|
# si.submit()
|
||||||
|
#
|
||||||
# insert and submit stock entry for sales return
|
# # insert and submit stock entry for sales return
|
||||||
se = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
|
# se = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
|
||||||
qty=returned_qty, purpose="Sales Return", delivery_note_no=dn.name)
|
# qty=returned_qty, purpose="Sales Return", delivery_note_no=dn.name)
|
||||||
|
#
|
||||||
actual_qty_2 = get_qty_after_transaction()
|
# actual_qty_2 = get_qty_after_transaction()
|
||||||
self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2)
|
# self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2)
|
||||||
|
#
|
||||||
return se
|
# return se
|
||||||
|
#
|
||||||
def test_delivery_note_return_of_non_packing_item(self):
|
# def test_delivery_note_return_of_non_packing_item(self):
|
||||||
self._test_delivery_note_return("_Test Item", 5, 2)
|
# self._test_delivery_note_return("_Test Item", 5, 2)
|
||||||
|
#
|
||||||
def test_delivery_note_return_of_packing_item(self):
|
# def test_delivery_note_return_of_packing_item(self):
|
||||||
self._test_delivery_note_return("_Test Product Bundle Item", 25, 20)
|
# self._test_delivery_note_return("_Test Product Bundle Item", 25, 20)
|
||||||
|
#
|
||||||
def _test_sales_return_jv(self, se):
|
# def _test_sales_return_jv(self, se):
|
||||||
jv = make_return_jv(se.name)
|
# jv = make_return_jv(se.name)
|
||||||
|
#
|
||||||
self.assertEqual(len(jv.get("accounts")), 2)
|
# self.assertEqual(len(jv.get("accounts")), 2)
|
||||||
self.assertEqual(jv.get("voucher_type"), "Credit Note")
|
# self.assertEqual(jv.get("voucher_type"), "Credit Note")
|
||||||
self.assertEqual(jv.get("posting_date"), getdate(se.posting_date))
|
# self.assertEqual(jv.get("posting_date"), getdate(se.posting_date))
|
||||||
self.assertEqual(jv.get("accounts")[0].get("account"), "Debtors - _TC")
|
# self.assertEqual(jv.get("accounts")[0].get("account"), "Debtors - _TC")
|
||||||
self.assertEqual(jv.get("accounts")[0].get("party_type"), "Customer")
|
# self.assertEqual(jv.get("accounts")[0].get("party_type"), "Customer")
|
||||||
self.assertEqual(jv.get("accounts")[0].get("party"), "_Test Customer")
|
# self.assertEqual(jv.get("accounts")[0].get("party"), "_Test Customer")
|
||||||
self.assertEqual(jv.get("accounts")[1].get("account"), "Sales - _TC")
|
# self.assertEqual(jv.get("accounts")[1].get("account"), "Sales - _TC")
|
||||||
|
#
|
||||||
def test_make_return_jv_for_sales_invoice_non_packing_item(self):
|
# def test_make_return_jv_for_sales_invoice_non_packing_item(self):
|
||||||
se = self._test_sales_invoice_return("_Test Item", 5, 2)
|
# se = self._test_sales_invoice_return("_Test Item", 5, 2)
|
||||||
self._test_sales_return_jv(se)
|
# self._test_sales_return_jv(se)
|
||||||
|
#
|
||||||
def test_make_return_jv_for_sales_invoice_packing_item(self):
|
# def test_make_return_jv_for_sales_invoice_packing_item(self):
|
||||||
se = self._test_sales_invoice_return("_Test Product Bundle Item", 25, 20)
|
# se = self._test_sales_invoice_return("_Test Product Bundle Item", 25, 20)
|
||||||
self._test_sales_return_jv(se)
|
# self._test_sales_return_jv(se)
|
||||||
|
#
|
||||||
def test_make_return_jv_for_delivery_note_non_packing_item(self):
|
# def test_make_return_jv_for_delivery_note_non_packing_item(self):
|
||||||
se = self._test_delivery_note_return("_Test Item", 5, 2)
|
# se = self._test_delivery_note_return("_Test Item", 5, 2)
|
||||||
self._test_sales_return_jv(se)
|
# self._test_sales_return_jv(se)
|
||||||
|
#
|
||||||
se = self._test_delivery_note_return_against_sales_order("_Test Item", 5, 2)
|
# se = self._test_delivery_note_return_against_sales_order("_Test Item", 5, 2)
|
||||||
self._test_sales_return_jv(se)
|
# self._test_sales_return_jv(se)
|
||||||
|
#
|
||||||
def test_make_return_jv_for_delivery_note_packing_item(self):
|
# def test_make_return_jv_for_delivery_note_packing_item(self):
|
||||||
se = self._test_delivery_note_return("_Test Product Bundle Item", 25, 20)
|
# se = self._test_delivery_note_return("_Test Product Bundle Item", 25, 20)
|
||||||
self._test_sales_return_jv(se)
|
# self._test_sales_return_jv(se)
|
||||||
|
#
|
||||||
se = self._test_delivery_note_return_against_sales_order("_Test Product Bundle Item", 25, 20)
|
# se = self._test_delivery_note_return_against_sales_order("_Test Product Bundle Item", 25, 20)
|
||||||
self._test_sales_return_jv(se)
|
# self._test_sales_return_jv(se)
|
||||||
|
#
|
||||||
def _test_delivery_note_return_against_sales_order(self, item_code, delivered_qty, returned_qty):
|
# def _test_delivery_note_return_against_sales_order(self, item_code, delivered_qty, returned_qty):
|
||||||
from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
|
# from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
|
||||||
|
#
|
||||||
actual_qty_0 = get_qty_after_transaction()
|
# actual_qty_0 = get_qty_after_transaction()
|
||||||
|
#
|
||||||
so = make_sales_order(qty=50)
|
# so = make_sales_order(qty=50)
|
||||||
|
#
|
||||||
dn = create_dn_against_so(so.name, delivered_qty)
|
# dn = create_dn_against_so(so.name, delivered_qty)
|
||||||
|
#
|
||||||
actual_qty_1 = get_qty_after_transaction()
|
# actual_qty_1 = get_qty_after_transaction()
|
||||||
self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1)
|
# self.assertEquals(actual_qty_0 - delivered_qty, actual_qty_1)
|
||||||
|
#
|
||||||
si = make_sales_invoice(so.name)
|
# si = make_sales_invoice(so.name)
|
||||||
si.insert()
|
# si.insert()
|
||||||
si.submit()
|
# si.submit()
|
||||||
|
#
|
||||||
# insert and submit stock entry for sales return
|
# # insert and submit stock entry for sales return
|
||||||
se = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
|
# se = make_stock_entry(item_code="_Test Item", target="_Test Warehouse - _TC",
|
||||||
qty=returned_qty, purpose="Sales Return", delivery_note_no=dn.name)
|
# qty=returned_qty, purpose="Sales Return", delivery_note_no=dn.name)
|
||||||
|
#
|
||||||
actual_qty_2 = get_qty_after_transaction()
|
# actual_qty_2 = get_qty_after_transaction()
|
||||||
self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2)
|
# self.assertEquals(actual_qty_1 + returned_qty, actual_qty_2)
|
||||||
|
#
|
||||||
return se
|
# return se
|
||||||
|
#
|
||||||
def test_purchase_receipt_return(self):
|
# def test_purchase_receipt_return(self):
|
||||||
actual_qty_0 = get_qty_after_transaction()
|
# actual_qty_0 = get_qty_after_transaction()
|
||||||
|
#
|
||||||
# submit purchase receipt
|
# # submit purchase receipt
|
||||||
pr = make_purchase_receipt(item_code="_Test Item", warehouse="_Test Warehouse - _TC", qty=5)
|
# pr = make_purchase_receipt(item_code="_Test Item", warehouse="_Test Warehouse - _TC", qty=5)
|
||||||
|
#
|
||||||
actual_qty_1 = get_qty_after_transaction()
|
# actual_qty_1 = get_qty_after_transaction()
|
||||||
|
#
|
||||||
self.assertEquals(actual_qty_0 + 5, actual_qty_1)
|
# self.assertEquals(actual_qty_0 + 5, actual_qty_1)
|
||||||
|
#
|
||||||
pi_doc = make_purchase_invoice(pr.name)
|
# pi_doc = make_purchase_invoice(pr.name)
|
||||||
|
#
|
||||||
pi = frappe.get_doc(pi_doc)
|
# pi = frappe.get_doc(pi_doc)
|
||||||
pi.posting_date = pr.posting_date
|
# pi.posting_date = pr.posting_date
|
||||||
pi.credit_to = "_Test Payable - _TC"
|
# pi.credit_to = "_Test Payable - _TC"
|
||||||
for d in pi.get("items"):
|
# for d in pi.get("items"):
|
||||||
d.expense_account = "_Test Account Cost for Goods Sold - _TC"
|
# d.expense_account = "_Test Account Cost for Goods Sold - _TC"
|
||||||
d.cost_center = "_Test Cost Center - _TC"
|
# d.cost_center = "_Test Cost Center - _TC"
|
||||||
|
#
|
||||||
for d in pi.get("taxes"):
|
# for d in pi.get("taxes"):
|
||||||
d.cost_center = "_Test Cost Center - _TC"
|
# d.cost_center = "_Test Cost Center - _TC"
|
||||||
|
#
|
||||||
pi.insert()
|
# pi.insert()
|
||||||
pi.submit()
|
# pi.submit()
|
||||||
|
#
|
||||||
# submit purchase return
|
# # submit purchase return
|
||||||
se = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC",
|
# se = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC",
|
||||||
qty=5, purpose="Purchase Return", purchase_receipt_no=pr.name)
|
# qty=5, purpose="Purchase Return", purchase_receipt_no=pr.name)
|
||||||
|
#
|
||||||
actual_qty_2 = get_qty_after_transaction()
|
# actual_qty_2 = get_qty_after_transaction()
|
||||||
|
#
|
||||||
self.assertEquals(actual_qty_1 - 5, actual_qty_2)
|
# self.assertEquals(actual_qty_1 - 5, actual_qty_2)
|
||||||
|
#
|
||||||
return se, pr.name
|
# return se, pr.name
|
||||||
|
#
|
||||||
def test_over_stock_return(self):
|
# def test_over_stock_return(self):
|
||||||
from erpnext.stock.doctype.stock_entry.stock_entry import StockOverReturnError
|
# from erpnext.stock.doctype.stock_entry.stock_entry import StockOverReturnError
|
||||||
|
#
|
||||||
# out of 10, 5 gets returned
|
# # out of 10, 5 gets returned
|
||||||
prev_se, pr_docname = self.test_purchase_receipt_return()
|
# prev_se, pr_docname = self.test_purchase_receipt_return()
|
||||||
|
#
|
||||||
se = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC",
|
# se = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC",
|
||||||
qty=6, purpose="Purchase Return", purchase_receipt_no=pr_docname, do_not_save=True)
|
# qty=6, purpose="Purchase Return", purchase_receipt_no=pr_docname, do_not_save=True)
|
||||||
|
#
|
||||||
self.assertRaises(StockOverReturnError, se.insert)
|
# self.assertRaises(StockOverReturnError, se.insert)
|
||||||
|
#
|
||||||
def _test_purchase_return_jv(self, se):
|
# def _test_purchase_return_jv(self, se):
|
||||||
jv = make_return_jv(se.name)
|
# jv = make_return_jv(se.name)
|
||||||
|
#
|
||||||
self.assertEqual(len(jv.get("accounts")), 2)
|
# self.assertEqual(len(jv.get("accounts")), 2)
|
||||||
self.assertEqual(jv.get("voucher_type"), "Debit Note")
|
# self.assertEqual(jv.get("voucher_type"), "Debit Note")
|
||||||
self.assertEqual(jv.get("posting_date"), getdate(se.posting_date))
|
# self.assertEqual(jv.get("posting_date"), getdate(se.posting_date))
|
||||||
self.assertEqual(jv.get("accounts")[0].get("account"), "_Test Payable - _TC")
|
# self.assertEqual(jv.get("accounts")[0].get("account"), "_Test Payable - _TC")
|
||||||
self.assertEqual(jv.get("accounts")[0].get("party"), "_Test Supplier")
|
# self.assertEqual(jv.get("accounts")[0].get("party"), "_Test Supplier")
|
||||||
self.assertEqual(jv.get("accounts")[1].get("account"), "_Test Account Cost for Goods Sold - _TC")
|
# self.assertEqual(jv.get("accounts")[1].get("account"), "_Test Account Cost for Goods Sold - _TC")
|
||||||
|
#
|
||||||
def test_make_return_jv_for_purchase_receipt(self):
|
# def test_make_return_jv_for_purchase_receipt(self):
|
||||||
se, pr_name = self.test_purchase_receipt_return()
|
# se, pr_name = self.test_purchase_receipt_return()
|
||||||
self._test_purchase_return_jv(se)
|
# self._test_purchase_return_jv(se)
|
||||||
|
#
|
||||||
se, pr_name = self._test_purchase_return_return_against_purchase_order()
|
# se, pr_name = self._test_purchase_return_return_against_purchase_order()
|
||||||
self._test_purchase_return_jv(se)
|
# self._test_purchase_return_jv(se)
|
||||||
|
#
|
||||||
def _test_purchase_return_return_against_purchase_order(self):
|
# def _test_purchase_return_return_against_purchase_order(self):
|
||||||
|
#
|
||||||
actual_qty_0 = get_qty_after_transaction()
|
# actual_qty_0 = get_qty_after_transaction()
|
||||||
|
#
|
||||||
from erpnext.buying.doctype.purchase_order.test_purchase_order \
|
# from erpnext.buying.doctype.purchase_order.test_purchase_order \
|
||||||
import test_records as purchase_order_test_records
|
# import test_records as purchase_order_test_records
|
||||||
|
#
|
||||||
from erpnext.buying.doctype.purchase_order.purchase_order import \
|
# from erpnext.buying.doctype.purchase_order.purchase_order import \
|
||||||
make_purchase_receipt, make_purchase_invoice
|
# make_purchase_receipt, make_purchase_invoice
|
||||||
|
#
|
||||||
# submit purchase receipt
|
# # submit purchase receipt
|
||||||
po = frappe.copy_doc(purchase_order_test_records[0])
|
# po = frappe.copy_doc(purchase_order_test_records[0])
|
||||||
po.transaction_date = nowdate()
|
# po.transaction_date = nowdate()
|
||||||
po.is_subcontracted = None
|
# po.is_subcontracted = None
|
||||||
po.get("items")[0].item_code = "_Test Item"
|
# po.get("items")[0].item_code = "_Test Item"
|
||||||
po.get("items")[0].rate = 50
|
# po.get("items")[0].rate = 50
|
||||||
po.insert()
|
# po.insert()
|
||||||
po.submit()
|
# po.submit()
|
||||||
|
#
|
||||||
pr_doc = make_purchase_receipt(po.name)
|
# pr_doc = make_purchase_receipt(po.name)
|
||||||
|
#
|
||||||
pr = frappe.get_doc(pr_doc)
|
# pr = frappe.get_doc(pr_doc)
|
||||||
pr.posting_date = po.transaction_date
|
# pr.posting_date = po.transaction_date
|
||||||
pr.insert()
|
# pr.insert()
|
||||||
pr.submit()
|
# pr.submit()
|
||||||
|
#
|
||||||
actual_qty_1 = get_qty_after_transaction()
|
# actual_qty_1 = get_qty_after_transaction()
|
||||||
|
#
|
||||||
self.assertEquals(actual_qty_0 + 10, actual_qty_1)
|
# self.assertEquals(actual_qty_0 + 10, actual_qty_1)
|
||||||
|
#
|
||||||
pi_doc = make_purchase_invoice(po.name)
|
# pi_doc = make_purchase_invoice(po.name)
|
||||||
|
#
|
||||||
pi = frappe.get_doc(pi_doc)
|
# pi = frappe.get_doc(pi_doc)
|
||||||
pi.posting_date = pr.posting_date
|
# pi.posting_date = pr.posting_date
|
||||||
pi.credit_to = "_Test Payable - _TC"
|
# pi.credit_to = "_Test Payable - _TC"
|
||||||
for d in pi.get("items"):
|
# for d in pi.get("items"):
|
||||||
d.expense_account = "_Test Account Cost for Goods Sold - _TC"
|
# d.expense_account = "_Test Account Cost for Goods Sold - _TC"
|
||||||
d.cost_center = "_Test Cost Center - _TC"
|
# d.cost_center = "_Test Cost Center - _TC"
|
||||||
for d in pi.get("taxes"):
|
# for d in pi.get("taxes"):
|
||||||
d.cost_center = "_Test Cost Center - _TC"
|
# d.cost_center = "_Test Cost Center - _TC"
|
||||||
|
#
|
||||||
pi.run_method("calculate_taxes_and_totals")
|
# pi.run_method("calculate_taxes_and_totals")
|
||||||
pi.bill_no = "NA"
|
# pi.bill_no = "NA"
|
||||||
pi.insert()
|
# pi.insert()
|
||||||
pi.submit()
|
# pi.submit()
|
||||||
|
#
|
||||||
# submit purchase return
|
# # submit purchase return
|
||||||
se = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC",
|
# se = make_stock_entry(item_code="_Test Item", source="_Test Warehouse - _TC",
|
||||||
qty=5, purpose="Purchase Return", purchase_receipt_no=pr.name)
|
# qty=5, purpose="Purchase Return", purchase_receipt_no=pr.name)
|
||||||
|
#
|
||||||
actual_qty_2 = get_qty_after_transaction()
|
# actual_qty_2 = get_qty_after_transaction()
|
||||||
|
#
|
||||||
self.assertEquals(actual_qty_1 - 5, actual_qty_2)
|
# self.assertEquals(actual_qty_1 - 5, actual_qty_2)
|
||||||
|
#
|
||||||
return se, pr.name
|
# return se, pr.name
|
||||||
|
|
||||||
def test_serial_no_not_reqd(self):
|
def test_serial_no_not_reqd(self):
|
||||||
se = frappe.copy_doc(test_records[0])
|
se = frappe.copy_doc(test_records[0])
|
||||||
|
|||||||
Reference in New Issue
Block a user