Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Asset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ public int TaxLife {

public List<DepYear> TaxDepreciation {get; set;}

public int StatusCode { get; set; } // Renamed from NumericStatusCode
public string StatusMessage { get; set; } // New: Status text or error message

//Empty Constructor
public Asset()
{
Expand Down
158 changes: 117 additions & 41 deletions Controllers/CalculateController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,77 +18,153 @@ public CalculateController(ILogger<CalculateController> logger)

/// <summary>
/// Returns an array of Assets with calculated Accounting and Tax Depreciation 'tables' along with the asset information originally submitted.
/// Each Asset in the response includes all original input fields, a StatusCode (200, 422, or 500), and a StatusMessage describing the result.
/// If all assets succeed, the HTTP response is 200. If any fail, the response is 207 (Multi-Status), and each asset's status is included in the response.
/// </summary>
/// <remarks>
/// Sample Request:
///
/// POST /Calculate/DepreciateArray?GaapMethod=SL&amp;TaxMethod=MACRSHY
///
/// POST /Calculate/DepreciateArray
/// [
/// {
/// "name": "New Asset",
/// "purchaseDate": "2011-01-01",
/// "purchasePrice": 1000,
/// "residualValue": 0,
/// "section179": 0,
/// "usefulLife": 5,
/// "taxLife": 5,
/// "gaapMethod": "SL",
/// "taxMethod": "MACRSHY"
/// },
/// {
/// "name": "New Asset 2",
/// "purchaseDate": "2001-01-01",
/// "purchasePrice": 2000,
/// "residualValue": 0,
/// "section179": 0,
/// "usefulLife": 7,
/// "taxLife": 7,
/// "gaapMethod": "DB200",
/// "taxMethod": "INVALIDMETHOD"
/// }
/// ]
///
/// Sample Response (HTTP 200 if all succeed, 207 if any fail):
/// [
/// {
/// "name": "New Asset",
/// "purchaseDate": "2011-01-01",
/// "purchasePrice": 1000,
/// "residualValue": 0,
/// "section179": 0,
/// "usefulLife": 5,
/// "taxLife": 5
/// "taxLife": 5,
/// "gaapMethod": "SL",
/// "taxMethod": "MACRSHY",
/// "statusCode": 200,
/// "statusMessage": "Calculation succeeded.",
/// "gaapDepreciation": [...],
/// "taxDepreciation": [...]
/// },
/// {
/// "name": "New Asset",
/// "purchaseDate": "2011-01-01",
/// "purchasePrice": 1000,
/// "name": "New Asset 2",
/// "purchaseDate": "2001-01-01",
/// "purchasePrice": 2000,
/// "residualValue": 0,
/// "section179": 0,
/// "usefulLife": 5,
/// "taxLife": 5
/// "usefulLife": 7,
/// "taxLife": 7,
/// "gaapMethod": "DB200",
/// "taxMethod": "INVALIDMETHOD",
/// "statusCode": 422,
/// "statusMessage": "Invalid Tax Method Provided. Only MACRSHY and MACRSMQ allowed.",
/// "gaapDepreciation": [...],
/// "taxDepreciation": null
/// }
/// ]
/// ]
/// </remarks>
/// <param name="assets">Array of Asset JSON dictionaries in the body of the post</param>
/// <returns>Array of Asset objects with both accounting and tax depreciation calculations added</returns>
/// <response code="200">Returns array of asset objects</response>
/// <param name="assets">Array of Asset JSON objects in the body of the post, each including all required fields and calculation methods.</param>
/// <returns>Array of Asset objects, each with calculation results and per-object status code/message.</returns>
/// <response code="200">Returns array of asset objects (all succeeded)</response>
/// <response code="207">Returns array of asset objects (partial success/failure)</response>
/// <response code="422">If GAAP Method, Tax Method or Tax Life are invalid</response>
/// <response code="500">Any other error</response>
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status207MultiStatus)]
[Route("[controller]/DepreciateArray")]
public ActionResult<Asset[]> PostDepreciateArray([FromBody]Asset[] assets)
{
foreach(Asset asset in assets)
bool allSuccess = true;
foreach (Asset asset in assets)
{
switch(asset.GaapMethod)
try
{
case "SL":
asset.calcSL();
break;
case "DB200":
asset.calcDB200();
break;
case "DB150":
asset.calcDB150();
break;
case "SYD":
asset.calcSYD();
break;
default:
throw new Exception("INVALID_GAAP_METHOD");
}
switch (asset.GaapMethod)
{
case "SL":
asset.calcSL();
break;
case "DB200":
asset.calcDB200();
break;
case "DB150":
asset.calcDB150();
break;
case "SYD":
asset.calcSYD();
break;
default:
throw new Exception("INVALID_GAAP_METHOD");
}

switch (asset.TaxMethod)
{
case "MACRSHY":
asset.calcMacrsHY();
break;
case "MACRSMQ":
asset.calcMacrsMQ();
break;
default:
throw new Exception("INVALID_TAX_METHOD");
}

switch(asset.TaxMethod)
asset.StatusCode = 200;
asset.StatusMessage = "Calculation succeeded.";
}
catch (Exception ex)
{
case "MACRSHY":
asset.calcMacrsHY();
break;
case "MACRSMQ":
asset.calcMacrsMQ();
break;
default:
throw new Exception("INVALID_TAX_METHOD");
allSuccess = false;
// Set error code and message based on ExceptionMiddleware logic
if (ex.Message == "INVALID_GAAP_METHOD")
{
asset.StatusCode = 422;
asset.StatusMessage = "Invalid GAAP Method Provided. Only SL, DB150, DB200 and SYD allowed";
}
else if (ex.Message == "INVALID_TAX_METHOD")
{
asset.StatusCode = 422;
asset.StatusMessage = "Invalid Tax Method Provided. Only MACRSHY and MACRSMQ allowed.";
}
else if (ex.Message == "INVALID_TAX_YEAR")
{
asset.StatusCode = 422;
asset.StatusMessage = "Invalid Tax Year. Only the following allowed: 3, 5, 7, 10, 15 & 20";
}
else
{
asset.StatusCode = 500;
asset.StatusMessage = "Unhandled exception occurred";
}
}
}

