function months(years) { return Math.round(Number(years) * 12); } function method(code, family, label, formula, options = {}) { return { code, family, label, formula, ...options }; } function macrsDeclining(prefix, labelPrefix, system, multiplier, lives, options = {}) { return lives.map((life) => method( `${prefix}_${String(life).replace('.', '_')}`, 'MACRS', `${labelPrefix} ${life}-year`, 'macrs_declining_balance', { system, lifeMonths: months(life), rateMultiplier: multiplier, switchToStraightLine: true, defaultConvention: life >= 27.5 ? 'mid_month' : 'half_year', ...options } )); } function straightLineMethods(prefix, family, labelPrefix, system, lives, options = {}) { return lives.map((life) => method( `${prefix}_${String(life).replace('.', '_')}`, family, `${labelPrefix} ${life}-year`, 'straight_line', { system, lifeMonths: months(life), defaultConvention: life >= 27.5 ? 'mid_month' : 'half_year', ...options } )); } function acrsRateMethod(code, label, life, rates, options = {}) { return method(code, 'ACRS', label, 'rate_table', { system: 'ACRS', lifeMonths: months(life), defaultConvention: 'none', rates, ...options }); } function buildMacrsMethods() { return [ ...macrsDeclining('macrs_gds_200db', 'MACRS GDS 200% DB', 'GDS', 2, [3, 5, 7, 10]), ...macrsDeclining('macrs_gds_150db', 'MACRS GDS 150% DB', 'GDS', 1.5, [3, 5, 7, 10, 15, 20]), ...straightLineMethods('macrs_gds_sl', 'MACRS', 'MACRS GDS straight-line', 'GDS', [3, 5, 7, 10, 15, 20, 27.5, 39]), ...straightLineMethods('macrs_ads_sl', 'MACRS', 'MACRS ADS straight-line', 'ADS', [3, 5, 7, 10, 12, 15, 20, 30, 40]), ...macrsDeclining('macrs_ads_150db_legacy', 'Legacy MACRS ADS 150% DB', 'ADS', 1.5, [3, 5, 7, 10, 12, 15, 20, 30, 40], { legacy: true, sourceNote: 'For property where an older ADS 150% DB election must continue.' }) ]; } function buildAcrsMethods() { const regular = [ acrsRateMethod('acrs_regular_3', 'ACRS regular 3-year', 3, [0.25, 0.38, 0.37]), acrsRateMethod('acrs_regular_5', 'ACRS regular 5-year', 5, [0.15, 0.22, 0.21, 0.21, 0.21]), acrsRateMethod('acrs_regular_10', 'ACRS regular 10-year', 10, [0.08, 0.14, 0.12, 0.10, 0.10, 0.10, 0.09, 0.09, 0.09, 0.09]), acrsRateMethod('acrs_regular_15_real', 'ACRS regular 15-year real property', 15, [], { requiresMonthTable: true, fallbackFormula: 'straight_line' }), acrsRateMethod('acrs_regular_15_low_income', 'ACRS regular 15-year low-income housing', 15, [], { requiresMonthTable: true, fallbackFormula: 'straight_line' }), acrsRateMethod('acrs_regular_18_real', 'ACRS regular 18-year real property', 18, [], { requiresMonthTable: true, fallbackFormula: 'straight_line' }), acrsRateMethod('acrs_regular_19_real', 'ACRS regular 19-year real property', 19, [], { requiresMonthTable: true, fallbackFormula: 'straight_line' }), acrsRateMethod('acrs_regular_listed_property', 'ACRS listed property predominant-use table', 5, [], { requiresListedPropertyTable: true, fallbackFormula: 'straight_line' }) ]; const alternate = straightLineMethods('acrs_alternate_sl', 'ACRS', 'ACRS alternate modified straight-line', 'ACRS', [3, 5, 10, 12, 15, 18, 19, 25], { formula: 'acrs_alternate_straight_line', defaultConvention: 'half_year' }); const straightLine = straightLineMethods('acrs_required_sl', 'ACRS', 'ACRS required straight-line', 'ACRS', [3, 5, 10, 15, 18, 19, 35, 45], { formula: 'straight_line', defaultConvention: 'half_year', legacy: true }); return [...regular, ...alternate, ...straightLine]; } function buildGaapMethods() { return [ method('straight_line', 'GAAP', 'Straight-line', 'straight_line'), method('sum_of_years_digits', 'GAAP', 'Sum-of-years-digits', 'sum_of_years_digits'), method('declining_balance_200', 'GAAP', '200% declining balance', 'declining_balance', { rateMultiplier: 2 }), method('declining_balance_175', 'GAAP', '175% declining balance', 'declining_balance', { rateMultiplier: 1.75 }), method('declining_balance_150', 'GAAP', '150% declining balance', 'declining_balance', { rateMultiplier: 1.5 }), method('declining_balance_125', 'GAAP', '125% declining balance', 'declining_balance', { rateMultiplier: 1.25 }) ]; } function buildSpecialMethods() { return [ method('manual', 'Manual', 'Manual depreciation entry', 'manual'), method('amortization', 'Lease', 'Straight-line amortization', 'straight_line') ]; } // Sage-style 200% declining-balance method codes. The MACRS family (MF/MT/MI) ignores // salvage value and recovers the full basis; the standard family (DB/DH/DD) honors salvage // (depreciates only down to it). All use a 200% rate and switch to straight-line. function build200Methods() { return [ method('MF200', 'MACRS', 'MF200 — MACRS Formula, 200% DB (GDS)', 'macrs_declining_balance', { system: 'GDS', rateMultiplier: 2, switchToStraightLine: true, defaultConvention: 'half_year', ignoreSalvage: true }), method('MT200', 'MACRS', 'MT200 — MACRS Tables, 200% DB (GDS)', 'macrs_declining_balance', { system: 'GDS', rateMultiplier: 2, switchToStraightLine: true, defaultConvention: 'half_year', ignoreSalvage: true, usesTables: true }), method('MI200', 'MACRS', 'MI200 — MACRS 200% DB, Indian Reservation', 'macrs_declining_balance', { system: 'GDS', rateMultiplier: 2, switchToStraightLine: true, defaultConvention: 'half_year', ignoreSalvage: true, indianReservation: true }), method('DB200', 'Declining Balance', 'DB200 — 200% Declining Balance to SL (uses book convention)', 'declining_balance', { rateMultiplier: 2, switchToStraightLine: true }), method('DH200', 'Declining Balance', 'DH200 — 200% Declining Balance to SL, Half-Year', 'declining_balance', { rateMultiplier: 2, switchToStraightLine: true, defaultConvention: 'half_year' }), method('DD200', 'Declining Balance', 'DD200 — 200% Declining Balance to SL, Full-Year', 'declining_balance', { rateMultiplier: 2, switchToStraightLine: true, defaultConvention: 'none' }) ]; } function buildDepreciationMethods() { return [ ...build200Methods(), ...buildMacrsMethods(), ...buildAcrsMethods(), ...buildGaapMethods(), ...buildSpecialMethods() ]; } function expandRuleSet(ruleSet) { const methods = buildDepreciationMethods(); return { ...ruleSet, methodCatalog: ruleSet.methodCatalog || 'mixedassets-68-us-tax-and-accounting-v1', methodCounts: { macrs: methods.filter((item) => item.family === 'MACRS').length, acrs: methods.filter((item) => item.family === 'ACRS').length, gaap: methods.filter((item) => item.family === 'GAAP').length, supplemental: methods.filter((item) => !['MACRS', 'ACRS', 'GAAP'].includes(item.family)).length, total: methods.length }, methods }; } module.exports = { buildDepreciationMethods, expandRuleSet };