feat: daily asset depreciation method [dev] (#36588)

feat: daily asset depreciation method
diff --git a/erpnext/assets/doctype/asset/test_asset.py b/erpnext/assets/doctype/asset/test_asset.py
index 2a74f20..cd66f1d 100644
--- a/erpnext/assets/doctype/asset/test_asset.py
+++ b/erpnext/assets/doctype/asset/test_asset.py
@@ -754,6 +754,40 @@
 
 		self.assertEqual(schedules, expected_schedules)
 
+	def test_schedule_for_straight_line_method_with_daily_depreciation(self):
+		asset = create_asset(
+			calculate_depreciation=1,
+			available_for_use_date="2023-01-01",
+			purchase_date="2023-01-01",
+			gross_purchase_amount=12000,
+			depreciation_start_date="2023-01-31",
+			total_number_of_depreciations=12,
+			frequency_of_depreciation=1,
+			daily_depreciation=1,
+		)
+
+		expected_schedules = [
+			["2023-01-31", 1019.18, 1019.18],
+			["2023-02-28", 920.55, 1939.73],
+			["2023-03-31", 1019.18, 2958.91],
+			["2023-04-30", 986.3, 3945.21],
+			["2023-05-31", 1019.18, 4964.39],
+			["2023-06-30", 986.3, 5950.69],
+			["2023-07-31", 1019.18, 6969.87],
+			["2023-08-31", 1019.18, 7989.05],
+			["2023-09-30", 986.3, 8975.35],
+			["2023-10-31", 1019.18, 9994.53],
+			["2023-11-30", 986.3, 10980.83],
+			["2023-12-31", 1019.17, 12000.0],
+		]
+
+		schedules = [
+			[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
+			for d in get_depr_schedule(asset.name, "Draft")
+		]
+
+		self.assertEqual(schedules, expected_schedules)
+
 	def test_schedule_for_straight_line_method_for_existing_asset(self):
 		asset = create_asset(
 			calculate_depreciation=1,
@@ -1724,6 +1758,7 @@
 				"total_number_of_depreciations": args.total_number_of_depreciations or 5,
 				"expected_value_after_useful_life": args.expected_value_after_useful_life or 0,
 				"depreciation_start_date": args.depreciation_start_date,
+				"daily_depreciation": args.daily_depreciation or 0,
 			},
 		)
 
diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.json b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.json
index d38508d..3772ef4 100644
--- a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.json
+++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.json
@@ -19,6 +19,7 @@
   "depreciation_method",
   "total_number_of_depreciations",
   "rate_of_depreciation",
+  "daily_depreciation",
   "column_break_8",
   "frequency_of_depreciation",
   "expected_value_after_useful_life",
@@ -174,12 +175,21 @@
    "label": "Number of Depreciations Booked",
    "print_hide": 1,
    "read_only": 1
+  },
+  {
+   "default": "0",
+   "depends_on": "eval:doc.depreciation_method == \"Straight Line\" || doc.depreciation_method == \"Manual\"",
+   "fieldname": "daily_depreciation",
+   "fieldtype": "Check",
+   "label": "Daily Depreciation",
+   "print_hide": 1,
+   "read_only": 1
   }
  ],
  "index_web_pages_for_search": 1,
  "is_submittable": 1,
  "links": [],
- "modified": "2023-02-26 16:37:23.734806",
+ "modified": "2023-08-10 22:22:09.722968",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Asset Depreciation Schedule",
diff --git a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py
index e616665..39ebd4e 100644
--- a/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py
+++ b/erpnext/assets/doctype/asset_depreciation_schedule/asset_depreciation_schedule.py
@@ -153,6 +153,7 @@
 		self.frequency_of_depreciation = row.frequency_of_depreciation
 		self.rate_of_depreciation = row.rate_of_depreciation
 		self.expected_value_after_useful_life = row.expected_value_after_useful_life
