mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-07 23:31:20 +00:00
Merge pull request #41942 from frappe/version-14-hotfix
chore: release v14
This commit is contained in:
@@ -82,7 +82,7 @@
|
||||
"icon": "fa fa-calendar",
|
||||
"idx": 1,
|
||||
"links": [],
|
||||
"modified": "2020-11-05 12:16:53.081573",
|
||||
"modified": "2024-05-27 17:29:55.560840",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Fiscal Year",
|
||||
@@ -126,6 +126,10 @@
|
||||
{
|
||||
"read": 1,
|
||||
"role": "Stock Manager"
|
||||
},
|
||||
{
|
||||
"read": 1,
|
||||
"role": "Auditor"
|
||||
}
|
||||
],
|
||||
"show_name_in_global_search": 1,
|
||||
|
||||
@@ -171,7 +171,7 @@ frappe.ui.form.on("Journal Entry", {
|
||||
!(frm.doc.accounts || []).length ||
|
||||
((frm.doc.accounts || []).length === 1 && !frm.doc.accounts[0].account)
|
||||
) {
|
||||
if (in_list(["Bank Entry", "Cash Entry"], frm.doc.voucher_type)) {
|
||||
if (["Bank Entry", "Cash Entry"].includes(frm.doc.voucher_type)) {
|
||||
return frappe.call({
|
||||
type: "GET",
|
||||
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_default_bank_cash_account",
|
||||
@@ -283,7 +283,7 @@ erpnext.accounts.JournalEntry = class JournalEntry extends frappe.ui.form.Contro
|
||||
filters: [[jvd.reference_type, "docstatus", "=", 1]],
|
||||
};
|
||||
|
||||
if (in_list(["Sales Invoice", "Purchase Invoice"], jvd.reference_type)) {
|
||||
if (["Sales Invoice", "Purchase Invoice"].includes(jvd.reference_type)) {
|
||||
out.filters.push([jvd.reference_type, "outstanding_amount", "!=", 0]);
|
||||
// Filter by cost center
|
||||
if (jvd.cost_center) {
|
||||
@@ -295,7 +295,7 @@ erpnext.accounts.JournalEntry = class JournalEntry extends frappe.ui.form.Contro
|
||||
out.filters.push([jvd.reference_type, party_account_field, "=", jvd.account]);
|
||||
}
|
||||
|
||||
if (in_list(["Sales Order", "Purchase Order"], jvd.reference_type)) {
|
||||
if (["Sales Order", "Purchase Order"].includes(jvd.reference_type)) {
|
||||
// party_type and party mandatory
|
||||
frappe.model.validate_missing(jvd, "party_type");
|
||||
frappe.model.validate_missing(jvd, "party");
|
||||
|
||||
@@ -21,7 +21,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.set_query("paid_from", function() {
|
||||
frm.events.validate_company(frm);
|
||||
|
||||
var account_types = in_list(["Pay", "Internal Transfer"], frm.doc.payment_type) ?
|
||||
var account_types = ["Pay", "Internal Transfer"].includes(frm.doc.payment_type) ?
|
||||
["Bank", "Cash"] : [frappe.boot.party_account_types[frm.doc.party_type]];
|
||||
return {
|
||||
filters: {
|
||||
@@ -75,7 +75,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.set_query("paid_to", function() {
|
||||
frm.events.validate_company(frm);
|
||||
|
||||
var account_types = in_list(["Receive", "Internal Transfer"], frm.doc.payment_type) ?
|
||||
var account_types = ["Receive", "Internal Transfer"].includes(frm.doc.payment_type) ?
|
||||
["Bank", "Cash"] : [frappe.boot.party_account_types[frm.doc.party_type]];
|
||||
return {
|
||||
filters: {
|
||||
@@ -121,7 +121,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
|
||||
frm.set_query('payment_term', 'references', function(frm, cdt, cdn) {
|
||||
const child = locals[cdt][cdn];
|
||||
if (in_list(['Purchase Invoice', 'Sales Invoice'], child.reference_doctype) && child.reference_name) {
|
||||
if (['Purchase Invoice', 'Sales Invoice'].includes(child.reference_doctype) && child.reference_name) {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.get_payment_terms_for_references",
|
||||
filters: {
|
||||
@@ -485,7 +485,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
if (frm.doc.paid_from_account_currency == company_currency) {
|
||||
frm.set_value("source_exchange_rate", 1);
|
||||
} else if (frm.doc.paid_from){
|
||||
if (in_list(["Internal Transfer", "Pay"], frm.doc.payment_type)) {
|
||||
if (["Internal Transfer", "Pay"].includes(frm.doc.payment_type)) {
|
||||
let company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
|
||||
frappe.call({
|
||||
method: "erpnext.setup.utils.get_exchange_rate",
|
||||
@@ -853,7 +853,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
}
|
||||
|
||||
var allocated_positive_outstanding = paid_amount + allocated_negative_outstanding;
|
||||
} else if (in_list(["Customer", "Supplier"], frm.doc.party_type)) {
|
||||
} else if (["Customer", "Supplier"].includes(frm.doc.party_type)) {
|
||||
total_negative_outstanding = flt(total_negative_outstanding, precision("outstanding_amount"))
|
||||
if(paid_amount > total_negative_outstanding) {
|
||||
if(total_negative_outstanding == 0) {
|
||||
@@ -988,7 +988,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
}
|
||||
|
||||
if(frm.doc.party_type=="Customer" &&
|
||||
!in_list(["Sales Order", "Sales Invoice", "Journal Entry", "Dunning"], row.reference_doctype)
|
||||
!["Sales Order", "Sales Invoice", "Journal Entry", "Dunning"].includes(row.reference_doctype)
|
||||
) {
|
||||
frappe.model.set_value(row.doctype, row.name, "reference_doctype", null);
|
||||
frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Sales Order, Sales Invoice, Journal Entry or Dunning", [row.idx]));
|
||||
@@ -996,7 +996,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
}
|
||||
|
||||
if(frm.doc.party_type=="Supplier" &&
|
||||
!in_list(["Purchase Order", "Purchase Invoice", "Journal Entry"], row.reference_doctype)
|
||||
!["Purchase Order", "Purchase Invoice", "Journal Entry"].includes(row.reference_doctype)
|
||||
) {
|
||||
frappe.model.set_value(row.doctype, row.name, "against_voucher_type", null);
|
||||
frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Purchase Order, Purchase Invoice or Journal Entry", [row.idx]));
|
||||
@@ -1080,7 +1080,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
|
||||
bank_account: function(frm) {
|
||||
const field = frm.doc.payment_type == "Pay" ? "paid_from":"paid_to";
|
||||
if (frm.doc.bank_account && in_list(['Pay', 'Receive'], frm.doc.payment_type)) {
|
||||
if (frm.doc.bank_account && ['Pay', 'Receive'].includes(frm.doc.payment_type)) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.bank_account.bank_account.get_bank_account_details",
|
||||
args: {
|
||||
|
||||
@@ -28,7 +28,7 @@ frappe.ui.form.on("Payment Request", "refresh", function (frm) {
|
||||
if (
|
||||
frm.doc.payment_request_type == "Inward" &&
|
||||
frm.doc.payment_channel !== "Phone" &&
|
||||
!in_list(["Initiated", "Paid"], frm.doc.status) &&
|
||||
!["Initiated", "Paid"].includes(frm.doc.status) &&
|
||||
!frm.doc.__islocal &&
|
||||
frm.doc.docstatus == 1
|
||||
) {
|
||||
|
||||
@@ -200,7 +200,7 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e
|
||||
if(cur_frm.meta._default_print_format) {
|
||||
cur_frm.meta.default_print_format = cur_frm.meta._default_print_format;
|
||||
cur_frm.meta._default_print_format = null;
|
||||
} else if(in_list([cur_frm.pos_print_format, cur_frm.return_print_format], cur_frm.meta.default_print_format)) {
|
||||
} else if([cur_frm.pos_print_format, cur_frm.return_print_format].includes(cur_frm.meta.default_print_format)) {
|
||||
cur_frm.meta.default_print_format = null;
|
||||
cur_frm.meta._default_print_format = null;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ frappe.ui.form.on("Asset", {
|
||||
frm.events.make_schedules_editable(frm);
|
||||
|
||||
if (frm.doc.docstatus == 1) {
|
||||
if (in_list(["Submitted", "Partially Depreciated", "Fully Depreciated"], frm.doc.status)) {
|
||||
if (["Submitted", "Partially Depreciated", "Fully Depreciated"].includes(frm.doc.status)) {
|
||||
frm.add_custom_button(
|
||||
__("Transfer Asset"),
|
||||
function () {
|
||||
@@ -280,7 +280,7 @@ frappe.ui.form.on("Asset", {
|
||||
if (v.journal_entry) {
|
||||
asset_values.push(asset_value);
|
||||
} else {
|
||||
if (in_list(["Scrapped", "Sold"], frm.doc.status)) {
|
||||
if (["Scrapped", "Sold"].includes(frm.doc.status)) {
|
||||
asset_values.push(null);
|
||||
} else {
|
||||
asset_values.push(asset_value);
|
||||
@@ -312,7 +312,7 @@ frappe.ui.form.on("Asset", {
|
||||
});
|
||||
}
|
||||
|
||||
if (in_list(["Scrapped", "Sold"], frm.doc.status)) {
|
||||
if (["Scrapped", "Sold"].includes(frm.doc.status)) {
|
||||
x_intervals.push(frappe.format(frm.doc.disposal_date, { fieldtype: "Date" }));
|
||||
asset_values.push(0);
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ frappe.provide("erpnext.accounts.dimensions");
|
||||
{% include 'erpnext/public/js/controllers/buying.js' %};
|
||||
|
||||
frappe.ui.form.on("Purchase Order", {
|
||||
setup: function(frm) {
|
||||
|
||||
setup: function (frm) {
|
||||
frm.ignore_doctypes_on_cancel_all = ["Unreconcile Payment", "Unreconcile Payment Entries"];
|
||||
if (frm.doc.is_old_subcontracting_flow) {
|
||||
frm.set_query("reserve_warehouse", "supplied_items", function() {
|
||||
return {
|
||||
@@ -180,7 +180,7 @@ erpnext.buying.PurchaseOrderController = class PurchaseOrderController extends e
|
||||
this.frm.fields_dict.items_section.wrapper.removeClass("hide-border");
|
||||
}
|
||||
|
||||
if(!in_list(["Closed", "Delivered"], doc.status)) {
|
||||
if(!["Closed", "Delivered"].includes(doc.status)) {
|
||||
if(this.frm.doc.status !== 'Closed' && flt(this.frm.doc.per_received) < 100 && flt(this.frm.doc.per_billed) < 100) {
|
||||
// Don't add Update Items button if the PO is following the new subcontracting flow.
|
||||
if (!(this.frm.doc.is_subcontracted && !this.frm.doc.is_old_subcontracting_flow)) {
|
||||
@@ -211,7 +211,7 @@ erpnext.buying.PurchaseOrderController = class PurchaseOrderController extends e
|
||||
|
||||
this.frm.page.set_inner_btn_group_as_primary(__("Status"));
|
||||
}
|
||||
} else if(in_list(["Closed", "Delivered"], doc.status)) {
|
||||
} else if(["Closed", "Delivered"].includes(doc.status)) {
|
||||
if (this.frm.has_perm("submit")) {
|
||||
this.frm.add_custom_button(__('Re-open'), () => this.unclose_purchase_order(), __("Status"));
|
||||
}
|
||||
|
||||
@@ -345,7 +345,13 @@ class PurchaseOrder(BuyingController):
|
||||
update_linked_doc(self.doctype, self.name, self.inter_company_order_reference)
|
||||
|
||||
def on_cancel(self):
|
||||
self.ignore_linked_doctypes = ("GL Entry", "Payment Ledger Entry")
|
||||
self.ignore_linked_doctypes = (
|
||||
"GL Entry",
|
||||
"Payment Ledger Entry",
|
||||
"Unreconcile Payment",
|
||||
"Unreconcile Payment Entries",
|
||||
)
|
||||
|
||||
super().on_cancel()
|
||||
|
||||
if self.is_against_so():
|
||||
|
||||
@@ -8,6 +8,7 @@ from frappe.contacts.doctype.address.address import render_address
|
||||
from frappe.utils import cint, cstr, flt, getdate
|
||||
from frappe.utils.data import nowtime
|
||||
|
||||
import erpnext
|
||||
from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget
|
||||
from erpnext.accounts.party import get_party_details
|
||||
from erpnext.buying.utils import update_last_purchase_rate, validate_for_items
|
||||
@@ -305,6 +306,8 @@ class BuyingController(SubcontractingController):
|
||||
else:
|
||||
item.valuation_rate = 0.0
|
||||
|
||||
update_regional_item_valuation_rate(self)
|
||||
|
||||
def set_incoming_rate(self):
|
||||
if self.doctype not in ("Purchase Receipt", "Purchase Invoice", "Purchase Order"):
|
||||
return
|
||||
@@ -894,3 +897,8 @@ def validate_item_type(doc, fieldname, message):
|
||||
).format(items, message)
|
||||
|
||||
frappe.throw(error_message)
|
||||
|
||||
|
||||
@erpnext.allow_regional
|
||||
def update_regional_item_valuation_rate(doc):
|
||||
pass
|
||||
|
||||
@@ -51,7 +51,7 @@ class StockController(AccountsController):
|
||||
self.validate_internal_transfer()
|
||||
self.validate_putaway_capacity()
|
||||
|
||||
def make_gl_entries(self, gl_entries=None, from_repost=False):
|
||||
def make_gl_entries(self, gl_entries=None, from_repost=False, via_landed_cost_voucher=False):
|
||||
if self.docstatus == 2:
|
||||
make_reverse_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
|
||||
|
||||
@@ -72,7 +72,11 @@ class StockController(AccountsController):
|
||||
|
||||
if self.docstatus == 1:
|
||||
if not gl_entries:
|
||||
gl_entries = self.get_gl_entries(warehouse_account)
|
||||
gl_entries = (
|
||||
self.get_gl_entries(warehouse_account, via_landed_cost_voucher)
|
||||
if self.doctype == "Purchase Receipt"
|
||||
else self.get_gl_entries(warehouse_account)
|
||||
)
|
||||
make_gl_entries(gl_entries, from_repost=from_repost)
|
||||
|
||||
def validate_serialized_batch(self):
|
||||
|
||||
@@ -400,7 +400,7 @@ frappe.ui.form.on("BOM", {
|
||||
},
|
||||
|
||||
rm_cost_as_per(frm) {
|
||||
if (in_list(["Valuation Rate", "Last Purchase Rate"], frm.doc.rm_cost_as_per)) {
|
||||
if (["Valuation Rate", "Last Purchase Rate"].includes(frm.doc.rm_cost_as_per)) {
|
||||
frm.set_value("plc_conversion_rate", 1.0);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -129,7 +129,7 @@ frappe.ui.form.on("Production Plan", {
|
||||
if (
|
||||
frm.doc.mr_items &&
|
||||
frm.doc.mr_items.length &&
|
||||
!in_list(["Material Requested", "Closed"], frm.doc.status)
|
||||
!["Material Requested", "Closed"].includes(frm.doc.status)
|
||||
) {
|
||||
frm.add_custom_button(
|
||||
__("Material Request"),
|
||||
|
||||
@@ -194,7 +194,7 @@ frappe.ui.form.on("Work Order", {
|
||||
},
|
||||
|
||||
add_custom_button_to_return_components: function (frm) {
|
||||
if (frm.doc.docstatus === 1 && in_list(["Closed", "Completed"], frm.doc.status)) {
|
||||
if (frm.doc.docstatus === 1 && ["Closed", "Completed"].includes(frm.doc.status)) {
|
||||
let non_consumed_items = frm.doc.required_items.filter((d) => {
|
||||
return flt(d.consumed_qty) < flt(d.transferred_qty - d.returned_qty);
|
||||
});
|
||||
@@ -594,7 +594,7 @@ erpnext.work_order = {
|
||||
);
|
||||
}
|
||||
|
||||
if (doc.docstatus === 1 && !in_list(["Closed", "Completed"], doc.status)) {
|
||||
if (doc.docstatus === 1 && !["Closed", "Completed"].includes(doc.status)) {
|
||||
if (doc.status != "Stopped" && doc.status != "Completed") {
|
||||
frm.add_custom_button(
|
||||
__("Stop"),
|
||||
|
||||
@@ -9,15 +9,13 @@ def execute():
|
||||
|
||||
dt = frappe.qb.DocType(doctype)
|
||||
records = (
|
||||
frappe.qb.from_(dt)
|
||||
.select(dt.name, dt.notes, dt.modified_by, dt.modified)
|
||||
.where(dt.notes.isnotnull() & dt.notes != "")
|
||||
frappe.qb.from_(dt).select(dt.name, dt.notes).where(dt.notes.isnotnull() & dt.notes != "")
|
||||
).run(as_dict=True)
|
||||
|
||||
for d in records:
|
||||
if strip_html(cstr(d.notes)).strip():
|
||||
doc = frappe.get_doc(doctype, d.name)
|
||||
doc.append("notes", {"note": d.notes, "added_by": d.modified_by, "added_on": d.modified})
|
||||
doc.append("notes", {"note": d.notes})
|
||||
doc.update_child_table("notes")
|
||||
|
||||
frappe.db.sql_ddl(f"alter table `tab{doctype}` drop column `notes`")
|
||||
|
||||
@@ -240,7 +240,7 @@ erpnext.AccountTreeGrid = class AccountTreeGrid extends frappe.views.TreeGridRep
|
||||
flt(account.closing_dr) -
|
||||
flt(account.closing_cr);
|
||||
me.set_debit_or_credit(parent_account, "closing", bal);
|
||||
} else if (in_list(["debit", "credit"], col.field)) {
|
||||
} else if (["debit", "credit"].includes(col.field)) {
|
||||
parent_account[col.field] =
|
||||
flt(parent_account[col.field]) + flt(account[col.field]);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ frappe.ui.form.on("Communication", {
|
||||
);
|
||||
}
|
||||
|
||||
if (!in_list(["Lead", "Opportunity"], frm.doc.reference_doctype)) {
|
||||
if (!["Lead", "Opportunity"].includes(frm.doc.reference_doctype)) {
|
||||
frm.add_custom_button(
|
||||
__("Lead"),
|
||||
() => {
|
||||
|
||||
@@ -9,7 +9,7 @@ frappe.ui.form.on(cur_frm.doctype, {
|
||||
setup: function(frm) {
|
||||
// set conditional display for rate column in taxes
|
||||
$(frm.wrapper).on('grid-row-render', function(e, grid_row) {
|
||||
if(in_list(['Sales Taxes and Charges', 'Purchase Taxes and Charges'], grid_row.doc.doctype)) {
|
||||
if(['Sales Taxes and Charges', 'Purchase Taxes and Charges'].includes(grid_row.doc.doctype)) {
|
||||
erpnext.taxes.set_conditional_mandatory_rate_or_amount(grid_row);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -136,7 +136,7 @@ erpnext.buying.BuyingController = class BuyingController extends erpnext.Transac
|
||||
}
|
||||
|
||||
toggle_subcontracting_fields() {
|
||||
if (in_list(['Purchase Receipt', 'Purchase Invoice'], this.frm.doc.doctype)) {
|
||||
if (['Purchase Receipt', 'Purchase Invoice'].includes(this.frm.doc.doctype)) {
|
||||
this.frm.fields_dict.supplied_items.grid.update_docfield_property('consumed_qty',
|
||||
'read_only', this.frm.doc.__onload && this.frm.doc.__onload.backflush_based_on === 'BOM');
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
||||
apply_pricing_rule_on_item(item) {
|
||||
let effective_item_rate = item.price_list_rate;
|
||||
let item_rate = item.rate;
|
||||
if (in_list(["Sales Order", "Quotation"], item.parenttype) && item.blanket_order_rate) {
|
||||
if (["Sales Order", "Quotation"].includes(item.parenttype) && item.blanket_order_rate) {
|
||||
effective_item_rate = item.blanket_order_rate;
|
||||
}
|
||||
if (item.margin_type == "Percentage") {
|
||||
@@ -52,7 +52,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
||||
|
||||
// Advance calculation applicable to Sales/Purchase Invoice
|
||||
if (
|
||||
in_list(["Sales Invoice", "POS Invoice", "Purchase Invoice"], this.frm.doc.doctype)
|
||||
["Sales Invoice", "POS Invoice", "Purchase Invoice"].includes(this.frm.doc.doctype)
|
||||
&& this.frm.doc.docstatus < 2
|
||||
&& !this.frm.doc.is_return
|
||||
) {
|
||||
@@ -60,7 +60,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
||||
}
|
||||
|
||||
if (
|
||||
in_list(["Sales Invoice", "POS Invoice"], this.frm.doc.doctype)
|
||||
["Sales Invoice", "POS Invoice"].includes(this.frm.doc.doctype)
|
||||
&& this.frm.doc.is_pos
|
||||
&& this.frm.doc.is_return
|
||||
) {
|
||||
@@ -69,7 +69,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
||||
}
|
||||
|
||||
// Sales person's commission
|
||||
if (in_list(["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"], this.frm.doc.doctype)) {
|
||||
if (["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"].includes(this.frm.doc.doctype)) {
|
||||
this.calculate_commission();
|
||||
this.calculate_contribution();
|
||||
}
|
||||
@@ -547,7 +547,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
||||
? this.frm.doc["taxes"][tax_count - 1].total + flt(this.frm.doc.rounding_adjustment)
|
||||
: this.frm.doc.net_total);
|
||||
|
||||
if(in_list(["Quotation", "Sales Order", "Delivery Note", "Sales Invoice", "POS Invoice"], this.frm.doc.doctype)) {
|
||||
if(["Quotation", "Sales Order", "Delivery Note", "Sales Invoice", "POS Invoice"].includes(this.frm.doc.doctype)) {
|
||||
this.frm.doc.base_grand_total = (this.frm.doc.total_taxes_and_charges) ?
|
||||
flt(this.frm.doc.grand_total * this.frm.doc.conversion_rate) : this.frm.doc.base_net_total;
|
||||
} else {
|
||||
@@ -555,7 +555,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
||||
this.frm.doc.taxes_and_charges_added = this.frm.doc.taxes_and_charges_deducted = 0.0;
|
||||
if(tax_count) {
|
||||
$.each(this.frm.doc["taxes"] || [], function(i, tax) {
|
||||
if (in_list(["Valuation and Total", "Total"], tax.category)) {
|
||||
if (["Valuation and Total", "Total"].includes(tax.category)) {
|
||||
if(tax.add_deduct_tax == "Add") {
|
||||
me.frm.doc.taxes_and_charges_added += flt(tax.tax_amount_after_discount_amount);
|
||||
} else {
|
||||
@@ -702,7 +702,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
||||
var actual_taxes_dict = {};
|
||||
|
||||
$.each(this.frm.doc["taxes"] || [], function(i, tax) {
|
||||
if (in_list(["Actual", "On Item Quantity"], tax.charge_type)) {
|
||||
if (["Actual", "On Item Quantity"].includes(tax.charge_type)) {
|
||||
var tax_amount = (tax.category == "Valuation") ? 0.0 : tax.tax_amount;
|
||||
tax_amount *= (tax.add_deduct_tax == "Deduct") ? -1.0 : 1.0;
|
||||
actual_taxes_dict[tax.idx] = tax_amount;
|
||||
@@ -747,7 +747,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
||||
// NOTE:
|
||||
// paid_amount and write_off_amount is only for POS/Loyalty Point Redemption Invoice
|
||||
// total_advance is only for non POS Invoice
|
||||
if(in_list(["Sales Invoice", "POS Invoice"], this.frm.doc.doctype) && this.frm.doc.is_return){
|
||||
if(["Sales Invoice", "POS Invoice"].includes(this.frm.doc.doctype) && this.frm.doc.is_return){
|
||||
this.calculate_paid_amount();
|
||||
}
|
||||
|
||||
@@ -755,7 +755,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
||||
|
||||
frappe.model.round_floats_in(this.frm.doc, ["grand_total", "total_advance", "write_off_amount"]);
|
||||
|
||||
if(in_list(["Sales Invoice", "POS Invoice", "Purchase Invoice"], this.frm.doc.doctype)) {
|
||||
if(["Sales Invoice", "POS Invoice", "Purchase Invoice"].includes(this.frm.doc.doctype)) {
|
||||
let grand_total = this.frm.doc.rounded_total || this.frm.doc.grand_total;
|
||||
let base_grand_total = this.frm.doc.base_rounded_total || this.frm.doc.base_grand_total;
|
||||
|
||||
@@ -778,7 +778,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
||||
this.frm.refresh_field("base_paid_amount");
|
||||
}
|
||||
|
||||
if(in_list(["Sales Invoice", "POS Invoice"], this.frm.doc.doctype)) {
|
||||
if(["Sales Invoice", "POS Invoice"].includes(this.frm.doc.doctype)) {
|
||||
let total_amount_for_payment = (this.frm.doc.redeem_loyalty_points && this.frm.doc.loyalty_amount)
|
||||
? flt(total_amount_to_pay - this.frm.doc.loyalty_amount, precision("base_grand_total"))
|
||||
: total_amount_to_pay;
|
||||
@@ -882,7 +882,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
||||
calculate_change_amount(){
|
||||
this.frm.doc.change_amount = 0.0;
|
||||
this.frm.doc.base_change_amount = 0.0;
|
||||
if(in_list(["Sales Invoice", "POS Invoice"], this.frm.doc.doctype)
|
||||
if(["Sales Invoice", "POS Invoice"].includes(this.frm.doc.doctype)
|
||||
&& this.frm.doc.paid_amount > this.frm.doc.grand_total && !this.frm.doc.is_return) {
|
||||
|
||||
var payment_types = $.map(this.frm.doc.payments, function(d) { return d.type; });
|
||||
|
||||
@@ -260,7 +260,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
}
|
||||
|
||||
setup_quality_inspection() {
|
||||
if(!in_list(["Delivery Note", "Sales Invoice", "Purchase Receipt", "Purchase Invoice"], this.frm.doc.doctype)) {
|
||||
if(!["Delivery Note", "Sales Invoice", "Purchase Receipt", "Purchase Invoice"].includes(this.frm.doc.doctype)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
this.frm.page.set_inner_btn_group_as_primary(__('Create'));
|
||||
}
|
||||
|
||||
const inspection_type = in_list(["Purchase Receipt", "Purchase Invoice"], this.frm.doc.doctype)
|
||||
const inspection_type = ["Purchase Receipt", "Purchase Invoice"].includes(this.frm.doc.doctype)
|
||||
? "Incoming" : "Outgoing";
|
||||
|
||||
let quality_inspection_field = this.frm.get_docfield("items", "quality_inspection");
|
||||
@@ -304,7 +304,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
|
||||
make_payment_request() {
|
||||
let me = this;
|
||||
const payment_request_type = (in_list(['Sales Order', 'Sales Invoice'], this.frm.doc.doctype))
|
||||
const payment_request_type = (['Sales Order', 'Sales Invoice'].includes(this.frm.doc.doctype))
|
||||
? "Inward" : "Outward";
|
||||
|
||||
frappe.call({
|
||||
@@ -417,7 +417,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
setup_sms() {
|
||||
var me = this;
|
||||
let blacklist = ['Purchase Invoice', 'BOM'];
|
||||
if(this.frm.doc.docstatus===1 && !in_list(["Lost", "Stopped", "Closed"], this.frm.doc.status)
|
||||
if(this.frm.doc.docstatus===1 && !["Lost", "Stopped", "Closed"].includes(this.frm.doc.status)
|
||||
&& !blacklist.includes(this.frm.doctype)) {
|
||||
this.frm.page.add_menu_item(__('Send SMS'), function() { me.send_sms(); });
|
||||
}
|
||||
@@ -780,7 +780,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
}
|
||||
|
||||
var set_party_account = function(set_pricing) {
|
||||
if (in_list(["Sales Invoice", "Purchase Invoice"], me.frm.doc.doctype)) {
|
||||
if (["Sales Invoice", "Purchase Invoice"].includes(me.frm.doc.doctype)) {
|
||||
if(me.frm.doc.doctype=="Sales Invoice") {
|
||||
var party_type = "Customer";
|
||||
var party_account_field = 'debit_to';
|
||||
@@ -815,7 +815,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
}
|
||||
|
||||
if (frappe.meta.get_docfield(this.frm.doctype, "shipping_address") &&
|
||||
in_list(['Purchase Order', 'Purchase Receipt', 'Purchase Invoice'], this.frm.doctype)) {
|
||||
['Purchase Order', 'Purchase Receipt', 'Purchase Invoice'].includes(this.frm.doctype)) {
|
||||
erpnext.utils.get_shipping_address(this.frm, function() {
|
||||
set_party_account(set_pricing);
|
||||
});
|
||||
@@ -1482,7 +1482,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
"doctype": me.frm.doc.doctype,
|
||||
"name": me.frm.doc.name,
|
||||
"is_return": cint(me.frm.doc.is_return),
|
||||
"update_stock": in_list(['Sales Invoice', 'Purchase Invoice'], me.frm.doc.doctype) ? cint(me.frm.doc.update_stock) : 0,
|
||||
"update_stock": ['Sales Invoice', 'Purchase Invoice'].includes(me.frm.doc.doctype) ? cint(me.frm.doc.update_stock) : 0,
|
||||
"conversion_factor": me.frm.doc.conversion_factor,
|
||||
"pos_profile": me.frm.doc.doctype == 'Sales Invoice' ? me.frm.doc.pos_profile : '',
|
||||
"coupon_code": me.frm.doc.coupon_code
|
||||
@@ -2126,7 +2126,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
|
||||
get_method_for_payment() {
|
||||
var method = "erpnext.accounts.doctype.payment_entry.payment_entry.get_payment_entry";
|
||||
if(cur_frm.doc.__onload && cur_frm.doc.__onload.make_payment_via_journal_entry){
|
||||
if(in_list(['Sales Invoice', 'Purchase Invoice'], cur_frm.doc.doctype)){
|
||||
if(['Sales Invoice', 'Purchase Invoice'].includes( cur_frm.doc.doctype)){
|
||||
method = "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_against_invoice";
|
||||
}else {
|
||||
method= "erpnext.accounts.doctype.journal_entry.journal_entry.get_payment_entry_against_order";
|
||||
|
||||
@@ -218,7 +218,7 @@ erpnext.payments = class payments extends erpnext.stock.StockController {
|
||||
|
||||
update_paid_amount(update_write_off) {
|
||||
var me = this;
|
||||
if (in_list(["change_amount", "write_off_amount"], this.idx)) {
|
||||
if (["change_amount", "write_off_amount"].includes(this.idx)) {
|
||||
var value = me.selected_mode.val();
|
||||
if (me.idx == "change_amount") {
|
||||
me.change_amount(value);
|
||||
|
||||
@@ -28,11 +28,11 @@ erpnext.SMSManager = function SMSManager(doc) {
|
||||
"Purchase Receipt": "Items has been received against purchase receipt: " + doc.name,
|
||||
};
|
||||
|
||||
if (in_list(["Sales Order", "Delivery Note", "Sales Invoice"], doc.doctype))
|
||||
if (["Sales Order", "Delivery Note", "Sales Invoice"].includes(doc.doctype))
|
||||
this.show(doc.contact_person, "Customer", doc.customer, "", default_msg[doc.doctype]);
|
||||
else if (doc.doctype === "Quotation")
|
||||
this.show(doc.contact_person, "Customer", doc.party_name, "", default_msg[doc.doctype]);
|
||||
else if (in_list(["Purchase Order", "Purchase Receipt"], doc.doctype))
|
||||
else if (["Purchase Order", "Purchase Receipt"].includes(doc.doctype))
|
||||
this.show(doc.contact_person, "Supplier", doc.supplier, "", default_msg[doc.doctype]);
|
||||
else if (doc.doctype == "Lead") this.show("", "", "", doc.mobile_no, default_msg[doc.doctype]);
|
||||
else if (doc.doctype == "Opportunity")
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
{% for(var i=0, l=notes.length; i<l; i++) { %}
|
||||
<div class="comment-content p-3 row" name="{{ notes[i].name }}">
|
||||
<div class="mb-2 head col-xs-3">
|
||||
{% if (notes[i].added_by && notes[i].added_on) %}
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
{{ frappe.avatar(notes[i].added_by) }}
|
||||
@@ -25,6 +26,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% } %}
|
||||
</div>
|
||||
<div class="content col-xs-8">
|
||||
{{ notes[i].note }}
|
||||
|
||||
@@ -14,10 +14,10 @@ erpnext.utils.get_party_details = function (frm, method, args, callback) {
|
||||
if (!args) {
|
||||
if (
|
||||
(frm.doctype != "Purchase Order" && frm.doc.customer) ||
|
||||
(frm.doc.party_name && in_list(["Quotation", "Opportunity"], frm.doc.doctype))
|
||||
(frm.doc.party_name && ["Quotation", "Opportunity"].includes(frm.doc.doctype))
|
||||
) {
|
||||
let party_type = "Customer";
|
||||
if (frm.doc.quotation_to && in_list(["Lead", "Prospect"], frm.doc.quotation_to)) {
|
||||
if (frm.doc.quotation_to && ["Lead", "Prospect"].includes(frm.doc.quotation_to)) {
|
||||
party_type = frm.doc.quotation_to;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ frappe.ui.form.on("Import Supplier Invoice", {
|
||||
},
|
||||
|
||||
toggle_read_only_fields: function (frm) {
|
||||
if (in_list(["File Import Completed", "Processing File Data"], frm.doc.status)) {
|
||||
if (["File Import Completed", "Processing File Data"].includes(frm.doc.status)) {
|
||||
cur_frm.set_read_only();
|
||||
cur_frm.refresh_fields();
|
||||
frm.set_df_property("import_invoices", "hidden", 1);
|
||||
|
||||
@@ -150,7 +150,11 @@ frappe.ui.form.on("Sales Order", {
|
||||
frm.set_value("advance_paid", 0)
|
||||
}
|
||||
|
||||
frm.ignore_doctypes_on_cancel_all = ['Purchase Order'];
|
||||
frm.ignore_doctypes_on_cancel_all = [
|
||||
"Purchase Order",
|
||||
"Unreconcile Payment",
|
||||
"Unreconcile Payment Entries",
|
||||
];
|
||||
},
|
||||
|
||||
delivery_date: function(frm) {
|
||||
|
||||
@@ -269,7 +269,13 @@ class SalesOrder(SellingController):
|
||||
update_coupon_code_count(self.coupon_code, "used")
|
||||
|
||||
def on_cancel(self):
|
||||
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry", "Payment Ledger Entry")
|
||||
self.ignore_linked_doctypes = (
|
||||
"GL Entry",
|
||||
"Stock Ledger Entry",
|
||||
"Payment Ledger Entry",
|
||||
"Unreconcile Payment",
|
||||
"Unreconcile Payment Entries",
|
||||
)
|
||||
super().on_cancel()
|
||||
|
||||
# Cannot cancel closed SO
|
||||
|
||||
@@ -73,7 +73,7 @@ erpnext.PointOfSale.PastOrderSummary = class {
|
||||
const { status } = doc;
|
||||
let indicator_color = "";
|
||||
|
||||
in_list(["Paid", "Consolidated"], status) && (indicator_color = "green");
|
||||
["Paid", "Consolidated"].includes(status) && (indicator_color = "green");
|
||||
status === "Draft" && (indicator_color = "red");
|
||||
status === "Return" && (indicator_color = "grey");
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ erpnext.selling.SellingController = class SellingController extends erpnext.Tran
|
||||
serial_no: item.serial_no || "",
|
||||
},
|
||||
callback:function(r){
|
||||
if (in_list(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||
if (['Delivery Note', 'Sales Invoice'].includes(doc.doctype)) {
|
||||
if (doc.doctype === 'Sales Invoice' && (!doc.update_stock)) return;
|
||||
if (has_batch_no) {
|
||||
me.set_batch_number(cdt, cdn);
|
||||
@@ -332,7 +332,7 @@ erpnext.selling.SellingController = class SellingController extends erpnext.Tran
|
||||
if ((doc.packed_items || []).length) {
|
||||
$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(true);
|
||||
|
||||
if (in_list(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||
if (['Delivery Note', 'Sales Invoice'].includes(doc.doctype)) {
|
||||
var help_msg = "<div class='alert alert-warning'>" +
|
||||
__("For 'Product Bundle' items, Warehouse, Serial No and Batch No will be considered from the 'Packing List' table. If Warehouse and Batch No are same for all packing items for any 'Product Bundle' item, those values can be entered in the main Item table, values will be copied to 'Packing List' table.")+
|
||||
"</div>";
|
||||
@@ -340,7 +340,7 @@ erpnext.selling.SellingController = class SellingController extends erpnext.Tran
|
||||
}
|
||||
} else {
|
||||
$(cur_frm.fields_dict.packing_list.row.wrapper).toggle(false);
|
||||
if (in_list(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||
if (['Delivery Note', 'Sales Invoice'].includes(doc.doctype)) {
|
||||
frappe.meta.get_docfield(doc.doctype, 'product_bundle_help', doc.name).options = '';
|
||||
}
|
||||
}
|
||||
@@ -367,7 +367,7 @@ erpnext.selling.SellingController = class SellingController extends erpnext.Tran
|
||||
conversion_factor(doc, cdt, cdn, dont_fetch_price_list_rate) {
|
||||
super.conversion_factor(doc, cdt, cdn, dont_fetch_price_list_rate);
|
||||
if(frappe.meta.get_docfield(cdt, "stock_qty", cdn) &&
|
||||
in_list(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||
['Delivery Note', 'Sales Invoice'].includes(doc.doctype)) {
|
||||
if (doc.doctype === 'Sales Invoice' && (!doc.update_stock)) return;
|
||||
this.set_batch_number(cdt, cdn);
|
||||
}
|
||||
@@ -376,7 +376,7 @@ erpnext.selling.SellingController = class SellingController extends erpnext.Tran
|
||||
qty(doc, cdt, cdn) {
|
||||
super.qty(doc, cdt, cdn);
|
||||
|
||||
if(in_list(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||
if(['Delivery Note', 'Sales Invoice'].includes(doc.doctype)) {
|
||||
if (doc.doctype === 'Sales Invoice' && (!doc.update_stock)) return;
|
||||
this.set_batch_number(cdt, cdn);
|
||||
}
|
||||
@@ -440,7 +440,7 @@ erpnext.selling.SellingController = class SellingController extends erpnext.Tran
|
||||
};
|
||||
|
||||
frappe.ui.form.on(cur_frm.doctype,"project", function(frm) {
|
||||
if(in_list(["Delivery Note", "Sales Invoice"], frm.doc.doctype)) {
|
||||
if(["Delivery Note", "Sales Invoice"].includes(frm.doc.doctype)) {
|
||||
if(frm.doc.project) {
|
||||
frappe.call({
|
||||
method:'erpnext.projects.doctype.project.project.get_cost_center_name' ,
|
||||
|
||||
@@ -712,7 +712,7 @@
|
||||
"image_field": "company_logo",
|
||||
"is_tree": 1,
|
||||
"links": [],
|
||||
"modified": "2023-10-23 10:19:24.322898",
|
||||
"modified": "2024-05-27 17:32:49.057386",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Setup",
|
||||
"name": "Company",
|
||||
@@ -768,6 +768,10 @@
|
||||
"role": "Accounts Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"role": "Auditor",
|
||||
"select": 1
|
||||
}
|
||||
],
|
||||
"show_name_in_global_search": 1,
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
"idx": 1,
|
||||
"is_tree": 1,
|
||||
"links": [],
|
||||
"modified": "2023-08-28 17:26:46.826501",
|
||||
"modified": "2024-06-12 16:10:31.451257",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Setup",
|
||||
"name": "Department",
|
||||
@@ -132,6 +132,10 @@
|
||||
"role": "HR Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"role": "Employee",
|
||||
"select": 1
|
||||
}
|
||||
],
|
||||
"show_name_in_global_search": 1,
|
||||
|
||||
@@ -8,7 +8,7 @@ frappe.ui.form.on("Closing Stock Balance", {
|
||||
},
|
||||
|
||||
generate_closing_balance(frm) {
|
||||
if (in_list(["Queued", "Failed"], frm.doc.status)) {
|
||||
if (["Queued", "Failed"].includes(frm.doc.status)) {
|
||||
frm.add_custom_button(__("Generate Closing Stock Balance"), () => {
|
||||
frm.call({
|
||||
method: "enqueue_job",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
frappe.listview_settings["Delivery Trip"] = {
|
||||
add_fields: ["status"],
|
||||
get_indicator: function (doc) {
|
||||
if (in_list(["Cancelled", "Draft"], doc.status)) {
|
||||
if (["Cancelled", "Draft"].includes(doc.status)) {
|
||||
return [__(doc.status), "red", "status,=," + doc.status];
|
||||
} else if (in_list(["In Transit", "Scheduled"], doc.status)) {
|
||||
} else if (["In Transit", "Scheduled"].includes(doc.status)) {
|
||||
return [__(doc.status), "orange", "status,=," + doc.status];
|
||||
} else if (doc.status === "Completed") {
|
||||
return [__(doc.status), "green", "status,=," + doc.status];
|
||||
|
||||
@@ -224,7 +224,10 @@ class LandedCostVoucher(Document):
|
||||
# update stock & gl entries for submit state of PR
|
||||
doc.docstatus = 1
|
||||
doc.update_stock_ledger(allow_negative_stock=True, via_landed_cost_voucher=True)
|
||||
doc.make_gl_entries()
|
||||
if d.receipt_document_type == "Purchase Receipt":
|
||||
doc.make_gl_entries(via_landed_cost_voucher=True)
|
||||
else:
|
||||
doc.make_gl_entries()
|
||||
doc.repost_future_sle_and_gle()
|
||||
|
||||
def validate_asset_qty_and_status(self, receipt_document_type, receipt_document):
|
||||
|
||||
@@ -307,13 +307,13 @@ class PurchaseReceipt(BuyingController):
|
||||
self.delete_auto_created_batches()
|
||||
self.set_consumed_qty_in_subcontract_order()
|
||||
|
||||
def get_gl_entries(self, warehouse_account=None):
|
||||
def get_gl_entries(self, warehouse_account=None, via_landed_cost_voucher=False):
|
||||
from erpnext.accounts.general_ledger import process_gl_map
|
||||
|
||||
gl_entries = []
|
||||
|
||||
self.make_item_gl_entries(gl_entries, warehouse_account=warehouse_account)
|
||||
self.make_tax_gl_entries(gl_entries)
|
||||
self.make_tax_gl_entries(gl_entries, via_landed_cost_voucher)
|
||||
update_regional_gl_entries(gl_entries, self)
|
||||
|
||||
return process_gl_map(gl_entries)
|
||||
@@ -661,7 +661,7 @@ class PurchaseReceipt(BuyingController):
|
||||
posting_date=posting_date,
|
||||
)
|
||||
|
||||
def make_tax_gl_entries(self, gl_entries):
|
||||
def make_tax_gl_entries(self, gl_entries, via_landed_cost_voucher=False):
|
||||
negative_expense_to_be_booked = sum([flt(d.item_tax_amount) for d in self.get("items")])
|
||||
is_asset_pr = any(d.is_fixed_asset for d in self.get("items"))
|
||||
# Cost center-wise amount breakup for other charges included for valuation
|
||||
@@ -696,18 +696,17 @@ class PurchaseReceipt(BuyingController):
|
||||
i = 1
|
||||
for tax in self.get("taxes"):
|
||||
if valuation_tax.get(tax.name):
|
||||
negative_expense_booked_in_pi = frappe.db.sql(
|
||||
"""select name from `tabPurchase Invoice Item` pi
|
||||
where docstatus = 1 and purchase_receipt=%s
|
||||
and exists(select name from `tabGL Entry` where voucher_type='Purchase Invoice'
|
||||
and voucher_no=pi.parent and account=%s)""",
|
||||
(self.name, tax.account_head),
|
||||
)
|
||||
|
||||
if negative_expense_booked_in_pi:
|
||||
account = stock_rbnb
|
||||
else:
|
||||
if via_landed_cost_voucher:
|
||||
account = tax.account_head
|
||||
else:
|
||||
negative_expense_booked_in_pi = frappe.db.sql(
|
||||
"""select name from `tabPurchase Invoice Item` pi
|
||||
where docstatus = 1 and purchase_receipt=%s
|
||||
and exists(select name from `tabGL Entry` where voucher_type='Purchase Invoice'
|
||||
and voucher_no=pi.parent and account=%s)""",
|
||||
(self.name, tax.account_head),
|
||||
)
|
||||
account = stock_rbnb if negative_expense_booked_in_pi else tax.account_head
|
||||
|
||||
if i == len(valuation_tax):
|
||||
applicable_amount = amount_including_divisional_loss
|
||||
|
||||
@@ -9,6 +9,7 @@ from pypika import functions as fn
|
||||
import erpnext
|
||||
from erpnext.accounts.doctype.account.test_account import get_inventory_account
|
||||
from erpnext.controllers.buying_controller import QtyMismatchError
|
||||
from erpnext.stock import get_warehouse_account_map
|
||||
from erpnext.stock.doctype.item.test_item import create_item, make_item
|
||||
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import make_purchase_invoice
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||
@@ -1640,7 +1641,6 @@ class TestPurchaseReceipt(FrappeTestCase):
|
||||
frappe.db.set_single_value("Stock Settings", "over_delivery_receipt_allowance", 0)
|
||||
|
||||
def test_internal_pr_gl_entries(self):
|
||||
from erpnext.stock import get_warehouse_account_map
|
||||
from erpnext.stock.doctype.delivery_note.delivery_note import make_inter_company_purchase_receipt
|
||||
from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
|
||||
@@ -2301,6 +2301,54 @@ class TestPurchaseReceipt(FrappeTestCase):
|
||||
for index, d in enumerate(data):
|
||||
self.assertEqual(d.qty_after_transaction, 11 + index)
|
||||
|
||||
def test_valuation_taxes_lcv_repost_after_billing(self):
|
||||
from erpnext.stock.doctype.landed_cost_voucher.test_landed_cost_voucher import (
|
||||
make_landed_cost_voucher,
|
||||
)
|
||||
|
||||
old_perpetual_inventory = erpnext.is_perpetual_inventory_enabled("_Test Company")
|
||||
frappe.local.enable_perpetual_inventory["_Test Company"] = 1
|
||||
frappe.db.set_value(
|
||||
"Company",
|
||||
"_Test Company",
|
||||
"stock_received_but_not_billed",
|
||||
"Stock Received But Not Billed - _TC",
|
||||
)
|
||||
|
||||
pr = make_purchase_receipt(qty=10, rate=1000, do_not_submit=1)
|
||||
pr.append(
|
||||
"taxes",
|
||||
{
|
||||
"category": "Valuation and Total",
|
||||
"charge_type": "Actual",
|
||||
"account_head": "Freight and Forwarding Charges - _TC",
|
||||
"tax_amount": 2000,
|
||||
"description": "Test",
|
||||
},
|
||||
)
|
||||
pr.submit()
|
||||
pi = make_purchase_invoice(pr.name)
|
||||
pi.submit()
|
||||
make_landed_cost_voucher(
|
||||
company=pr.company,
|
||||
receipt_document_type="Purchase Receipt",
|
||||
receipt_document=pr.name,
|
||||
charges=2000,
|
||||
distribute_charges_based_on="Qty",
|
||||
expense_account="Expenses Included In Valuation - _TC",
|
||||
)
|
||||
|
||||
gl_entries = get_gl_entries("Purchase Receipt", pr.name, skip_cancelled=True, as_dict=False)
|
||||
warehouse_account = get_warehouse_account_map("_Test Company")
|
||||
expected_gle = (
|
||||
("Stock Received But Not Billed - _TC", 0, 10000, "Main - _TC"),
|
||||
("Freight and Forwarding Charges - _TC", 0, 2000, "Main - _TC"),
|
||||
("Expenses Included In Valuation - _TC", 0, 2000, "Main - _TC"),
|
||||
(warehouse_account[pr.items[0].warehouse]["account"], 14000, 0, "Main - _TC"),
|
||||
)
|
||||
self.assertSequenceEqual(expected_gle, gl_entries)
|
||||
frappe.local.enable_perpetual_inventory["_Test Company"] = old_perpetual_inventory
|
||||
|
||||
|
||||
def prepare_data_for_internal_transfer():
|
||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_internal_supplier
|
||||
@@ -2347,14 +2395,24 @@ def get_sl_entries(voucher_type, voucher_no):
|
||||
)
|
||||
|
||||
|
||||
def get_gl_entries(voucher_type, voucher_no):
|
||||
return frappe.db.sql(
|
||||
"""select account, debit, credit, cost_center, is_cancelled
|
||||
from `tabGL Entry` where voucher_type=%s and voucher_no=%s
|
||||
order by account desc""",
|
||||
(voucher_type, voucher_no),
|
||||
as_dict=1,
|
||||
def get_gl_entries(voucher_type, voucher_no, skip_cancelled=False, as_dict=True):
|
||||
gl = frappe.qb.DocType("GL Entry")
|
||||
gl_query = (
|
||||
frappe.qb.from_(gl)
|
||||
.select(
|
||||
gl.account,
|
||||
gl.debit,
|
||||
gl.credit,
|
||||
gl.cost_center,
|
||||
)
|
||||
.where((gl.voucher_type == voucher_type) & (gl.voucher_no == voucher_no))
|
||||
.orderby(gl.account, order=frappe.qb.desc)
|
||||
)
|
||||
if skip_cancelled:
|
||||
gl_query = gl_query.where(gl.is_cancelled == 0)
|
||||
else:
|
||||
gl_query = gl_query.select(gl.is_cancelled)
|
||||
return gl_query.run(as_dict=as_dict)
|
||||
|
||||
|
||||
def get_taxes(**args):
|
||||
|
||||
@@ -45,7 +45,7 @@ class RepostItemValuation(Document):
|
||||
|
||||
def validate_period_closing_voucher(self):
|
||||
# Period Closing Voucher
|
||||
year_end_date = self.get_max_year_end_date(self.company)
|
||||
year_end_date = self.get_max_period_closing_date(self.company)
|
||||
if year_end_date and getdate(self.posting_date) <= getdate(year_end_date):
|
||||
date = frappe.format(year_end_date, "Date")
|
||||
msg = f"Due to period closing, you cannot repost item valuation before {date}"
|
||||
@@ -88,24 +88,16 @@ class RepostItemValuation(Document):
|
||||
return frappe.get_all("Closing Stock Balance", fields=["name", "to_date"], filters=filters)
|
||||
|
||||
@staticmethod
|
||||
def get_max_year_end_date(company):
|
||||
data = frappe.get_all(
|
||||
"Period Closing Voucher", fields=["fiscal_year"], filters={"docstatus": 1, "company": company}
|
||||
)
|
||||
|
||||
if not data:
|
||||
return
|
||||
|
||||
fiscal_years = [d.fiscal_year for d in data]
|
||||
table = frappe.qb.DocType("Fiscal Year")
|
||||
def get_max_period_closing_date(company):
|
||||
table = frappe.qb.DocType("Period Closing Voucher")
|
||||
|
||||
query = (
|
||||
frappe.qb.from_(table)
|
||||
.select(Max(table.year_end_date))
|
||||
.where((table.name.isin(fiscal_years)) & (table.disabled == 0))
|
||||
.select(Max(table.posting_date))
|
||||
.where((table.company == company) & (table.docstatus == 1))
|
||||
).run()
|
||||
|
||||
return query[0][0] if query else None
|
||||
return query[0][0] if query and query[0][0] else None
|
||||
|
||||
def validate_accounts_freeze(self):
|
||||
acc_settings = frappe.db.get_value(
|
||||
|
||||
@@ -77,7 +77,7 @@ frappe.ui.form.on('Stock Entry', {
|
||||
if(!item.item_code) {
|
||||
frappe.throw(__("Please enter Item Code to get Batch Number"));
|
||||
} else {
|
||||
if (in_list(["Material Transfer for Manufacture", "Manufacture", "Repack", "Send to Subcontractor"], doc.purpose)) {
|
||||
if (["Material Transfer for Manufacture", "Manufacture", "Repack", "Send to Subcontractor"].includes(doc.purpose)) {
|
||||
var filters = {
|
||||
'item_code': item.item_code,
|
||||
'posting_date': frm.doc.posting_date || frappe.datetime.nowdate()
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
actual_qty = (frm.doc.doctype==="Sales Order"
|
||||
? doc.projected_qty : doc.actual_qty);
|
||||
if(flt(frm.doc.per_delivered) < 100
|
||||
&& in_list(["Sales Order Item", "Delivery Note Item"], doc.doctype)) {
|
||||
&& ["Sales Order Item", "Delivery Note Item"].includes(doc.doctype)) {
|
||||
if(actual_qty != undefined) {
|
||||
if(actual_qty >= doc.qty) {
|
||||
var color = "green";
|
||||
|
||||
Reference in New Issue
Block a user