Merge branch 'develop' into fix-depr-after-sale
This commit is contained in:
commit
5a0289a810
@ -1296,12 +1296,20 @@ class SalesInvoice(SellingController):
|
|||||||
|
|
||||||
serial_nos = item.serial_no or ""
|
serial_nos = item.serial_no or ""
|
||||||
si_serial_nos = set(get_serial_nos(serial_nos))
|
si_serial_nos = set(get_serial_nos(serial_nos))
|
||||||
|
serial_no_diff = si_serial_nos - dn_serial_nos
|
||||||
|
|
||||||
if si_serial_nos - dn_serial_nos:
|
if serial_no_diff:
|
||||||
frappe.throw(_("Serial Numbers in row {0} does not match with Delivery Note").format(item.idx))
|
dn_link = frappe.utils.get_link_to_form("Delivery Note", item.delivery_note)
|
||||||
|
serial_no_msg = ", ".join(frappe.bold(d) for d in serial_no_diff)
|
||||||
|
|
||||||
|
msg = _("Row #{0}: The following Serial Nos are not present in Delivery Note {1}:").format(
|
||||||
|
item.idx, dn_link)
|
||||||
|
msg += " " + serial_no_msg
|
||||||
|
|
||||||
|
frappe.throw(msg=msg, title=_("Serial Nos Mismatch"))
|
||||||
|
|
||||||
if item.serial_no and cint(item.qty) != len(si_serial_nos):
|
if item.serial_no and cint(item.qty) != len(si_serial_nos):
|
||||||
frappe.throw(_("Row {0}: {1} Serial numbers required for Item {2}. You have provided {3}.").format(
|
frappe.throw(_("Row #{0}: {1} Serial numbers required for Item {2}. You have provided {3}.").format(
|
||||||
item.idx, item.qty, item.item_code, len(si_serial_nos)))
|
item.idx, item.qty, item.item_code, len(si_serial_nos)))
|
||||||
|
|
||||||
def update_project(self):
|
def update_project(self):
|
||||||
|
@ -194,7 +194,7 @@ class Asset(AccountsController):
|
|||||||
start = self.clear_depreciation_schedule()
|
start = self.clear_depreciation_schedule()
|
||||||
|
|
||||||
# value_after_depreciation - current Asset value
|
# value_after_depreciation - current Asset value
|
||||||
if d.value_after_depreciation:
|
if self.docstatus == 1 and d.value_after_depreciation:
|
||||||
value_after_depreciation = (flt(d.value_after_depreciation) -
|
value_after_depreciation = (flt(d.value_after_depreciation) -
|
||||||
flt(self.opening_accumulated_depreciation))
|
flt(self.opening_accumulated_depreciation))
|
||||||
else:
|
else:
|
||||||
|
@ -831,6 +831,26 @@ class TestDepreciationBasics(AssetSetup):
|
|||||||
|
|
||||||
self.assertEqual(gle, expected_gle)
|
self.assertEqual(gle, expected_gle)
|
||||||
self.assertEqual(asset.get("value_after_depreciation"), 0)
|
self.assertEqual(asset.get("value_after_depreciation"), 0)
|
||||||
|
def test_expected_value_change(self):
|
||||||
|
"""
|
||||||
|
tests if changing `expected_value_after_useful_life`
|
||||||
|
affects `value_after_depreciation`
|
||||||
|
"""
|
||||||
|
|
||||||
|
asset = create_asset(calculate_depreciation=1)
|
||||||
|
asset.opening_accumulated_depreciation = 2000
|
||||||
|
asset.number_of_depreciations_booked = 1
|
||||||
|
|
||||||
|
asset.finance_books[0].expected_value_after_useful_life = 100
|
||||||
|
asset.save()
|
||||||
|
asset.reload()
|
||||||
|
self.assertEquals(asset.finance_books[0].value_after_depreciation, 98000.0)
|
||||||
|
|
||||||
|
# changing expected_value_after_useful_life shouldn't affect value_after_depreciation
|
||||||
|
asset.finance_books[0].expected_value_after_useful_life = 200
|
||||||
|
asset.save()
|
||||||
|
asset.reload()
|
||||||
|
self.assertEquals(asset.finance_books[0].value_after_depreciation, 98000.0)
|
||||||
|
|
||||||
def create_asset_data():
|
def create_asset_data():
|
||||||
if not frappe.db.exists("Asset Category", "Computers"):
|
if not frappe.db.exists("Asset Category", "Computers"):
|
||||||
|
@ -22,7 +22,7 @@ class TestAssetRepair(unittest.TestCase):
|
|||||||
frappe.db.sql("delete from `tabTax Rule`")
|
frappe.db.sql("delete from `tabTax Rule`")
|
||||||
|
|
||||||
def test_update_status(self):
|
def test_update_status(self):
|
||||||
asset = create_asset()
|
asset = create_asset(submit=1)
|
||||||
initial_status = asset.status
|
initial_status = asset.status
|
||||||
asset_repair = create_asset_repair(asset = asset)
|
asset_repair = create_asset_repair(asset = asset)
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ class TestAssetRepair(unittest.TestCase):
|
|||||||
self.assertEqual(stock_entry.items[0].qty, asset_repair.stock_items[0].consumed_quantity)
|
self.assertEqual(stock_entry.items[0].qty, asset_repair.stock_items[0].consumed_quantity)
|
||||||
|
|
||||||
def test_increase_in_asset_value_due_to_stock_consumption(self):
|
def test_increase_in_asset_value_due_to_stock_consumption(self):
|
||||||
asset = create_asset(calculate_depreciation = 1)
|
asset = create_asset(calculate_depreciation = 1, submit=1)
|
||||||
initial_asset_value = get_asset_value(asset)
|
initial_asset_value = get_asset_value(asset)
|
||||||
asset_repair = create_asset_repair(asset= asset, stock_consumption = 1, submit = 1)
|
asset_repair = create_asset_repair(asset= asset, stock_consumption = 1, submit = 1)
|
||||||
asset.reload()
|
asset.reload()
|
||||||
@ -85,7 +85,7 @@ class TestAssetRepair(unittest.TestCase):
|
|||||||
self.assertEqual(asset_repair.stock_items[0].total_value, increase_in_asset_value)
|
self.assertEqual(asset_repair.stock_items[0].total_value, increase_in_asset_value)
|
||||||
|
|
||||||
def test_increase_in_asset_value_due_to_repair_cost_capitalisation(self):
|
def test_increase_in_asset_value_due_to_repair_cost_capitalisation(self):
|
||||||
asset = create_asset(calculate_depreciation = 1)
|
asset = create_asset(calculate_depreciation = 1, submit=1)
|
||||||
initial_asset_value = get_asset_value(asset)
|
initial_asset_value = get_asset_value(asset)
|
||||||
asset_repair = create_asset_repair(asset= asset, capitalize_repair_cost = 1, submit = 1)
|
asset_repair = create_asset_repair(asset= asset, capitalize_repair_cost = 1, submit = 1)
|
||||||
asset.reload()
|
asset.reload()
|
||||||
@ -103,7 +103,7 @@ class TestAssetRepair(unittest.TestCase):
|
|||||||
self.assertEqual(asset_repair.name, gl_entry.voucher_no)
|
self.assertEqual(asset_repair.name, gl_entry.voucher_no)
|
||||||
|
|
||||||
def test_increase_in_asset_life(self):
|
def test_increase_in_asset_life(self):
|
||||||
asset = create_asset(calculate_depreciation = 1)
|
asset = create_asset(calculate_depreciation = 1, submit=1)
|
||||||
initial_num_of_depreciations = num_of_depreciations(asset)
|
initial_num_of_depreciations = num_of_depreciations(asset)
|
||||||
create_asset_repair(asset= asset, capitalize_repair_cost = 1, submit = 1)
|
create_asset_repair(asset= asset, capitalize_repair_cost = 1, submit = 1)
|
||||||
asset.reload()
|
asset.reload()
|
||||||
@ -126,7 +126,7 @@ def create_asset_repair(**args):
|
|||||||
if args.asset:
|
if args.asset:
|
||||||
asset = args.asset
|
asset = args.asset
|
||||||
else:
|
else:
|
||||||
asset = create_asset(is_existing_asset = 1)
|
asset = create_asset(is_existing_asset = 1, submit=1)
|
||||||
asset_repair = frappe.new_doc("Asset Repair")
|
asset_repair = frappe.new_doc("Asset Repair")
|
||||||
asset_repair.update({
|
asset_repair.update({
|
||||||
"asset": asset.name,
|
"asset": asset.name,
|
||||||
|
@ -79,8 +79,15 @@ class StockController(AccountsController):
|
|||||||
def clean_serial_nos(self):
|
def clean_serial_nos(self):
|
||||||
for row in self.get("items"):
|
for row in self.get("items"):
|
||||||
if hasattr(row, "serial_no") and row.serial_no:
|
if hasattr(row, "serial_no") and row.serial_no:
|
||||||
# replace commas by linefeed and remove all spaces in string
|
# replace commas by linefeed
|
||||||
row.serial_no = row.serial_no.replace(",", "\n").replace(" ", "")
|
row.serial_no = row.serial_no.replace(",", "\n")
|
||||||
|
|
||||||
|
# strip preceeding and succeeding spaces for each SN
|
||||||
|
# (SN could have valid spaces in between e.g. SN - 123 - 2021)
|
||||||
|
serial_no_list = row.serial_no.split("\n")
|
||||||
|
serial_no_list = [sn.strip() for sn in serial_no_list]
|
||||||
|
|
||||||
|
row.serial_no = "\n".join(serial_no_list)
|
||||||
|
|
||||||
def get_gl_entries(self, warehouse_account=None, default_expense_account=None,
|
def get_gl_entries(self, warehouse_account=None, default_expense_account=None,
|
||||||
default_cost_center=None):
|
default_cost_center=None):
|
||||||
|
@ -97,7 +97,7 @@ class ShiftType(Document):
|
|||||||
assigned_employees = [x[0] for x in assigned_employees]
|
assigned_employees = [x[0] for x in assigned_employees]
|
||||||
|
|
||||||
if consider_default_shift:
|
if consider_default_shift:
|
||||||
filters = {'default_shift': self.name}
|
filters = {'default_shift': self.name, 'status': ['!=', 'Inactive']}
|
||||||
default_shift_employees = frappe.get_all('Employee', 'name', filters, as_list=True)
|
default_shift_employees = frappe.get_all('Employee', 'name', filters, as_list=True)
|
||||||
default_shift_employees = [x[0] for x in default_shift_employees]
|
default_shift_employees = [x[0] for x in default_shift_employees]
|
||||||
return list(set(assigned_employees+default_shift_employees))
|
return list(set(assigned_employees+default_shift_employees))
|
||||||
|
@ -305,4 +305,5 @@ erpnext.patches.v13_0.modify_invalid_gain_loss_gl_entries #2
|
|||||||
erpnext.patches.v13_0.fix_additional_cost_in_mfg_stock_entry
|
erpnext.patches.v13_0.fix_additional_cost_in_mfg_stock_entry
|
||||||
erpnext.patches.v13_0.set_status_in_maintenance_schedule_table
|
erpnext.patches.v13_0.set_status_in_maintenance_schedule_table
|
||||||
erpnext.patches.v13_0.add_default_interview_notification_templates
|
erpnext.patches.v13_0.add_default_interview_notification_templates
|
||||||
|
erpnext.patches.v13_0.enable_scheduler_job_for_item_reposting
|
||||||
erpnext.patches.v13_0.requeue_failed_reposts
|
erpnext.patches.v13_0.requeue_failed_reposts
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
frappe.reload_doc('core', 'doctype', 'scheduled_job_type')
|
||||||
|
if frappe.db.exists('Scheduled Job Type', 'repost_item_valuation.repost_entries'):
|
||||||
|
frappe.db.set_value('Scheduled Job Type',
|
||||||
|
'repost_item_valuation.repost_entries', 'stopped', 0)
|
@ -184,14 +184,14 @@ class TestSerialNo(ERPNextTestCase):
|
|||||||
|
|
||||||
se = frappe.copy_doc(test_records[0])
|
se = frappe.copy_doc(test_records[0])
|
||||||
se.get("items")[0].item_code = item_code
|
se.get("items")[0].item_code = item_code
|
||||||
se.get("items")[0].qty = 3
|
se.get("items")[0].qty = 4
|
||||||
se.get("items")[0].serial_no = " _TS1, _TS2 , _TS3 "
|
se.get("items")[0].serial_no = " _TS1, _TS2 , _TS3 , _TS4 - 2021"
|
||||||
se.get("items")[0].transfer_qty = 3
|
se.get("items")[0].transfer_qty = 4
|
||||||
se.set_stock_entry_type()
|
se.set_stock_entry_type()
|
||||||
se.insert()
|
se.insert()
|
||||||
se.submit()
|
se.submit()
|
||||||
|
|
||||||
self.assertEqual(se.get("items")[0].serial_no, "_TS1\n_TS2\n_TS3")
|
self.assertEqual(se.get("items")[0].serial_no, "_TS1\n_TS2\n_TS3\n_TS4 - 2021")
|
||||||
|
|
||||||
frappe.db.rollback()
|
frappe.db.rollback()
|
||||||
|
|
||||||
|
@ -37,7 +37,6 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"default": "7",
|
"default": "7",
|
||||||
"description": "Auto close Issue after 7 days",
|
|
||||||
"fieldname": "close_issue_after_days",
|
"fieldname": "close_issue_after_days",
|
||||||
"fieldtype": "Int",
|
"fieldtype": "Int",
|
||||||
"label": "Close Issue After Days"
|
"label": "Close Issue After Days"
|
||||||
@ -164,7 +163,7 @@
|
|||||||
],
|
],
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-06-11 13:08:38.473616",
|
"modified": "2021-10-14 13:08:38.473616",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Support",
|
"module": "Support",
|
||||||
"name": "Support Settings",
|
"name": "Support Settings",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user