Skip to content

Commit

Permalink
Merge pull request #34238 from frappe/version-14-hotfix
Browse files Browse the repository at this point in the history
chore: release v14
  • Loading branch information
ruthra-kumar authored Feb 28, 2023
2 parents cb266cd + 01b5ed9 commit 60ab0d3
Show file tree
Hide file tree
Showing 26 changed files with 340 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ def _import_accounts(children, parent, root_type, root_account=False):
"root_type",
"is_group",
"tax_rate",
"account_currency",
]:

account_number = cstr(child.get("account_number")).strip()
Expand Down Expand Up @@ -95,7 +96,17 @@ def identify_is_group(child):
is_group = child.get("is_group")
elif len(
set(child.keys())
- set(["account_name", "account_type", "root_type", "is_group", "tax_rate", "account_number"])
- set(
[
"account_name",
"account_type",
"root_type",
"is_group",
"tax_rate",
"account_number",
"account_currency",
]
)
):
is_group = 1
else:
Expand Down Expand Up @@ -185,6 +196,7 @@ def get_account_tree_from_existing_company(existing_company):
"root_type",
"tax_rate",
"account_number",
"account_currency",
],
order_by="lft, rgt",
)
Expand Down Expand Up @@ -267,6 +279,7 @@ def _import_accounts(children, parent):
"root_type",
"is_group",
"tax_rate",
"account_currency",
]:
continue

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def validate_columns(data):

no_of_columns = max([len(d) for d in data])

if no_of_columns > 7:
if no_of_columns > 8:
frappe.throw(
_("More columns found than expected. Please compare the uploaded file with standard template"),
title=(_("Wrong Template")),
Expand Down Expand Up @@ -233,6 +233,7 @@ def return_parent(data, child):
is_group,
account_type,
root_type,
account_currency,
) = i

if not account_name:
Expand All @@ -253,6 +254,8 @@ def return_parent(data, child):
charts_map[account_name]["account_type"] = account_type
if root_type:
charts_map[account_name]["root_type"] = root_type
if account_currency:
charts_map[account_name]["account_currency"] = account_currency
path = return_parent(data, account_name)[::-1]
paths.append(path) # List of path is created
line_no += 1
Expand Down Expand Up @@ -315,6 +318,7 @@ def get_template(template_type):
"Is Group",
"Account Type",
"Root Type",
"Account Currency",
]
writer = UnicodeWriter()
writer.writerow(fields)
Expand Down
8 changes: 4 additions & 4 deletions erpnext/accounts/doctype/pos_invoice/pos_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ def validate_pos_reserved_batch_qty(self, item):

bold_item_name = frappe.bold(item.item_name)
bold_extra_batch_qty_needed = frappe.bold(
abs(available_batch_qty - reserved_batch_qty - item.qty)
abs(available_batch_qty - reserved_batch_qty - item.stock_qty)
)
bold_invalid_batch_no = frappe.bold(item.batch_no)

Expand All @@ -172,7 +172,7 @@ def validate_pos_reserved_batch_qty(self, item):
).format(item.idx, bold_invalid_batch_no, bold_item_name),
title=_("Item Unavailable"),
)
elif (available_batch_qty - reserved_batch_qty - item.qty) < 0:
elif (available_batch_qty - reserved_batch_qty - item.stock_qty) < 0:
frappe.throw(
_(
"Row #{}: Batch No. {} of item {} has less than required stock available, {} more required"
Expand Down Expand Up @@ -246,7 +246,7 @@ def validate_stock_availablility(self):
),
title=_("Item Unavailable"),
)
elif is_stock_item and flt(available_stock) < flt(d.qty):
elif is_stock_item and flt(available_stock) < flt(d.stock_qty):
frappe.throw(
_(
"Row #{}: Stock quantity not enough for Item Code: {} under warehouse {}. Available quantity {}."
Expand Down Expand Up @@ -650,7 +650,7 @@ def get_bundle_availability(bundle_item_code, warehouse):
item_pos_reserved_qty = get_pos_reserved_qty(item.item_code, warehouse)
available_qty = item_bin_qty - item_pos_reserved_qty

max_available_bundles = available_qty / item.qty
max_available_bundles = available_qty / item.stock_qty
if bundle_bin_qty > max_available_bundles and frappe.get_value(
"Item", item.item_code, "is_stock_item"
):
Expand Down
2 changes: 1 addition & 1 deletion erpnext/accounts/doctype/sales_invoice/sales_invoice.js
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,7 @@ var select_loyalty_program = function(frm, loyalty_programs) {
]
});

