Skip to content

Commit

Permalink
Merge branch 'develop' into bootstrapped_gst_setup_develop
Browse files Browse the repository at this point in the history
  • Loading branch information
nextchamp-saqib authored Jul 14, 2021
2 parents 9fa0907 + 8ae8984 commit 0f81ccb
Show file tree
Hide file tree
Showing 11 changed files with 582 additions and 116 deletions.
17 changes: 14 additions & 3 deletions erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -975,8 +975,17 @@ def test_deferred_expense_via_journal_entry(self):
acc_settings.save()

def test_gain_loss_with_advance_entry(self):
unlink_enabled = frappe.db.get_value("Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice")
frappe.db.set_value("Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice", 1)
unlink_enabled = frappe.db.get_value(
"Accounts Settings", "Accounts Settings",
"unlink_payment_on_cancel_of_invoice")

frappe.db.set_value(
"Accounts Settings", "Accounts Settings",
"unlink_payment_on_cancel_of_invoice", 1)

original_account = frappe.db.get_value("Company", "_Test Company", "exchange_gain_loss_account")
frappe.db.set_value("Company", "_Test Company", "exchange_gain_loss_account", "Exchange Gain/Loss - _TC")

pay = frappe.get_doc({
'doctype': 'Payment Entry',
'company': '_Test Company',
Expand Down Expand Up @@ -1016,7 +1025,8 @@ def test_gain_loss_with_advance_entry(self):
gl_entries = frappe.db.sql("""
select account, sum(debit - credit) as balance from `tabGL Entry`
where voucher_no=%s
group by account order by account asc""", (pi.name), as_dict=1)
group by account
order by account asc""", (pi.name), as_dict=1)

for i, gle in enumerate(gl_entries):
self.assertEqual(expected_gle[i][0], gle.account)
Expand Down Expand Up @@ -1076,6 +1086,7 @@ def test_gain_loss_with_advance_entry(self):
pay.cancel()

frappe.db.set_value("Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice", unlink_enabled)
frappe.db.set_value("Company", "_Test Company", "exchange_gain_loss_account", original_account)

def test_purchase_invoice_advance_taxes(self):
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
Expand Down
33 changes: 25 additions & 8 deletions erpnext/accounts/doctype/sales_invoice/sales_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from erpnext.stock.doctype.delivery_note.delivery_note import update_billed_amount_based_on_so
from erpnext.projects.doctype.timesheet.timesheet import get_projectwise_timesheet_data
from erpnext.assets.doctype.asset.depreciation \
import get_disposal_account_and_cost_center, get_gl_entries_on_asset_disposal
import get_disposal_account_and_cost_center, get_gl_entries_on_asset_disposal, get_gl_entries_on_asset_regain
from erpnext.stock.doctype.batch.batch import set_batch_nos
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos, get_delivery_note_serial_no
from erpnext.setup.doctype.company.company import update_company_current_month_sales
Expand Down Expand Up @@ -149,7 +149,7 @@ def validate_fixed_asset(self):
if self.update_stock:
frappe.throw(_("'Update Stock' cannot be checked for fixed asset sale"))

elif asset.status in ("Scrapped", "Cancelled", "Sold"):
elif asset.status in ("Scrapped", "Cancelled") or (asset.status == "Sold" and not self.is_return):
frappe.throw(_("Row #{0}: Asset {1} cannot be submitted, it is already {2}").format(d.idx, d.asset, asset.status))

def validate_item_cost_centers(self):
Expand Down Expand Up @@ -918,22 +918,33 @@ def make_item_gl_entries(self, gl_entries):
for item in self.get("items"):
if flt(item.base_net_amount, item.precision("base_net_amount")):
if item.is_fixed_asset:
asset = frappe.get_doc("Asset", item.asset)

if item.get('asset'):
asset = frappe.get_doc("Asset", item.asset)
else:
frappe.throw(_(
"Row #{0}: You must select an Asset for Item {1}.").format(item.idx, item.item_name),
title=_("Missing Asset")
)
if (len(asset.finance_books) > 1 and not item.finance_book
and asset.finance_books[0].finance_book):
frappe.throw(_("Select finance book for the item {0} at row {1}")
.format(item.item_code, item.idx))

fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset,
item.base_net_amount, item.finance_book)
if self.is_return:
fixed_asset_gl_entries = get_gl_entries_on_asset_regain(asset,
item.base_net_amount, item.finance_book)
asset.db_set("disposal_date", None)
else:
fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(asset,
item.base_net_amount, item.finance_book)
asset.db_set("disposal_date", self.posting_date)

for gle in fixed_asset_gl_entries:
gle["against"] = self.customer
gl_entries.append(self.get_gl_dict(gle, item=item))

asset.db_set("disposal_date", self.posting_date)
asset.set_status("Sold" if self.docstatus==1 else None)
self.set_asset_status(asset)

else:
# Do not book income for transfer within same company
if not self.is_internal_transfer():
Expand All @@ -959,6 +970,12 @@ def make_item_gl_entries(self, gl_entries):
erpnext.is_perpetual_inventory_enabled(self.company):
gl_entries += super(SalesInvoice, self).get_gl_entries()

def set_asset_status(self, asset):
if self.is_return:
asset.set_status()
else:
asset.set_status("Sold" if self.docstatus==1 else None)

def make_loyalty_point_redemption_gle(self, gl_entries):
if cint(self.redeem_loyalty_points):
gl_entries.append(
Expand Down
32 changes: 32 additions & 0 deletions erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import unlink_payment_on_cancel_of_invoice
from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile
from erpnext.assets.doctype.asset.test_asset import create_asset, create_asset_data
from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency
from erpnext.stock.doctype.serial_no.serial_no import SerialNoWarehouseError
from frappe.model.naming import make_autoname
Expand Down Expand Up @@ -1069,6 +1070,36 @@ def test_return_sales_invoice(self):
self.assertFalse(si1.outstanding_amount)
self.assertEqual(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"), 1500)

def test_gle_made_when_asset_is_returned(self):
create_asset_data()
asset = create_asset(item_code="Macbook Pro")

si = create_sales_invoice(item_code="Macbook Pro", asset=asset.name, qty=1, rate=90000)
return_si = create_sales_invoice(is_return=1, return_against=si.name, item_code="Macbook Pro", asset=asset.name, qty=-1, rate=90000)

disposal_account = frappe.get_cached_value("Company", "_Test Company", "disposal_account")

# Asset value is 100,000 but it was sold for 90,000, so there should be a loss of 10,000
loss_for_si = frappe.get_all(
"GL Entry",
filters = {
"voucher_no": si.name,
"account": disposal_account
},
fields = ["credit", "debit"]
)[0]

loss_for_return_si = frappe.get_all(
"GL Entry",
filters = {
"voucher_no": return_si.name,
"account": disposal_account
},
fields = ["credit", "debit"]
)[0]

self.assertEqual(loss_for_si['credit'], loss_for_return_si['debit'])
self.assertEqual(loss_for_si['debit'], loss_for_return_si['credit'])

def test_discount_on_net_total(self):
si = frappe.copy_doc(test_records[2])
Expand Down Expand Up @@ -2164,6 +2195,7 @@ def create_sales_invoice(**args):
"rate": args.rate if args.get("rate") is not None else 100,
"income_account": args.income_account or "Sales - _TC",
"expense_account": args.expense_account or "Cost of Goods Sold - _TC",
"asset": args.asset or None,
"cost_center": args.cost_center or "_Test Cost Center - _TC",
"serial_no": args.serial_no,
"conversion_factor": 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -743,7 +743,6 @@
"fieldname": "asset",
"fieldtype": "Link",
"label": "Asset",
"no_copy": 1,
"options": "Asset"
},
{
Expand Down Expand Up @@ -826,7 +825,7 @@
"idx": 1,
"istable": 1,
"links": [],
"modified": "2021-02-23 01:05:22.123527",
"modified": "2021-06-21 23:03:11.599901",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Item",
Expand Down
75 changes: 54 additions & 21 deletions erpnext/assets/doctype/asset/depreciation.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,22 +176,34 @@ def restore_asset(asset_name):

asset.set_status()

@frappe.whitelist()
def get_gl_entries_on_asset_disposal(asset, selling_amount=0, finance_book=None):
fixed_asset_account, accumulated_depr_account, depr_expense_account = get_depreciation_accounts(asset)
disposal_account, depreciation_cost_center = get_disposal_account_and_cost_center(asset.company)
depreciation_cost_center = asset.cost_center or depreciation_cost_center
def get_gl_entries_on_asset_regain(asset, selling_amount=0, finance_book=None):
fixed_asset_account, asset, depreciation_cost_center, accumulated_depr_account, accumulated_depr_amount, disposal_account, value_after_depreciation = \
get_asset_details(asset, finance_book)

idx = 1
if finance_book:
for d in asset.finance_books:
if d.finance_book == finance_book:
idx = d.idx
break
gl_entries = [
{
"account": fixed_asset_account,
"debit_in_account_currency": asset.gross_purchase_amount,
"debit": asset.gross_purchase_amount,
"cost_center": depreciation_cost_center
},
{
"account": accumulated_depr_account,
"credit_in_account_currency": accumulated_depr_amount,
"credit": accumulated_depr_amount,
"cost_center": depreciation_cost_center
}
]

value_after_depreciation = (asset.finance_books[idx - 1].value_after_depreciation
if asset.calculate_depreciation else asset.value_after_depreciation)
accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(value_after_depreciation)
profit_amount = abs(flt(value_after_depreciation)) - abs(flt(selling_amount))
if profit_amount:
get_profit_gl_entries(profit_amount, gl_entries, disposal_account, depreciation_cost_center)

return gl_entries

def get_gl_entries_on_asset_disposal(asset, selling_amount=0, finance_book=None):
fixed_asset_account, asset, depreciation_cost_center, accumulated_depr_account, accumulated_depr_amount, disposal_account, value_after_depreciation = \
get_asset_details(asset, finance_book)

gl_entries = [
{
Expand All @@ -210,16 +222,37 @@ def get_gl_entries_on_asset_disposal(asset, selling_amount=0, finance_book=None)

profit_amount = flt(selling_amount) - flt(value_after_depreciation)
if profit_amount:
debit_or_credit = "debit" if profit_amount < 0 else "credit"
gl_entries.append({
"account": disposal_account,
"cost_center": depreciation_cost_center,
debit_or_credit: abs(profit_amount),
debit_or_credit + "_in_account_currency": abs(profit_amount)
})
get_profit_gl_entries(profit_amount, gl_entries, disposal_account, depreciation_cost_center)

return gl_entries

def get_asset_details(asset, finance_book=None):
fixed_asset_account, accumulated_depr_account, depr_expense_account = get_depreciation_accounts(asset)
disposal_account, depreciation_cost_center = get_disposal_account_and_cost_center(asset.company)
depreciation_cost_center = asset.cost_center or depreciation_cost_center

idx = 1
if finance_book:
for d in asset.finance_books:
if d.finance_book == finance_book:
idx = d.idx
break

value_after_depreciation = (asset.finance_books[idx - 1].value_after_depreciation
if asset.calculate_depreciation else asset.value_after_depreciation)
accumulated_depr_amount = flt(asset.gross_purchase_amount) - flt(value_after_depreciation)

return fixed_asset_account, asset, depreciation_cost_center, accumulated_depr_account, accumulated_depr_amount, disposal_account, value_after_depreciation

def get_profit_gl_entries(profit_amount, gl_entries, disposal_account, depreciation_cost_center):
debit_or_credit = "debit" if profit_amount < 0 else "credit"
gl_entries.append({
"account": disposal_account,
"cost_center": depreciation_cost_center,
debit_or_credit: abs(profit_amount),
debit_or_credit + "_in_account_currency": abs(profit_amount)
})

@frappe.whitelist()
def get_disposal_account_and_cost_center(company):
disposal_account, depreciation_cost_center = frappe.get_cached_value('Company', company,
Expand Down
5 changes: 4 additions & 1 deletion erpnext/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,10 @@
"erpnext.portal.utils.set_default_role"]
},
"Communication": {
"on_update": "erpnext.support.doctype.service_level_agreement.service_level_agreement.update_hold_time"
"on_update": [
"erpnext.support.doctype.service_level_agreement.service_level_agreement.update_hold_time",
"erpnext.support.doctype.issue.issue.set_first_response_time"
]
},
("Sales Taxes and Charges Template", 'Price List'): {
"on_update": "erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings.validate_cart_settings"
Expand Down
Loading

0 comments on commit 0f81ccb

Please sign in to comment.