+		self.daily_depreciation = row.daily_depreciation
 		self.status = "Draft"
 
 	def make_depr_schedule(
@@ -499,29 +500,36 @@
 	return date_diff(date, period_start_date)
 
 
-@erpnext.allow_regional
 def get_depreciation_amount(
 	asset,
 	depreciable_value,
-	row,
+	fb_row,
 	schedule_idx=0,
 	prev_depreciation_amount=0,
 	has_wdv_or_dd_non_yearly_pro_rata=False,
 ):
-	if row.depreciation_method in ("Straight Line", "Manual"):
-		return get_straight_line_or_manual_depr_amount(asset, row)
+	if fb_row.depreciation_method in ("Straight Line", "Manual"):
+		return get_straight_line_or_manual_depr_amount(asset, fb_row, schedule_idx)
 	else:
+		rate_of_depreciation = get_updated_rate_of_depreciation_for_wdv_and_dd(
+			asset, depreciable_value, fb_row
+		)
 		return get_wdv_or_dd_depr_amount(
 			depreciable_value,
-			row.rate_of_depreciation,
-			row.frequency_of_depreciation,
+			rate_of_depreciation,
+			fb_row.frequency_of_depreciation,
 			schedule_idx,
 			prev_depreciation_amount,
 			has_wdv_or_dd_non_yearly_pro_rata,
 		)
 
 
-def get_straight_line_or_manual_depr_amount(asset, row):
+@erpnext.allow_regional
+def get_updated_rate_of_depreciation_for_wdv_and_dd(asset, depreciable_value, fb_row):
+	return fb_row.rate_of_depreciation
+
+
+def get_straight_line_or_manual_depr_amount(asset, row, schedule_idx):
 	# if the Depreciation Schedule is being modified after Asset Repair due to increase in asset life and value
 	if asset.flags.increase_in_asset_life:
 		return (flt(row.value_after_depreciation) - flt(row.expected_value_after_useful_life)) / (
@@ -534,11 +542,30 @@
 		)
 	# if the Depreciation Schedule is being prepared for the first time
 	else:
-		return (
-			flt(asset.gross_purchase_amount)
-			- flt(asset.opening_accumulated_depreciation)
-			- flt(row.expected_value_after_useful_life)
-		) / flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked)
+		if row.daily_depreciation:
+			daily_depr_amount = (
+				flt(asset.gross_purchase_amount)
+				- flt(asset.opening_accumulated_depreciation)
+				- flt(row.expected_value_after_useful_life)
+			) / date_diff(
+				add_months(
+					row.depreciation_start_date,
+					flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked)
+					* row.frequency_of_depreciation,
+				),
+				row.depreciation_start_date,
+			)
+			to_date = add_months(row.depreciation_start_date, schedule_idx * row.frequency_of_depreciation)
+			from_date = add_months(
+				row.depreciation_start_date, (schedule_idx - 1) * row.frequency_of_depreciation
+			)
+			return daily_depr_amount * date_diff(to_date, from_date)
+		else:
+			return (
+				flt(asset.gross_purchase_amount)
+				- flt(asset.opening_accumulated_depreciation)
+				- flt(row.expected_value_after_useful_life)
+			) / flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked)
 
 
 def get_wdv_or_dd_depr_amount(
diff --git a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json
index e5a5f19..4121302 100644
--- a/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json
+++ b/erpnext/assets/doctype/asset_finance_book/asset_finance_book.json
@@ -8,6 +8,7 @@
   "finance_book",
   "depreciation_method",
   "total_number_of_depreciations",
+  "daily_depreciation",
   "column_break_5",
   "frequency_of_depreciation",
   "depreciation_start_date",
@@ -17,6 +18,7 @@
  ],
  "fields": [
   {
+   "columns": 2,
    "fieldname": "finance_book",
    "fieldtype": "Link",
    "in_list_view": 1,
@@ -32,6 +34,7 @@
    "reqd": 1
   },
   {
+   "columns": 2,
    "fieldname": "total_number_of_depreciations",
    "fieldtype": "Int",
    "in_list_view": 1,
@@ -43,6 +46,7 @@
    "fieldtype": "Column Break"
   },
   {
+   "columns": 2,
    "fieldname": "frequency_of_depreciation",
    "fieldtype": "Int",
    "in_list_view": 1,
@@ -57,6 +61,7 @@
    "mandatory_depends_on": "eval:parent.doctype == 'Asset'"
   },
   {
+   "columns": 1,
    "default": "0",
    "depends_on": "eval:parent.doctype == 'Asset'",
    "fieldname": "expected_value_after_useful_life",
@@ -79,12 +84,19 @@
    "fieldname": "rate_of_depreciation",
    "fieldtype": "Percent",
    "label": "Rate of Depreciation"
+  },
+  {
+   "default": "0",
+   "depends_on": "eval:doc.depreciation_method == \"Straight Line\" || doc.depreciation_method == \"Manual\"",
+   "fieldname": "daily_depreciation",
+   "fieldtype": "Check",
+   "label": "Daily Depreciation"
   }
  ],
  "index_web_pages_for_search": 1,
  "istable": 1,
  "links": [],
- "modified": "2021-06-17 12:59:05.743683",
+ "modified": "2023-08-10 22:10:36.576199",
  "modified_by": "Administrator",
  "module": "Assets",
  "name": "Asset Finance Book",
@@ -93,5 +105,6 @@
  "quick_entry": 1,
  "sort_field": "modified",
  "sort_order": "DESC",
+ "states": [],
  "track_changes": 1
 }
\ No newline at end of file