[taxes and charges] refactor
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||||
// License: GNU General Public License v3. See license.txt
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
cur_frm.cscript.tax_table = "Purchase Taxes and Charges";
|
||||||
|
|
||||||
{% include "public/js/controllers/accounts.js" %}
|
{% include "public/js/controllers/accounts.js" %}
|
||||||
|
|
||||||
frappe.ui.form.on("Purchase Taxes and Charges", "add_deduct_tax", function(doc, cdt, cdn) {
|
frappe.ui.form.on("Purchase Taxes and Charges", "add_deduct_tax", function(doc, cdt, cdn) {
|
||||||
|
|||||||
@@ -199,8 +199,8 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
|||||||
this.hide_fields(this.frm.doc);
|
this.hide_fields(this.frm.doc);
|
||||||
},
|
},
|
||||||
|
|
||||||
items_on_form_rendered: function(doc, grid_row) {
|
items_on_form_rendered: function() {
|
||||||
erpnext.setup_serial_no(grid_row)
|
erpnext.setup_serial_no();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
"oldfieldname": "rate",
|
"oldfieldname": "rate",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"reqd": 1
|
"reqd": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "col_break_1",
|
"fieldname": "col_break_1",
|
||||||
@@ -186,7 +186,7 @@
|
|||||||
"hide_heading": 1,
|
"hide_heading": 1,
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2015-02-23 12:36:02.213508",
|
"modified": "2015-02-25 02:50:44.152307",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Taxes and Charges",
|
"name": "Sales Taxes and Charges",
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||||
// License: GNU General Public License v3. See license.txt
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
cur_frm.cscript.tax_table = "Sales Taxes and Charges";
|
||||||
|
|
||||||
{% include "public/js/controllers/accounts.js" %}
|
{% include "public/js/controllers/accounts.js" %}
|
||||||
|
|
||||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
frappe.ui.form.on("Sales Taxes and Charges Master", "onload", function(frm) {
|
||||||
if(doc.doctype === "Sales Taxes and Charges Master")
|
erpnext.add_applicable_territory();
|
||||||
erpnext.add_applicable_territory();
|
});
|
||||||
}
|
|
||||||
|
|||||||
@@ -20,3 +20,4 @@ class SalesTaxesandChargesMaster(Document):
|
|||||||
validate_taxes_and_charges(tax)
|
validate_taxes_and_charges(tax)
|
||||||
validate_inclusive_tax(tax, self)
|
validate_inclusive_tax(tax, self)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -370,6 +370,15 @@ def validate_taxes_and_charges(tax):
|
|||||||
elif tax.row_id and cint(tax.row_id) >= cint(tax.idx):
|
elif tax.row_id and cint(tax.row_id) >= cint(tax.idx):
|
||||||
frappe.throw(_("Cannot refer row number greater than or equal to current row number for this Charge type"))
|
frappe.throw(_("Cannot refer row number greater than or equal to current row number for this Charge type"))
|
||||||
|
|
||||||
|
if tax.charge_type == "Actual":
|
||||||
|
if not tax.tax_amount:
|
||||||
|
frappe.throw(_("Amount is mandatory for charge type 'Actual'"))
|
||||||
|
tax.rate = None
|
||||||
|
else:
|
||||||
|
if not tax.rate:
|
||||||
|
frappe.throw(_("Rate is mandatory for charge type '{0}'").format(tax.charge_type))
|
||||||
|
tax.tax_amount = None
|
||||||
|
|
||||||
def validate_inclusive_tax(tax, doc):
|
def validate_inclusive_tax(tax, doc):
|
||||||
def _on_previous_row_error(row_range):
|
def _on_previous_row_error(row_range):
|
||||||
throw(_("To include tax in row {0} in Item rate, taxes in rows {1} must also be included").format(tax.idx,
|
throw(_("To include tax in row {0} in Item rate, taxes in rows {1} must also be included").format(tax.idx,
|
||||||
|
|||||||
@@ -126,3 +126,4 @@ erpnext.patches.v5_0.item_patches
|
|||||||
erpnext.patches.v5_0.update_journal_entry_title
|
erpnext.patches.v5_0.update_journal_entry_title
|
||||||
erpnext.patches.v5_0.taxes_and_totals_in_party_currency
|
erpnext.patches.v5_0.taxes_and_totals_in_party_currency
|
||||||
erpnext.patches.v5_0.replace_renamed_fields_in_custom_scripts_and_print_formats
|
erpnext.patches.v5_0.replace_renamed_fields_in_custom_scripts_and_print_formats
|
||||||
|
execute:frappe.db.sql("update `tabStock Entry` set from_bom = if(ifnull(bom_no, '')='', 0, 1)")
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
// License: GNU General Public License v3. See license.txt
|
// License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
// get tax rate
|
// get tax rate
|
||||||
|
frappe.provide("erpnext.taxes");
|
||||||
|
frappe.provide("erpnext.taxes.flags");
|
||||||
|
|
||||||
|
|
||||||
cur_frm.cscript.account_head = function(doc, cdt, cdn) {
|
cur_frm.cscript.account_head = function(doc, cdt, cdn) {
|
||||||
var d = locals[cdt][cdn];
|
var d = locals[cdt][cdn];
|
||||||
if(!d.charge_type && d.account_head){
|
if(!d.charge_type && d.account_head){
|
||||||
@@ -82,34 +86,60 @@ cur_frm.cscript.validate_inclusive_tax = function(tax) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
frappe.ui.form.on(cur_frm.cscript.tax_table, "row_id", function(frm, cdt, cdn) {
|
if(!erpnext.taxes.flags[cur_frm.cscript.tax_table]) {
|
||||||
cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
|
erpnext.taxes.flags[cur_frm.cscript.tax_table] = true;
|
||||||
});
|
|
||||||
|
|
||||||
frappe.ui.form.on(cur_frm.cscript.tax_table, "rate", function(frm, cdt, cdn) {
|
frappe.ui.form.on(cur_frm.cscript.tax_table, "row_id", function(frm, cdt, cdn) {
|
||||||
cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
|
|
||||||
});
|
|
||||||
|
|
||||||
frappe.ui.form.on(cur_frm.cscript.tax_table, "tax_amount", function(frm, cdt, cdn) {
|
|
||||||
cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
|
|
||||||
});
|
|
||||||
|
|
||||||
frappe.ui.form.on(cur_frm.cscript.tax_table, "charge_type", function(frm, cdt, cdn) {
|
|
||||||
cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
|
|
||||||
});
|
|
||||||
|
|
||||||
frappe.ui.form.on(cur_frm.cscript.tax_table, "included_in_print_rate", function(frm, cdt, cdn) {
|
|
||||||
var tax = frappe.get_doc(cdt, cdn);
|
|
||||||
try {
|
|
||||||
cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
|
cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
|
||||||
cur_frm.cscript.validate_inclusive_tax(tax);
|
});
|
||||||
} catch(e) {
|
|
||||||
tax.included_in_print_rate = 0;
|
frappe.ui.form.on(cur_frm.cscript.tax_table, "rate", function(frm, cdt, cdn) {
|
||||||
refresh_field("included_in_print_rate", tax.name, tax.parentfield);
|
cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
|
||||||
throw e;
|
});
|
||||||
|
|
||||||
|
frappe.ui.form.on(cur_frm.cscript.tax_table, "tax_amount", function(frm, cdt, cdn) {
|
||||||
|
cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
|
||||||
|
});
|
||||||
|
|
||||||
|
frappe.ui.form.on(cur_frm.cscript.tax_table, "charge_type", function(frm, cdt, cdn) {
|
||||||
|
cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
|
||||||
|
erpnext.taxes.set_conditional_mandatory_rate_or_amount(frm);
|
||||||
|
});
|
||||||
|
|
||||||
|
frappe.ui.form.on(cur_frm.cscript.tax_table, "included_in_print_rate", function(frm, cdt, cdn) {
|
||||||
|
var tax = frappe.get_doc(cdt, cdn);
|
||||||
|
try {
|
||||||
|
cur_frm.cscript.validate_taxes_and_charges(cdt, cdn);
|
||||||
|
cur_frm.cscript.validate_inclusive_tax(tax);
|
||||||
|
} catch(e) {
|
||||||
|
tax.included_in_print_rate = 0;
|
||||||
|
refresh_field("included_in_print_rate", tax.name, tax.parentfield);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
erpnext.taxes.set_conditional_mandatory_rate_or_amount = function(frm) {
|
||||||
|
var grid_row = frm.open_grid_row();
|
||||||
|
if(grid_row.doc.charge_type==="Actual") {
|
||||||
|
grid_row.toggle_display("tax_amount", true);
|
||||||
|
grid_row.toggle_reqd("tax_amount", true);
|
||||||
|
grid_row.toggle_display("rate", false);
|
||||||
|
grid_row.toggle_reqd("rate", false);
|
||||||
|
} else {
|
||||||
|
grid_row.toggle_display("rate", true);
|
||||||
|
grid_row.toggle_reqd("rate", true);
|
||||||
|
grid_row.toggle_display("tax_amount", false);
|
||||||
|
grid_row.toggle_reqd("tax_amount", false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup conditional mandatory for tax and rates
|
||||||
|
frappe.ui.form.on(cur_frm.doctype, "taxes_on_form_rendered", function(frm) {
|
||||||
|
erpnext.taxes.set_conditional_mandatory_rate_or_amount(frm);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
cur_frm.set_query("account_head", "taxes", function(doc) {
|
cur_frm.set_query("account_head", "taxes", function(doc) {
|
||||||
if(cur_frm.cscript.tax_table == "Sales Taxes and Charges") {
|
if(cur_frm.cscript.tax_table == "Sales Taxes and Charges") {
|
||||||
var account_type = ["Tax", "Chargeable", "Expense Account"];
|
var account_type = ["Tax", "Chargeable", "Expense Account"];
|
||||||
|
|||||||
@@ -57,13 +57,15 @@ $.extend(erpnext, {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setup_serial_no: function(grid_row) {
|
setup_serial_no: function() {
|
||||||
|
var grid_row = cur_frm.open_grid_row();
|
||||||
|
|
||||||
if(!grid_row.fields_dict.serial_no ||
|
if(!grid_row.fields_dict.serial_no ||
|
||||||
grid_row.fields_dict.serial_no.get_status()!=="Write") return;
|
grid_row.fields_dict.serial_no.get_status()!=="Write") return;
|
||||||
|
|
||||||
var $btn = $('<button class="btn btn-sm btn-default">'+__("Add Serial No")+'</button>')
|
var $btn = $('<button class="btn btn-sm btn-default">'+__("Add Serial No")+'</button>')
|
||||||
.appendTo($("<div>")
|
.appendTo($("<div>")
|
||||||
.css({"margin-bottom": "10px", "margin-left": "15px"})
|
.css({"margin-bottom": "10px", "margin-top": "10px"})
|
||||||
.appendTo(grid_row.fields_dict.serial_no.$wrapper));
|
.appendTo(grid_row.fields_dict.serial_no.$wrapper));
|
||||||
|
|
||||||
$btn.on("click", function() {
|
$btn.on("click", function() {
|
||||||
@@ -99,7 +101,7 @@ $.extend(erpnext, {
|
|||||||
d.show();
|
d.show();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
get_letter_head: function(company) {
|
get_letter_head: function(company) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
type:"GET",
|
type:"GET",
|
||||||
@@ -112,7 +114,7 @@ $.extend(erpnext, {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
|
|||||||
},
|
},
|
||||||
|
|
||||||
items_on_form_rendered: function(doc, grid_row) {
|
items_on_form_rendered: function(doc, grid_row) {
|
||||||
erpnext.setup_serial_no(grid_row)
|
erpnext.setup_serial_no();
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ 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(grid_row)
|
erpnext.setup_serial_no();
|
||||||
},
|
},
|
||||||
|
|
||||||
customer: function() {
|
customer: function() {
|
||||||
|
|||||||
@@ -7,6 +7,14 @@
|
|||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"fields": [
|
"fields": [
|
||||||
|
{
|
||||||
|
"fieldname": "items_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "",
|
||||||
|
"oldfieldtype": "Section Break",
|
||||||
|
"permlevel": 0,
|
||||||
|
"read_only": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "col1",
|
"fieldname": "col1",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
@@ -73,15 +81,6 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 1
|
"search_index": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
|
|
||||||
"fieldname": "bom_no",
|
|
||||||
"fieldtype": "Link",
|
|
||||||
"label": "BOM No",
|
|
||||||
"options": "BOM",
|
|
||||||
"permlevel": 0,
|
|
||||||
"read_only": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"depends_on": "eval:doc.purpose==\"Sales Return\"",
|
"depends_on": "eval:doc.purpose==\"Sales Return\"",
|
||||||
@@ -132,6 +131,13 @@
|
|||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"search_index": 1
|
"search_index": 1
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "from_bom",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "From BOM",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "col2",
|
"fieldname": "col2",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
@@ -178,13 +184,91 @@
|
|||||||
"search_index": 0
|
"search_index": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "items_section",
|
"depends_on": "eval: doc.from_bom && (doc.purpose!==\"Sales Return\" && doc.purpose!==\"Purchase Return\")",
|
||||||
|
"fieldname": "sb1",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
"label": "",
|
"label": "",
|
||||||
"oldfieldtype": "Section Break",
|
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"read_only": 0
|
"read_only": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
|
||||||
|
"fieldname": "bom_no",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "BOM No",
|
||||||
|
"options": "BOM",
|
||||||
|
"permlevel": 0,
|
||||||
|
"read_only": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:inList([\"Manufacture\", \"Repack\"], doc.purpose)",
|
||||||
|
"fieldname": "additional_operating_cost",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"label": "Additional Operating Cost",
|
||||||
|
"no_copy": 1,
|
||||||
|
"options": "Company:company:default_currency",
|
||||||
|
"permlevel": 0,
|
||||||
|
"read_only": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "cb1",
|
||||||
|
"fieldtype": "Column Break",
|
||||||
|
"permlevel": 0,
|
||||||
|
"read_only": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
|
||||||
|
"description": "As per Stock UOM",
|
||||||
|
"fieldname": "fg_completed_qty",
|
||||||
|
"fieldtype": "Float",
|
||||||
|
"hidden": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"label": "Manufacturing Quantity",
|
||||||
|
"no_copy": 0,
|
||||||
|
"oldfieldname": "fg_completed_qty",
|
||||||
|
"oldfieldtype": "Currency",
|
||||||
|
"permlevel": 0,
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "1",
|
||||||
|
"depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
|
||||||
|
"description": "Including items for sub assemblies",
|
||||||
|
"fieldname": "use_multi_level_bom",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Use Multi-Level BOM",
|
||||||
|
"permlevel": 0,
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
|
||||||
|
"fieldname": "get_items",
|
||||||
|
"fieldtype": "Button",
|
||||||
|
"hidden": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"label": "Get Items",
|
||||||
|
"no_copy": 0,
|
||||||
|
"oldfieldtype": "Button",
|
||||||
|
"permlevel": 0,
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "section_break_12",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"fieldname": "from_warehouse",
|
"fieldname": "from_warehouse",
|
||||||
@@ -301,77 +385,6 @@
|
|||||||
"precision": "",
|
"precision": "",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"depends_on": "eval:(doc.purpose!==\"Sales Return\" && doc.purpose!==\"Purchase Return\")",
|
|
||||||
"fieldname": "sb1",
|
|
||||||
"fieldtype": "Section Break",
|
|
||||||
"label": "From Bill of Materials",
|
|
||||||
"permlevel": 0,
|
|
||||||
"read_only": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
|
|
||||||
"description": "As per Stock UOM",
|
|
||||||
"fieldname": "fg_completed_qty",
|
|
||||||
"fieldtype": "Float",
|
|
||||||
"hidden": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"label": "Manufacturing Quantity",
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldname": "fg_completed_qty",
|
|
||||||
"oldfieldtype": "Currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"depends_on": "eval:inList([\"Manufacture\", \"Repack\"], doc.purpose)",
|
|
||||||
"fieldname": "additional_operating_cost",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"label": "Additional Operating Cost",
|
|
||||||
"no_copy": 1,
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"permlevel": 0,
|
|
||||||
"read_only": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fieldname": "cb1",
|
|
||||||
"fieldtype": "Column Break",
|
|
||||||
"permlevel": 0,
|
|
||||||
"read_only": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"default": "1",
|
|
||||||
"depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
|
|
||||||
"description": "If checked, BOM for sub-assembly items will be considered for getting raw materials. Otherwise, all sub-assembly items will be treated as a raw material.",
|
|
||||||
"fieldname": "use_multi_level_bom",
|
|
||||||
"fieldtype": "Check",
|
|
||||||
"label": "Use Multi-Level BOM",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 1,
|
|
||||||
"read_only": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"allow_on_submit": 0,
|
|
||||||
"depends_on": "eval:!inList([\"Sales Return\", \"Purchase Return\"], doc.purpose)",
|
|
||||||
"fieldname": "get_items",
|
|
||||||
"fieldtype": "Button",
|
|
||||||
"hidden": 0,
|
|
||||||
"in_filter": 0,
|
|
||||||
"label": "Get Items",
|
|
||||||
"no_copy": 0,
|
|
||||||
"oldfieldtype": "Button",
|
|
||||||
"permlevel": 0,
|
|
||||||
"print_hide": 1,
|
|
||||||
"read_only": 0,
|
|
||||||
"report_hide": 0,
|
|
||||||
"reqd": 0,
|
|
||||||
"search_index": 0
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "fold",
|
"fieldname": "fold",
|
||||||
"fieldtype": "Fold",
|
"fieldtype": "Fold",
|
||||||
@@ -632,7 +645,7 @@
|
|||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2015-02-20 05:04:09.060180",
|
"modified": "2015-02-25 01:59:14.371042",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Stock Entry",
|
"name": "Stock Entry",
|
||||||
|
|||||||
@@ -282,14 +282,15 @@ class StockEntry(StockController):
|
|||||||
def add_operation_cost(self, raw_material_cost, force):
|
def add_operation_cost(self, raw_material_cost, force):
|
||||||
"""Adds operating cost if Production Order is set"""
|
"""Adds operating cost if Production Order is set"""
|
||||||
# set incoming rate for fg item
|
# set incoming rate for fg item
|
||||||
if self.production_order:
|
number_of_fg_items = len([t.t_warehouse for t in self.get("items") if t.t_warehouse])
|
||||||
number_of_fg_items = len([t.t_warehouse for t in self.get("items") if t.t_warehouse])
|
for d in self.get("items"):
|
||||||
for d in self.get("items"):
|
if (d.t_warehouse and number_of_fg_items == 1):
|
||||||
if d.bom_no or (d.t_warehouse and number_of_fg_items == 1):
|
operation_cost_per_unit = 0.0
|
||||||
|
if self.production_order:
|
||||||
operation_cost_per_unit = self.get_operation_cost_per_unit(d.bom_no, d.qty)
|
operation_cost_per_unit = self.get_operation_cost_per_unit(d.bom_no, d.qty)
|
||||||
d.incoming_rate = operation_cost_per_unit + (raw_material_cost / flt(d.transfer_qty))
|
d.incoming_rate = operation_cost_per_unit + (raw_material_cost / flt(d.transfer_qty))
|
||||||
d.amount = flt(flt(d.transfer_qty) * flt(d.incoming_rate), self.precision("transfer_qty", d))
|
d.amount = flt(flt(d.transfer_qty) * flt(d.incoming_rate), self.precision("transfer_qty", d))
|
||||||
break
|
break
|
||||||
|
|
||||||
def get_operation_cost_per_unit(self, bom_no, qty):
|
def get_operation_cost_per_unit(self, bom_no, qty):
|
||||||
"""Returns operating cost from Production Order for given `bom_no`"""
|
"""Returns operating cost from Production Order for given `bom_no`"""
|
||||||
@@ -510,10 +511,14 @@ class StockEntry(StockController):
|
|||||||
self.set('items', [])
|
self.set('items', [])
|
||||||
self.validate_production_order()
|
self.validate_production_order()
|
||||||
|
|
||||||
|
if not getattr(self, "pro_doc", None):
|
||||||
|
self.pro_doc = None
|
||||||
|
|
||||||
if self.production_order:
|
if self.production_order:
|
||||||
# common validations
|
# common validations
|
||||||
if not getattr(self, "pro_doc", None):
|
if not self.pro_doc:
|
||||||
self.pro_doc = frappe.get_doc('Production Order', self.production_order)
|
self.pro_doc = frappe.get_doc('Production Order', self.production_order)
|
||||||
|
|
||||||
if self.pro_doc:
|
if self.pro_doc:
|
||||||
self.bom_no = self.pro_doc.bom_no
|
self.bom_no = self.pro_doc.bom_no
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -10,12 +10,18 @@ from erpnext.stock.stock_ledger import update_entries_after
|
|||||||
from erpnext.controllers.stock_controller import StockController
|
from erpnext.controllers.stock_controller import StockController
|
||||||
from erpnext.stock.utils import get_stock_balance
|
from erpnext.stock.utils import get_stock_balance
|
||||||
|
|
||||||
|
class OpeningEntryAccountError(frappe.ValidationError): pass
|
||||||
|
|
||||||
class StockReconciliation(StockController):
|
class StockReconciliation(StockController):
|
||||||
def __init__(self, arg1, arg2=None):
|
def __init__(self, arg1, arg2=None):
|
||||||
super(StockReconciliation, self).__init__(arg1, arg2)
|
super(StockReconciliation, self).__init__(arg1, arg2)
|
||||||
self.head_row = ["Item Code", "Warehouse", "Quantity", "Valuation Rate"]
|
self.head_row = ["Item Code", "Warehouse", "Quantity", "Valuation Rate"]
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
|
if not self.expense_account:
|
||||||
|
self.expense_account = frappe.db.get_value("Company", self.company, "stock_adjustment_account")
|
||||||
|
if not self.cost_center:
|
||||||
|
self.cost_center = frappe.db.get_value("Company", self.company, "cost_center")
|
||||||
self.validate_posting_time()
|
self.validate_posting_time()
|
||||||
self.remove_items_with_no_change()
|
self.remove_items_with_no_change()
|
||||||
self.validate_data()
|
self.validate_data()
|
||||||
@@ -215,7 +221,12 @@ class StockReconciliation(StockController):
|
|||||||
msgprint(_("Please enter Expense Account"), raise_exception=1)
|
msgprint(_("Please enter Expense Account"), raise_exception=1)
|
||||||
elif not frappe.db.sql("""select name from `tabStock Ledger Entry` limit 1"""):
|
elif not frappe.db.sql("""select name from `tabStock Ledger Entry` limit 1"""):
|
||||||
if frappe.db.get_value("Account", self.expense_account, "report_type") == "Profit and Loss":
|
if frappe.db.get_value("Account", self.expense_account, "report_type") == "Profit and Loss":
|
||||||
frappe.throw(_("Difference Account must be a 'Liability' type account, since this Stock Reconciliation is an Opening Entry"))
|
frappe.throw(_("Difference Account must be a 'Liability' type account, since this Stock Reconciliation is an Opening Entry"), OpeningEntryAccountError)
|
||||||
|
|
||||||
|
def get_items_for(self, warehouse):
|
||||||
|
self.items = []
|
||||||
|
for item in get_items(warehouse, self.posting_date, self.posting_time):
|
||||||
|
self.append("items", item)
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_items(warehouse, posting_date, posting_time):
|
def get_items(warehouse, posting_date, posting_time):
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ class update_entries_after(object):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if sle.serial_no:
|
if sle.serial_no:
|
||||||
self.valuation_rate = self.get_serialized_values(sle)
|
self.get_serialized_values(sle)
|
||||||
self.qty_after_transaction += flt(sle.actual_qty)
|
self.qty_after_transaction += flt(sle.actual_qty)
|
||||||
self.stock_value = flt(self.qty_after_transaction) * flt(self.valuation_rate)
|
self.stock_value = flt(self.qty_after_transaction) * flt(self.valuation_rate)
|
||||||
else:
|
else:
|
||||||
@@ -208,12 +208,14 @@ class update_entries_after(object):
|
|||||||
if incoming_rate < 0:
|
if incoming_rate < 0:
|
||||||
# wrong incoming rate
|
# wrong incoming rate
|
||||||
incoming_rate = self.valuation_rate
|
incoming_rate = self.valuation_rate
|
||||||
elif incoming_rate == 0 or flt(sle.actual_qty) < 0:
|
|
||||||
# In case of delivery/stock issue, get average purchase rate
|
elif incoming_rate == 0:
|
||||||
# of serial nos of current entry
|
if flt(sle.actual_qty) < 0:
|
||||||
incoming_rate = flt(frappe.db.sql("""select avg(ifnull(purchase_rate, 0))
|
# In case of delivery/stock issue, get average purchase rate
|
||||||
from `tabSerial No` where name in (%s)""" % (", ".join(["%s"]*len(serial_no))),
|
# of serial nos of current entry
|
||||||
tuple(serial_no))[0][0])
|
incoming_rate = flt(frappe.db.sql("""select avg(ifnull(purchase_rate, 0))
|
||||||
|
from `tabSerial No` where name in (%s)""" % (", ".join(["%s"]*len(serial_no))),
|
||||||
|
tuple(serial_no))[0][0])
|
||||||
|
|
||||||
if incoming_rate and not self.valuation_rate:
|
if incoming_rate and not self.valuation_rate:
|
||||||
self.valuation_rate = incoming_rate
|
self.valuation_rate = incoming_rate
|
||||||
|
|||||||
Reference in New Issue
Block a user