return assets;
if (allSuccess)
return Ok(assets);
else
return StatusCode(207, assets); // 207 Multi-Status for partial success
}

/// <summary>
Expand Down
72 changes: 72 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,78 @@ Returns:
- **422** - Error for an invalid tax life, GAAP Method or Tax Method provided (See returned error description for which).
- **500** - Any other error.

### POST - DepreciateArray (Batch Calculation with Per-Asset Status)
A comprehensive call that returns an array of Asset objects, each with both GAAP and Tax depreciation tables, all original input fields, and per-object status fields. If all assets succeed, the HTTP response is 200. If any fail, the response is 207 (Multi-Status), and each asset's status is included in the response.

Example Request:

```
POST /Calculate/DepreciateArray
Content-Type: application/json

[
{
"name": "New Asset",
"purchaseDate": "2011-01-01",
"purchasePrice": 1000,
"residualValue": 0,
"section179": 0,
"usefulLife": 5,
"taxLife": 5,
"gaapMethod": "SL",
"taxMethod": "MACRSHY"
},
{
"name": "New Asset 2",
"purchaseDate": "2001-01-01",
"purchasePrice": 2000,
"residualValue": 0,
"section179": 0,
"usefulLife": 7,
"taxLife": 7,
"gaapMethod": "DB200",
"taxMethod": "INVALIDMETHOD"
}
]
```

Example Response (HTTP 207 if any fail):

```
[
{
"name": "New Asset",
"purchaseDate": "2011-01-01",
"purchasePrice": 1000,
"residualValue": 0,
"section179": 0,
"usefulLife": 5,
"taxLife": 5,
"gaapMethod": "SL",
"taxMethod": "MACRSHY",
"statusCode": 200,
"statusMessage": "Calculation succeeded.",
"gaapDepreciation": [...],
"taxDepreciation": [...]
},
{
"name": "New Asset 2",
"purchaseDate": "2001-01-01",
"purchasePrice": 2000,
"residualValue": 0,
"section179": 0,
"usefulLife": 7,
"taxLife": 7,
"gaapMethod": "DB200",
"taxMethod": "INVALIDMETHOD",
"statusCode": 422,
"statusMessage": "Invalid Tax Method Provided. Only MACRSHY and MACRSMQ allowed.",
"gaapDepreciation": [...],
"taxDepreciation": null
}
]
```

-----------

## Additional Documentation and Examples
Expand Down
42 changes: 38 additions & 4 deletions test/manualTesting.http
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ Content-Type: application/json
"section179": 0,
"usefulLife": 5,
"taxLife": 5,
"GaapMethod": "SL",
"TaxMethod": "MACRSHY"
"gaapMethod": "SL",
"taxMethod": "MACRSHY"
},
{
"name": "New Asset 2",
Expand All @@ -105,7 +105,41 @@ Content-Type: application/json
"section179": 0,
"usefulLife": 7,
"taxLife": 7,
"GaapMethod": "DB200",
"TaxMethod": "MACRSMQ"
"gaapMethod": "DB200",
"taxMethod": "INVALIDMETHOD"
}
]

# Sample Response (HTTP 207 if any fail):
# [
# {
# "name": "New Asset",
# "purchaseDate": "2011-01-01",
# "purchasePrice": 1000,
# "residualValue": 0,
# "section179": 0,
# "usefulLife": 5,
# "taxLife": 5,
# "gaapMethod": "SL",
# "taxMethod": "MACRSHY",
# "statusCode": 200,
# "statusMessage": "Calculation succeeded.",
# "gaapDepreciation": [...],
# "taxDepreciation": [...]
# },
# {
# "name": "New Asset 2",
# "purchaseDate": "2001-01-01",
# "purchasePrice": 2000,
# "residualValue": 0,
# "section179": 0,
# "usefulLife": 7,
# "taxLife": 7,
# "gaapMethod": "DB200",
# "taxMethod": "INVALIDMETHOD",
# "statusCode": 422,
# "statusMessage": "Invalid Tax Method Provided. Only MACRSHY and MACRSMQ allowed.",
# "gaapDepreciation": [...],
# "taxDepreciation": null
# }
# ]