dialog.set_primary_action(__("Set"), function() {
dialog.set_primary_action(__("Set Loyalty Program"), function() {
dialog.hide();
return frappe.call({
method: "frappe.client.set_value",
Expand Down
59 changes: 34 additions & 25 deletions erpnext/accounts/report/gross_profit/gross_profit.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ def get_column_names():

class GrossProfitGenerator(object):
def __init__(self, filters=None):
self.sle = {}
self.data = []
self.average_buying_rate = {}
self.filters = frappe._dict(filters)
Expand All @@ -404,7 +405,6 @@ def __init__(self, filters=None):
if filters.group_by == "Invoice":
self.group_items_by_invoice()

self.load_stock_ledger_entries()
self.load_product_bundle()
self.load_non_stock_items()
self.get_returned_invoice_items()
Expand Down Expand Up @@ -633,7 +633,7 @@ def get_buying_amount(self, row, item_code):
return flt(row.qty) * item_rate

else:
my_sle = self.sle.get((item_code, row.warehouse))
my_sle = self.get_stock_ledger_entries(item_code, row.warehouse)
if (row.update_stock or row.dn_detail) and my_sle:
parenttype, parent = row.parenttype, row.parent
if row.dn_detail:
Expand All @@ -651,7 +651,7 @@ def get_buying_amount(self, row, item_code):
dn["item_row"],
dn["warehouse"],
)
my_sle = self.sle.get((item_code, warehouse))
my_sle = self.get_stock_ledger_entries(item_code, row.warehouse)
return self.calculate_buying_amount_from_sle(
row, my_sle, parenttype, parent, item_row, item_code
)
Expand All @@ -667,15 +667,12 @@ def get_buying_amount(self, row, item_code):
def get_buying_amount_from_so_dn(self, sales_order, so_detail, item_code):
from frappe.query_builder.functions import Sum

delivery_note = frappe.qb.DocType("Delivery Note")
delivery_note_item = frappe.qb.DocType("Delivery Note Item")

query = (
frappe.qb.from_(delivery_note)
.inner_join(delivery_note_item)
.on(delivery_note.name == delivery_note_item.parent)
frappe.qb.from_(delivery_note_item)
.select(Sum(delivery_note_item.incoming_rate * delivery_note_item.stock_qty))
.where(delivery_note.docstatus == 1)
.where(delivery_note_item.docstatus == 1)
.where(delivery_note_item.item_code == item_code)
.where(delivery_note_item.against_sales_order == sales_order)
.where(delivery_note_item.so_detail == so_detail)
Expand Down Expand Up @@ -940,24 +937,36 @@ def get_bundle_item_details(self, item_code):
"Item", item_code, ["item_name", "description", "item_group", "brand"]
)

def load_stock_ledger_entries(self):
res = frappe.db.sql(
"""select item_code, voucher_type, voucher_no,
voucher_detail_no, stock_value, warehouse, actual_qty as qty
from `tabStock Ledger Entry`
where company=%(company)s and is_cancelled = 0
order by
item_code desc, warehouse desc, posting_date desc,
posting_time desc, creation desc""",
self.filters,
as_dict=True,
)
self.sle = {}
for r in res:
if (r.item_code, r.warehouse) not in self.sle:
self.sle[(r.item_code, r.warehouse)] = []
def get_stock_ledger_entries(self, item_code, warehouse):
if item_code and warehouse:
if (item_code, warehouse) not in self.sle:
sle = qb.DocType("Stock Ledger Entry")
res = (
qb.from_(sle)
.select(
sle.item_code,
sle.voucher_type,
sle.voucher_no,
sle.voucher_detail_no,
sle.stock_value,
sle.warehouse,
sle.actual_qty.as_("qty"),
)
.where(
(sle.company == self.filters.company)
& (sle.item_code == item_code)
& (sle.warehouse == warehouse)
& (sle.is_cancelled == 0)
)
.orderby(sle.item_code)
.orderby(sle.warehouse, sle.posting_date, sle.posting_time, sle.creation, order=Order.desc)
.run(as_dict=True)
)

self.sle[(item_code, warehouse)] = res

self.sle[(r.item_code, r.warehouse)].append(r)
return self.sle[(item_code, warehouse)]
return []

def load_product_bundle(self):
self.product_bundles = {}
Expand Down
22 changes: 11 additions & 11 deletions erpnext/assets/doctype/asset/asset.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,10 +302,6 @@ frappe.ui.form.on('Asset', {
// frm.toggle_reqd("next_depreciation_date", (!frm.doc.is_existing_asset && frm.doc.calculate_depreciation));
},

opening_accumulated_depreciation: function(frm) {
erpnext.asset.set_accumulated_depreciation(frm);
},

make_schedules_editable: function(frm) {
if (frm.doc.finance_books) {
var is_editable = frm.doc.finance_books.filter(d => d.depreciation_method == "Manual").length > 0
Expand Down Expand Up @@ -567,19 +563,23 @@ frappe.ui.form.on('Depreciation Schedule', {
},

depreciation_amount: function(frm, cdt, cdn) {
erpnext.asset.set_accumulated_depreciation(frm);
erpnext.asset.set_accumulated_depreciation(frm, locals[cdt][cdn].finance_book_id);
}

})
});

erpnext.asset.set_accumulated_depreciation = function(frm) {
if(frm.doc.depreciation_method != "Manual") return;
erpnext.asset.set_accumulated_depreciation = function(frm, finance_book_id) {
var depreciation_method = frm.doc.finance_books[Number(finance_book_id) - 1].depreciation_method;

if(depreciation_method != "Manual") return;

var accumulated_depreciation = flt(frm.doc.opening_accumulated_depreciation);

$.each(frm.doc.schedules || [], function(i, row) {
accumulated_depreciation += flt(row.depreciation_amount);
frappe.model.set_value(row.doctype, row.name,
"accumulated_depreciation_amount", accumulated_depreciation);
if (row.finance_book_id === finance_book_id) {
accumulated_depreciation += flt(row.depreciation_amount);
frappe.model.set_value(row.doctype, row.name, "accumulated_depreciation_amount", accumulated_depreciation);
};
})
};

Expand Down
59 changes: 51 additions & 8 deletions erpnext/assets/doctype/asset/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,55 @@ def prepare_depreciation_data(self, date_of_disposal=None, date_of_return=None):
if self.calculate_depreciation:
self.value_after_depreciation = 0
self.set_depreciation_rate()
self.make_depreciation_schedule(date_of_disposal)
self.set_accumulated_depreciation(date_of_disposal, date_of_return)
if self.should_prepare_depreciation_schedule():
self.make_depreciation_schedule(date_of_disposal)
self.set_accumulated_depreciation(date_of_disposal, date_of_return)
else:
self.finance_books = []
self.value_after_depreciation = flt(self.gross_purchase_amount) - flt(
self.opening_accumulated_depreciation
)

def should_prepare_depreciation_schedule(self):
if not self.get("schedules"):
return True

old_asset_doc = self.get_doc_before_save()

if not old_asset_doc:
return True

have_asset_details_been_modified = (
old_asset_doc.gross_purchase_amount != self.gross_purchase_amount
or old_asset_doc.opening_accumulated_depreciation != self.opening_accumulated_depreciation
or old_asset_doc.number_of_depreciations_booked != self.number_of_depreciations_booked
)

if have_asset_details_been_modified:
return True

manual_fb_idx = -1
for d in self.finance_books:
if d.depreciation_method == "Manual":
manual_fb_idx = d.idx - 1

no_manual_depr_or_have_manual_depr_details_been_modified = (
manual_fb_idx == -1
or old_asset_doc.finance_books[manual_fb_idx].total_number_of_depreciations
!= self.finance_books[manual_fb_idx].total_number_of_depreciations
or old_asset_doc.finance_books[manual_fb_idx].frequency_of_depreciation
!= self.finance_books[manual_fb_idx].frequency_of_depreciation
or old_asset_doc.finance_books[manual_fb_idx].depreciation_start_date
!= getdate(self.finance_books[manual_fb_idx].depreciation_start_date)
or old_asset_doc.finance_books[manual_fb_idx].expected_value_after_useful_life
!= self.finance_books[manual_fb_idx].expected_value_after_useful_life
)

if no_manual_depr_or_have_manual_depr_details_been_modified:
return True

return False

def validate_item(self):
item = frappe.get_cached_value(
"Item", self.item_code, ["is_fixed_asset", "is_stock_item", "disabled"], as_dict=1
Expand Down Expand Up @@ -225,9 +266,7 @@ def set_depreciation_rate(self):
)

def make_depreciation_schedule(self, date_of_disposal):
if "Manual" not in [d.depreciation_method for d in self.finance_books] and not self.get(
"schedules"
):
if not self.get("schedules"):
self.schedules = []

if not self.available_for_use_date:
Expand Down Expand Up @@ -555,16 +594,20 @@ def has_only_one_finance_book(self):
def set_accumulated_depreciation(
self, date_of_disposal=None, date_of_return=None, ignore_booked_entry=False
):
straight_line_idx = [
d.idx for d in self.get("schedules") if d.depreciation_method == "Straight Line"
]
straight_line_idx = []
finance_books = []

for i, d in enumerate(self.get("schedules")):
if ignore_booked_entry and d.journal_entry:
continue

if int(d.finance_book_id) not in finance_books:
straight_line_idx = [
s.idx
for s in self.get("schedules")
if s.finance_book_id == d.finance_book_id
and (s.depreciation_method == "Straight Line" or s.depreciation_method == "Manual")
]
accumulated_depreciation = flt(self.opening_accumulated_depreciation)
value_after_depreciation = flt(
self.get("finance_books")[cint(d.finance_book_id) - 1].value_after_depreciation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ frappe.query_reports["Subcontracted Item To Be Received"] = {
fieldname:"from_date",
label: __("From Date"),
fieldtype: "Date",
default: frappe.datetime.add_months(frappe.datetime.month_start(), -1),
default: frappe.datetime.add_months(frappe.datetime.get_today(), -1),
reqd: 1
},
{
fieldname:"to_date",
label: __("To Date"),
fieldtype: "Date",
default: frappe.datetime.add_days(frappe.datetime.month_start(),-1),
default: frappe.datetime.get_today(),
reqd: 1
},
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ frappe.query_reports["Subcontracted Raw Materials To Be Transferred"] = {
fieldname:"from_date",
label: __("From Date"),
fieldtype: "Date",
default: frappe.datetime.add_months(frappe.datetime.month_start(), -1),
default: frappe.datetime.add_months(frappe.datetime.get_today(), -1),
reqd: 1
},
{
fieldname:"to_date",
label: __("To Date"),
fieldtype: "Date",
default: frappe.datetime.add_days(frappe.datetime.month_start(),-1),
default: frappe.datetime.get_today(),
reqd: 1
},
]
Expand Down
Loading

0 comments on commit 60ab0d3

Please sign in to comment.