Pub 225 Compliance
This commit is contained in:
@@ -38,11 +38,34 @@ function isRealProperty(asset, book) {
|
||||
return months >= 330 || /real|realty|1250|building/.test(pt);
|
||||
}
|
||||
|
||||
// Whole years a property was held (for the §1252 / §1255 applicable-percentage schedules).
|
||||
function yearsHeld(asset, disposalDate) {
|
||||
const acq = asset.acquired_date || asset.in_service_date;
|
||||
if (!acq) return 0;
|
||||
return Math.max(0, Math.floor((new Date(`${disposalDate}T00:00:00`) - new Date(`${acq}T00:00:00`)) / (365.25 * 86400000)));
|
||||
}
|
||||
|
||||
// §1252 applicable percentage (IRS Pub 225): 100% if farmland is disposed of within 5 years; then reduced
|
||||
// 20 points per year for years 6–10; 0% after 10 years.
|
||||
function section1252Percent(years) {
|
||||
if (years <= 5) return 1;
|
||||
return Math.max(0, 1 - 0.2 * (years - 5));
|
||||
}
|
||||
|
||||
// §1255 applicable percentage: 100% if held under 10 years; reduced 10 points for each year (or part) the
|
||||
// property was held beyond 10 years; 0% at 20 years.
|
||||
function section1255Percent(years) {
|
||||
if (years < 10) return 1;
|
||||
return Math.max(0, 1 - 0.1 * (years - 9));
|
||||
}
|
||||
|
||||
// Characterize the gain on disposal into ordinary-income recapture vs. §1231 (capital) gain (Form 4797).
|
||||
// §1245: ordinary recapture = lesser of gain or total depreciation taken (incl. §179/bonus). §1250:
|
||||
// ordinary recapture = lesser of gain or "additional depreciation" (accelerated over straight-line); the
|
||||
// remaining gain up to straight-line taken is unrecaptured §1250 gain (a 25% capital bucket).
|
||||
function characterizeRecapture(asset, book, rules, year, proportion, gainLoss, accumulated) {
|
||||
// remaining gain up to straight-line taken is unrecaptured §1250 gain (a 25% capital bucket). Farm
|
||||
// property adds §1252 (soil & water conservation, §175) and §1255 (cost-sharing, §126) ordinary recapture,
|
||||
// each by an applicable percentage of the years held and limited to the remaining gain.
|
||||
function characterizeRecapture(asset, book, rules, year, proportion, gainLoss, accumulated, disposalDate) {
|
||||
const section = isRealProperty(asset, book) ? '1250' : '1245';
|
||||
const gain = Math.max(0, gainLoss);
|
||||
let ordinary = 0;
|
||||
@@ -51,7 +74,6 @@ function characterizeRecapture(asset, book, rules, year, proportion, gainLoss, a
|
||||
if (section === '1245') {
|
||||
ordinary = Math.min(gain, accumulated);
|
||||
} else {
|
||||
// Straight-line accumulated for the same period (additional depreciation = accelerated − SL).
|
||||
const slBook = { ...book, depreciation_method: 'straight_line', section_179_amount: 0, bonus_percent: 0 };
|
||||
const slRow = annualSchedule(asset, slBook, rules, { startYear: year, endYear: year })[0] || {};
|
||||
const slAccum = money(Number(slRow.accumulated || 0) * proportion);
|
||||
@@ -60,11 +82,21 @@ function characterizeRecapture(asset, book, rules, year, proportion, gainLoss, a
|
||||
unrecaptured1250 = Math.min(money(gain - ordinary), slAccum);
|
||||
}
|
||||
}
|
||||
// Farm-property recapture (§1252 / §1255), applied to the gain remaining after depreciation recapture.
|
||||
const years = yearsHeld(asset, disposalDate);
|
||||
let remaining = Math.max(0, gain - ordinary);
|
||||
const r1252 = Math.min(remaining, money(section1252Percent(years) * Number(asset.soil_water_deductions || 0) * proportion));
|
||||
remaining = Math.max(0, remaining - r1252);
|
||||
const r1255 = Math.min(remaining, money(section1255Percent(years) * Number(asset.cost_sharing_excluded || 0) * proportion));
|
||||
const totalOrdinary = money(ordinary + r1252 + r1255);
|
||||
|
||||
return {
|
||||
recapture_section: section,
|
||||
ordinary_recapture: money(ordinary),
|
||||
unrecaptured_1250_gain: money(unrecaptured1250),
|
||||
section_1231_gain: money(gainLoss - ordinary) // negative for a §1231 loss
|
||||
section_1252_recapture: money(r1252),
|
||||
section_1255_recapture: money(r1255),
|
||||
section_1231_gain: money(gainLoss - totalOrdinary) // negative for a §1231 loss
|
||||
};
|
||||
}
|
||||
|
||||
@@ -95,7 +127,7 @@ function computeDisposal(asset, input = {}) {
|
||||
|
||||
// Recapture characterization is computed on the disposed book's depreciation (use a tax book — FEDERAL —
|
||||
// for tax recapture). "Depreciation taken" includes the impairment write-down already reflected in NBV.
|
||||
const recapture = characterizeRecapture(asset, book, rules, year, proportion, gainLoss, money(accumulated + impairment));
|
||||
const recapture = characterizeRecapture(asset, book, rules, year, proportion, gainLoss, money(accumulated + impairment), disposalDate);
|
||||
|
||||
return {
|
||||
book_type: bookType,
|
||||
@@ -146,14 +178,15 @@ function recordDisposal(assetId, input, userId) {
|
||||
asset_id, disposal_date, method, property_type, partial, disposed_cost,
|
||||
disposal_price, disposal_expense, accumulated_depreciation, net_book_value,
|
||||
gain_loss, book_type, recapture_section, ordinary_recapture, section_1231_gain,
|
||||
unrecaptured_1250_gain, notes, created_by, created_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
unrecaptured_1250_gain, section_1252_recapture, section_1255_recapture, notes, created_by, created_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
[
|
||||
assetId, result.disposal_date, result.method, result.property_type, result.partial,
|
||||
result.disposed_cost, result.disposal_price, result.disposal_expense,
|
||||
result.accumulated_depreciation, result.net_book_value, result.gain_loss,
|
||||
result.book_type, result.recapture_section, result.ordinary_recapture, result.section_1231_gain,
|
||||
result.unrecaptured_1250_gain, input.notes || null, userId, timestamp
|
||||
result.unrecaptured_1250_gain, result.section_1252_recapture, result.section_1255_recapture,
|
||||
input.notes || null, userId, timestamp
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user